From 0790b2791091ca46bed3813dc7d04cd3f30e5dac Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Apr 2011 23:24:52 +0200 Subject: HTTP: add support for gzip and deflate Transfer-Encoding Transfer-Encoding differs from Content-Encoding in a few subtle ways, but primarily it concerns the transfer only and not the content so when discovered to be compressed we know we have to uncompress it. There will only arrive compressed transfers in a response after we have requested them with the appropriate TE: header. Test case 1122 and 1123 verify. --- lib/http.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- lib/url.c | 1 + lib/urldata.h | 23 ++++++++++--------- 3 files changed, 80 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/http.c b/lib/http.c index 175ec7be7..6b14fab19 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1728,6 +1728,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return CURLE_OUT_OF_MEMORY; } +#if 0 + if(!Curl_checkheaders(data, "TE:")) { + Curl_safefree(conn->allocptr.te); + conn->allocptr.te = aprintf("TE: %s\r\n", "gzip"); + if(!conn->allocptr.te) + return CURLE_OUT_OF_MEMORY; + } +#endif + ptr = Curl_checkheaders(data, "Transfer-Encoding:"); if(ptr) { /* Some kind of TE is requested, check if 'chunked' is chosen */ @@ -2058,6 +2067,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) "%s" /* user agent */ "%s" /* host */ "%s" /* accept */ + "%s" /* TE: */ "%s" /* accept-encoding */ "%s" /* referer */ "%s" /* Proxy-Connection */ @@ -2075,6 +2085,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) conn->allocptr.uagent:"", (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ http->p_accept?http->p_accept:"", + conn->allocptr.te?conn->allocptr.te:"", (data->set.str[STRING_ENCODING] && *data->set.str[STRING_ENCODING] && conn->allocptr.accept_encoding)? @@ -3127,8 +3138,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, */ conn->bits.close = TRUE; /* close when done */ } - else if(Curl_compareheader(k->p, "Transfer-Encoding:", "chunked") && - !(conn->handler->protocol & CURLPROTO_RTSP)) { + else if(checkprefix("Transfer-Encoding:", k->p)) { + /* One or more encodings. We check for chunked and/or a compression + algorithm. */ /* * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding * means that the server will send a series of "chunks". Each @@ -3137,10 +3149,60 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, * with the previously mentioned size. There can be any amount * of chunks, and a chunk-data set to zero signals the * end-of-chunks. */ - k->chunk = TRUE; /* chunks coming our way */ - /* init our chunky engine */ - Curl_httpchunk_init(conn); + char *start; + + /* Find the first non-space letter */ + start = k->p + 18; + + do { + /* skip whitespaces and commas */ + while(*start && (ISSPACE(*start) || (*start == ','))) + start++; + + if(checkprefix("chunked", start)) { + k->chunk = TRUE; /* chunks coming our way */ + + /* init our chunky engine */ + Curl_httpchunk_init(conn); + + start += 7; + } + + if(k->content_encoding) + /* TODO: we only support the first mentioned compression for now */ + break; + + if(checkprefix("identity", start)) { + k->content_encoding = IDENTITY; + start += 8; + } + else if(checkprefix("deflate", start)) { + k->content_encoding = DEFLATE; + start += 7; + } + else if(checkprefix("gzip", start)) { + k->content_encoding = GZIP; + start += 4; + } + else if(checkprefix("x-gzip", start)) { + k->content_encoding = GZIP; + start += 6; + } + else if(checkprefix("compress", start)) { + k->content_encoding = COMPRESS; + start += 8; + } + else if(checkprefix("x-compress", start)) { + k->content_encoding = COMPRESS; + start += 10; + } + else + /* unknown! */ + break; + + } while(1); + } else if(checkprefix("Content-Encoding:", k->p) && data->set.str[STRING_ENCODING]) { diff --git a/lib/url.c b/lib/url.c index c7fcdfe96..a31c28033 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2549,6 +2549,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.uagent); Curl_safefree(conn->allocptr.userpwd); Curl_safefree(conn->allocptr.accept_encoding); + Curl_safefree(conn->allocptr.te); Curl_safefree(conn->allocptr.rangeline); Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); diff --git a/lib/urldata.h b/lib/urldata.h index d1718a9a4..f2fb279d4 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -837,18 +837,19 @@ struct connectdata { well be the same we read from. CURL_SOCKET_BAD disables */ - /** Dynamicly allocated strings, may need to be freed before this **/ - /** struct is killed. **/ + /** Dynamicly allocated strings, MUST be freed before this **/ + /** struct is killed. **/ struct dynamically_allocated_data { - char *proxyuserpwd; /* free later if not NULL! */ - char *uagent; /* free later if not NULL! */ - char *accept_encoding; /* free later if not NULL! */ - char *userpwd; /* free later if not NULL! */ - char *rangeline; /* free later if not NULL! */ - char *ref; /* free later if not NULL! */ - char *host; /* free later if not NULL */ - char *cookiehost; /* free later if not NULL */ - char *rtsp_transport; /* free later if not NULL */ + char *proxyuserpwd; + char *uagent; + char *accept_encoding; + char *userpwd; + char *rangeline; + char *ref; + char *host; + char *cookiehost; + char *rtsp_transport; + char *te; /* TE: request header */ } allocptr; int sec_complete; /* if kerberos is enabled for this connection */ -- cgit v1.2.3