X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fhttp.c;h=c34b46d4437639a46c36d0ac7a1d231ebe79d0b3;hb=7a9f915fa6be8c8955ff2c59169538a4d0349080;hp=9817d72af8301efa3ce25d1b4ccd0e87b9aa8531;hpb=2bc9d6bb53df44a0c5174767de734620c2cdfd9e;p=platform%2Fupstream%2Fcurl.git diff --git a/lib/http.c b/lib/http.c index 9817d72..c34b46d 100644 --- a/lib/http.c +++ b/lib/http.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -63,6 +63,7 @@ #include "share.h" #include "hostip.h" #include "http.h" +#include "curl_memory.h" #include "select.h" #include "parsedate.h" /* for the week day and month names */ #include "strtoofft.h" @@ -72,14 +73,15 @@ #include "http_proxy.h" #include "warnless.h" #include "non-ascii.h" -#include "conncache.h" +#include "bundles.h" #include "pipeline.h" #include "http2.h" #include "connect.h" -#include "curl_printf.h" -/* The last #include files should be: */ -#include "curl_memory.h" +#define _MPRINTF_REPLACE /* use our functions only */ +#include + +/* The last #include file should be: */ #include "memdebug.h" /* @@ -153,18 +155,12 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn) { /* allocate the HTTP-specific struct for the SessionHandle, only to survive during this request */ - struct HTTP *http; DEBUGASSERT(conn->data->req.protop == NULL); - http = calloc(1, sizeof(struct HTTP)); - if(!http) + conn->data->req.protop = calloc(1, sizeof(struct HTTP)); + if(!conn->data->req.protop) return CURLE_OUT_OF_MEMORY; - conn->data->req.protop = http; - - Curl_http2_setup_conn(conn); - Curl_http2_setup_req(conn->data); - return CURLE_OK; } @@ -307,7 +303,7 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy) if(!authorization) return CURLE_REMOTE_ACCESS_DENIED; - free(*userp); + Curl_safefree(*userp); *userp = aprintf("%sAuthorization: Basic %s\r\n", proxy?"Proxy-":"", authorization); @@ -351,6 +347,82 @@ static bool pickoneauth(struct auth *pick) return picked; } +/* whether to complete request (for authentication) in current connection */ +static bool complete_request(struct connectdata *conn, + curl_off_t remaining_bytes) +{ +#if defined(USE_NTLM) || defined(USE_SPNEGO) + struct SessionHandle *data = conn->data; + bool have_ntlm_or_negotiate = FALSE; + bool auth_started = FALSE; + + /* don't reset connection when we're in NTLM or Negotiate authentication; + * those authenticate the connection - creating a new connection breaks the + * authentication. + */ + +#if defined(USE_NTLM) + /* proxy NTLM authentication */ + if((data->state.authproxy.picked == CURLAUTH_NTLM) || + (data->state.authproxy.picked == CURLAUTH_NTLM_WB)) { + have_ntlm_or_negotiate = TRUE; + auth_started = auth_started + || (conn->proxyntlm.state != NTLMSTATE_NONE); + } + + /* normal NTLM authentication */ + if((data->state.authhost.picked == CURLAUTH_NTLM) || + (data->state.authhost.picked == CURLAUTH_NTLM_WB)) { + have_ntlm_or_negotiate = TRUE; + auth_started = auth_started + || (conn->ntlm.state != NTLMSTATE_NONE); + } +#endif + +#if defined(USE_SPNEGO) + /* proxy Negotiate authentication */ + if(data->state.authproxy.picked == CURLAUTH_NEGOTIATE) { + have_ntlm_or_negotiate = TRUE; + auth_started = auth_started + || (data->state.proxyneg.state != GSS_AUTHNONE); + } + + /* normal Negotiate authentication */ + if(data->state.authhost.picked == CURLAUTH_NEGOTIATE) { + have_ntlm_or_negotiate = TRUE; + auth_started = auth_started + || (data->state.negotiate.state != GSS_AUTHNONE); + } +#endif + + if(have_ntlm_or_negotiate) { + if(remaining_bytes < 2000 || auth_started) { + /* NTLM/Negotiation has started *OR* there is just a little (<2K) + * data left to send, keep on sending. + */ + + /* rewind data when completely done sending! */ + if(!conn->bits.authneg) { + conn->bits.rewindaftersend = TRUE; + infof(data, "Rewind stream after send\n"); + } + + return TRUE; + } + + infof(data, "NTLM/Negotiate send, close instead of sending %" + CURL_FORMAT_CURL_OFF_T " bytes\n", + remaining_bytes); + } +#else + /* unused parameters: */ + (void)conn; + (void)remaining_bytes; +#endif + + return FALSE; +} + /* * Curl_http_perhapsrewind() * @@ -409,8 +481,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) /* figure out how much data we are expected to send */ switch(data->set.httpreq) { case HTTPREQ_POST: - if(data->state.infilesize != -1) - expectsend = data->state.infilesize; + if(data->set.postfieldsize != -1) + expectsend = data->set.postfieldsize; else if(data->set.postfields) expectsend = (curl_off_t)strlen(data->set.postfields); break; @@ -429,36 +501,12 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) conn->bits.rewindaftersend = FALSE; /* default */ if((expectsend == -1) || (expectsend > bytessent)) { -#if defined(USE_NTLM) - /* There is still data left to send */ - if((data->state.authproxy.picked == CURLAUTH_NTLM) || - (data->state.authhost.picked == CURLAUTH_NTLM) || - (data->state.authproxy.picked == CURLAUTH_NTLM_WB) || - (data->state.authhost.picked == CURLAUTH_NTLM_WB)) { - if(((expectsend - bytessent) < 2000) || - (conn->ntlm.state != NTLMSTATE_NONE) || - (conn->proxyntlm.state != NTLMSTATE_NONE)) { - /* The NTLM-negotiation has started *OR* there is just a little (<2K) - data left to send, keep on sending. */ - - /* rewind data when completely done sending! */ - if(!conn->bits.authneg) { - conn->bits.rewindaftersend = TRUE; - infof(data, "Rewind stream after send\n"); - } - - return CURLE_OK; - } - - if(conn->bits.close) - /* this is already marked to get closed */ - return CURLE_OK; + if(conn->bits.close) + /* this is already marked to get closed */ + return CURLE_OK; - infof(data, "NTLM send, close instead of sending %" - CURL_FORMAT_CURL_OFF_T " bytes\n", - (curl_off_t)(expectsend - bytessent)); - } -#endif + if(complete_request(conn, (curl_off_t)(expectsend - bytessent))) + return CURLE_OK; /* This is not NTLM or many bytes left to send: close */ connclose(conn, "Mid-auth HTTP and much data left to send"); @@ -469,7 +517,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) } if(bytessent) - /* we rewind now at once since if we already sent something */ + /* we rewind now at once since we already sent something */ return Curl_readrewind(conn); return CURLE_OK; @@ -685,7 +733,7 @@ Curl_http_output_auth(struct connectdata *conn, if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) || conn->bits.user_passwd) - /* continue please */; + /* continue please */ ; else { authhost->done = TRUE; authproxy->done = TRUE; @@ -786,13 +834,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, while(*auth) { #ifdef USE_SPNEGO if(checkprefix("Negotiate", auth)) { + int neg; *availp |= CURLAUTH_NEGOTIATE; authp->avail |= CURLAUTH_NEGOTIATE; if(authp->picked == CURLAUTH_NEGOTIATE) { if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) { - CURLcode result = Curl_input_negotiate(conn, proxy, auth); - if(!result) { + neg = Curl_input_negotiate(conn, proxy, auth); + if(neg == 0) { DEBUGASSERT(!data->req.newurl); data->req.newurl = strdup(data->change.url); if(!data->req.newurl) @@ -1001,8 +1050,8 @@ static size_t readmoredata(char *buffer, /* move backup data into focus and continue on that */ http->postdata = http->backup.postdata; http->postsize = http->backup.postsize; - conn->data->set.fread_func = http->backup.fread_func; - conn->data->set.in = http->backup.fread_in; + conn->fread_func = http->backup.fread_func; + conn->fread_in = http->backup.fread_in; http->sending++; /* move one step up */ @@ -1033,16 +1082,6 @@ Curl_send_buffer *Curl_add_buffer_init(void) } /* - * Curl_add_buffer_free() frees all associated resources. - */ -void Curl_add_buffer_free(Curl_send_buffer *buff) -{ - if(buff) /* deal with NULL input */ - free(buff->buffer); - free(buff); -} - -/* * Curl_add_buffer_send() sends a header buffer and frees all associated * memory. Body data may be appended to the header data if desired. * @@ -1088,7 +1127,9 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, /* Curl_convert_to_network calls failf if unsuccessful */ if(result) { /* conversion failed, free memory and return to the caller */ - Curl_add_buffer_free(in); + if(in->buffer) + free(in->buffer); + free(in); return result; } @@ -1157,14 +1198,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, ptr = in->buffer + amount; /* backup the currently set pointers */ - http->backup.fread_func = conn->data->set.fread_func; - http->backup.fread_in = conn->data->set.in; + http->backup.fread_func = conn->fread_func; + http->backup.fread_in = conn->fread_in; http->backup.postdata = http->postdata; http->backup.postsize = http->postsize; /* set the new pointers for the request-sending */ - conn->data->set.fread_func = (curl_read_callback)readmoredata; - conn->data->set.in = (void *)conn; + conn->fread_func = (curl_read_callback)readmoredata; + conn->fread_in = (void *)conn; http->postdata = ptr; http->postsize = (curl_off_t)size; @@ -1187,10 +1228,12 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, */ return CURLE_SEND_ERROR; else - Curl_pipeline_leave_write(conn); + conn->writechannel_inuse = FALSE; } } - Curl_add_buffer_free(in); + if(in->buffer) + free(in->buffer); + free(in); return result; } @@ -1213,7 +1256,8 @@ CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...) return result; } /* If we failed, we cleanup the whole buffer and return error */ - free(in->buffer); + if(in->buffer) + free(in->buffer); free(in); return CURLE_OUT_OF_MEMORY; } @@ -1393,7 +1437,7 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done) } #endif -#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ +#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) /* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only. It should be made to query the generic SSL layer instead. */ @@ -1432,7 +1476,7 @@ static int https_getsock(struct connectdata *conn, return GETSOCK_BLANK; } #endif /* USE_SSL */ -#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */ +#endif /* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL */ /* * Curl_http_done() gets called from Curl_done() after a single HTTP request @@ -1443,19 +1487,16 @@ CURLcode Curl_http_done(struct connectdata *conn, CURLcode status, bool premature) { struct SessionHandle *data = conn->data; - struct HTTP *http = data->req.protop; -#ifdef USE_NGHTTP2 - struct http_conn *httpc = &conn->proto.httpc; -#endif + struct HTTP *http =data->req.protop; Curl_unencode_cleanup(conn); #ifdef USE_SPNEGO if(data->state.proxyneg.state == GSS_AUTHSENT || - data->state.negotiate.state == GSS_AUTHSENT) { - /* add forbid re-use if http-code != 401/407 as a WA only needed for - * 401/407 that signal auth failure (empty) otherwise state will be RECV - * with current code */ + data->state.negotiate.state == GSS_AUTHSENT) { + /* add forbid re-use if http-code != 401 as a WA + * only needed for 401 that failed handling + * otherwie state will be RECV with current code */ if((data->req.httpcode != 401) && (data->req.httpcode != 407)) connclose(conn, "Negotiate transfer completed"); Curl_cleanup_negotiate(data); @@ -1463,6 +1504,8 @@ CURLcode Curl_http_done(struct connectdata *conn, #endif /* set the proper values (possibly modified on POST) */ + conn->fread_func = data->set.fread_func; /* restore */ + conn->fread_in = data->set.in; /* restore */ conn->seek_func = data->set.seek_func; /* restore */ conn->seek_client = data->set.seek_client; /* restore */ @@ -1470,26 +1513,12 @@ CURLcode Curl_http_done(struct connectdata *conn, return CURLE_OK; if(http->send_buffer) { - Curl_add_buffer_free(http->send_buffer); - http->send_buffer = NULL; /* clear the pointer */ - } + Curl_send_buffer *buff = http->send_buffer; -#ifdef USE_NGHTTP2 - if(http->header_recvbuf) { - DEBUGF(infof(data, "free header_recvbuf!!\n")); - Curl_add_buffer_free(http->header_recvbuf); - http->header_recvbuf = NULL; /* clear the pointer */ - for(; http->push_headers_used > 0; --http->push_headers_used) { - free(http->push_headers[http->push_headers_used - 1]); - } - free(http->push_headers); - http->push_headers = NULL; - } - if(http->stream_id) { - nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0); - http->stream_id = 0; + free(buff->buffer); + free(buff); + http->send_buffer = NULL; /* clear the pointer */ } -#endif if(HTTPREQ_POST_FORM == data->set.httpreq) { data->req.bytecount = http->readbytecount + http->writebytecount; @@ -1553,11 +1582,10 @@ static CURLcode expect100(struct SessionHandle *data, const char *ptr; data->state.expect100header = FALSE; /* default to false unless it is set to TRUE below */ - if(use_http_1_1plus(data, conn) && - (conn->httpversion != 20)) { - /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an - Expect: 100-continue to the headers which actually speeds up post - operations (as there is one packet coming back from the web server) */ + if(use_http_1_1plus(data, conn)) { + /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect: + 100-continue to the headers which actually speeds up post operations + (as there is one packet coming back from the web server) */ ptr = Curl_checkheaders(conn, "Expect:"); if(ptr) { data->state.expect100header = @@ -1776,8 +1804,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(conn->httpversion < 20) { /* unless the connection is re-used and already http2 */ switch(conn->negnpn) { - case CURL_HTTP_VERSION_2_0: - conn->httpversion = 20; /* we know we're on HTTP/2 now */ + case NPN_HTTP2: result = Curl_http2_init(conn); if(result) return result; @@ -1790,7 +1817,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(result) return result; break; - case CURL_HTTP_VERSION_1_1: + case NPN_HTTP1_1: /* continue with HTTP/1.1 when explicitly requested */ break; default: @@ -1808,8 +1835,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) http = data->req.protop; if(!data->state.this_is_a_follow) { - /* Free to avoid leaking memory on multiple requests*/ - free(data->state.first_host); + /* this is not a followed location, get the original host name */ + if(data->state.first_host) + /* Free to avoid leaking memory on multiple requests*/ + free(data->state.first_host); data->state.first_host = strdup(conn->host.name); if(!data->state.first_host) @@ -1853,7 +1882,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) it might have been used in the proxy connect, but if we have got a header with the user-agent string specified, we erase the previously made string here. */ - if(Curl_checkheaders(conn, "User-Agent:")) { + if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) { free(conn->allocptr.uagent); conn->allocptr.uagent=NULL; } @@ -1996,14 +2025,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } #endif - if(strcmp("Host:", ptr)) { - conn->allocptr.host = aprintf("%s\r\n", ptr); - if(!conn->allocptr.host) - return CURLE_OUT_OF_MEMORY; - } - else - /* when clearing the header */ - conn->allocptr.host = NULL; + conn->allocptr.host = NULL; } else { /* When building Host: headers, we must put the host name within @@ -2198,7 +2220,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) && !Curl_checkheaders(conn, "Range:")) { /* if a line like this was already allocated, free the previous one */ - free(conn->allocptr.rangeline); + if(conn->allocptr.rangeline) + free(conn->allocptr.rangeline); conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->state.range); } @@ -2206,7 +2229,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) !Curl_checkheaders(conn, "Content-Range:")) { /* if a line like this was already allocated, free the previous one */ - free(conn->allocptr.rangeline); + if(conn->allocptr.rangeline) + free(conn->allocptr.rangeline); if(data->set.set_resume_from < 0) { /* Upload resume was asked for, but we don't know the size of the @@ -2270,11 +2294,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) Curl_add_bufferf(req_buffer, "%s" /* ftp typecode (;type=x) */ " HTTP/%s\r\n" /* HTTP version */ - "%s" /* host */ "%s" /* proxyuserpwd */ "%s" /* userpwd */ "%s" /* range */ "%s" /* user agent */ + "%s" /* host */ "%s" /* accept */ "%s" /* TE: */ "%s" /* accept-encoding */ @@ -2284,7 +2308,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) ftp_typecode, httpstring, - (conn->allocptr.host?conn->allocptr.host:""), conn->allocptr.proxyuserpwd? conn->allocptr.proxyuserpwd:"", conn->allocptr.userpwd?conn->allocptr.userpwd:"", @@ -2294,6 +2317,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) *data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)? conn->allocptr.uagent:"", + (conn->allocptr.host?conn->allocptr.host:""), http->p_accept?http->p_accept:"", conn->allocptr.te?conn->allocptr.te:"", (data->set.str[STRING_ENCODING] && @@ -2434,14 +2458,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* Get the currently set callback function pointer and store that in the form struct since we might want the actual user-provided callback later - on. The data->set.fread_func pointer itself will be changed for the + on. The conn->fread_func pointer itself will be changed for the multipart case to the function that returns a multipart formatted stream. */ - http->form.fread_func = data->set.fread_func; + http->form.fread_func = conn->fread_func; /* Set the read function to read from the generated form data */ - data->set.fread_func = (curl_read_callback)Curl_FormReader; - data->set.in = &http->form; + conn->fread_func = (curl_read_callback)Curl_FormReader; + conn->fread_in = &http->form; http->sending = HTTPSEND_BODY; @@ -2561,8 +2585,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) postsize = 0; else { /* figure out the size of the postfields */ - postsize = (data->state.infilesize != -1)? - data->state.infilesize: + postsize = (data->set.postfieldsize != -1)? + data->set.postfieldsize: (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1); } @@ -2659,8 +2683,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) http->sending = HTTPSEND_BODY; - data->set.fread_func = (curl_read_callback)readmoredata; - data->set.in = (void *)conn; + conn->fread_func = (curl_read_callback)readmoredata; + conn->fread_in = (void *)conn; /* set the upload size to the progress meter */ Curl_pgrsSetUploadSize(data, http->postsize); @@ -2685,7 +2709,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } - else if(data->state.infilesize) { + else if(data->set.postfieldsize) { /* set the upload size to the progress meter */ Curl_pgrsSetUploadSize(data, postsize?postsize:-1); @@ -3076,19 +3100,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, } } - /* At this point we have some idea about the fate of the connection. - If we are closing the connection it may result auth failure. */ -#if defined(USE_NTLM) - if(conn->bits.close && - (((data->req.httpcode == 401) && - (conn->ntlm.state == NTLMSTATE_TYPE2)) || - ((data->req.httpcode == 407) && - (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) { - infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); - data->state.authproblem = TRUE; - } -#endif - /* * When all the headers have been parsed, see if we should give * up and return an error. @@ -3366,23 +3377,28 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, } else if(conn->httpversion == 20 || (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) { - DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n")); - - /* HTTP/2 cannot blacklist multiplexing since it is a core - functionality of the protocol */ - conn->bundle->multiuse = BUNDLE_MULTIPLEX; + /* Don't enable pipelining for HTTP/2 or upgraded connection. For + HTTP/2, we do not support multiplexing. In general, requests + cannot be pipelined in upgraded connection, since it is now + different protocol. */ + DEBUGF(infof(data, + "HTTP 2 or upgraded connection do not support " + "pipelining for now\n")); } else if(conn->httpversion >= 11 && !conn->bits.close) { + struct connectbundle *cb_ptr; + /* If HTTP version is >= 1.1 and connection is persistent server supports pipelining. */ DEBUGF(infof(data, "HTTP 1.1 or later with persistent connection, " "pipelining supported\n")); /* Activate pipelining if needed */ - if(conn->bundle) { + cb_ptr = conn->bundle; + if(cb_ptr) { if(!Curl_pipeline_site_blacklisted(data, conn)) - conn->bundle->multiuse = BUNDLE_PIPELINING; + cb_ptr->server_supports_pipelining = TRUE; } } @@ -3461,17 +3477,14 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, } } else if(checkprefix("Server:", k->p)) { - if(conn->httpversion < 20) { - /* only do this for non-h2 servers */ - char *server_name = Curl_copy_header_value(k->p); - - /* Turn off pipelining if the server version is blacklisted */ - if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) { - if(Curl_pipeline_server_blacklisted(data, server_name)) - conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; - } - free(server_name); + char *server_name = Curl_copy_header_value(k->p); + + /* Turn off pipelining if the server version is blacklisted */ + if(conn->bundle && conn->bundle->server_supports_pipelining) { + if(Curl_pipeline_server_blacklisted(data, server_name)) + conn->bundle->server_supports_pipelining = FALSE; } + Curl_safefree(server_name); } else if((conn->httpversion == 10) && conn->bits.httpproxy && @@ -3568,6 +3581,14 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, k->auto_decoding = GZIP; start += 6; } + else if(checkprefix("compress", start)) { + k->auto_decoding = COMPRESS; + start += 8; + } + else if(checkprefix("x-compress", start)) { + k->auto_decoding = COMPRESS; + start += 10; + } else /* unknown! */ break; @@ -3600,6 +3621,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, else if(checkprefix("gzip", start) || checkprefix("x-gzip", start)) k->auto_decoding = GZIP; + else if(checkprefix("compress", start) + || checkprefix("x-compress", start)) + k->auto_decoding = COMPRESS; } else if(checkprefix("Content-Range:", k->p)) { /* Content-Range: bytes [num]- @@ -3665,7 +3689,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, result = Curl_http_input_auth(conn, proxy, auth); - free(auth); + Curl_safefree(auth); if(result) return result;