From: Daniel Stenberg Date: Mon, 11 Nov 2002 08:40:37 +0000 (+0000) Subject: Now supports "Transfer-Encoding: chunked" for HTTP PUT operations where the X-Git-Tag: upstream/7.37.1~15140 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=03c22b4576e99abf6385f64f54e3fb85c782cf0f;p=platform%2Fupstream%2Fcurl.git Now supports "Transfer-Encoding: chunked" for HTTP PUT operations where the size of the uploaded file is unknown. --- diff --git a/lib/http.c b/lib/http.c index 35cae48..460ce0a 100644 --- a/lib/http.c +++ b/lib/http.c @@ -485,6 +485,7 @@ CURLcode Curl_http(struct connectdata *conn) struct Cookie *co=NULL; /* no cookies from start */ char *ppath = conn->ppath; /* three previous function arguments */ char *host = conn->name; + const char *te = ""; /* tranfer-encoding */ if(!conn->proto.http) { /* Only allocate this struct if we don't already have it! */ @@ -546,6 +547,14 @@ CURLcode Curl_http(struct connectdata *conn) conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->set.cookie); } + if(conn->upload_chunky) { + if(!checkheaders(data, "Transfer-Encoding:")) { + te = "Transfer-Encoding: chunked\r\n"; + } + /* else + our header was already added, what to do now? */ + } + if(data->cookies) { co = Curl_cookie_getlist(data->cookies, host, ppath, @@ -717,7 +726,8 @@ CURLcode Curl_http(struct connectdata *conn) "%s" /* pragma */ "%s" /* accept */ "%s" /* accept-encoding */ - "%s", /* referer */ + "%s" /* referer */ + "%s",/* transfer-encoding */ data->set.customrequest?data->set.customrequest: (data->set.no_body?"HEAD": @@ -739,7 +749,8 @@ CURLcode Curl_http(struct connectdata *conn) http->p_accept?http->p_accept:"", (data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)? conn->allocptr.accept_encoding:"", /* 08/28/02 jhrg */ - (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: */ + (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: */, + te ); if(co) { diff --git a/lib/transfer.c b/lib/transfer.c index 7c9dda7..58ae8c9 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -899,11 +899,46 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* only read more data if there's no upload data already present in the upload buffer */ if(0 == conn->upload_present) { + size_t buffersize = BUFSIZE; /* init the "upload from here" pointer */ conn->upload_fromhere = k->uploadbuf; - nread = data->set.fread(conn->upload_fromhere, 1, - BUFSIZE, data->set.in); + if(!k->upload_done) { + + if(conn->upload_chunky) { + /* if chunked Transfer-Encoding */ + buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */ + conn->upload_fromhere += 10; /* 32bit hex + CRLF */ + } + + nread = data->set.fread(conn->upload_fromhere, 1, + buffersize, data->set.in); + + if(conn->upload_chunky) { + /* if chunked Transfer-Encoding */ + char hexbuffer[9]; + int hexlen = snprintf(hexbuffer, sizeof(hexbuffer), + "%x\r\n", nread); + /* move buffer pointer */ + conn->upload_fromhere -= hexlen; + nread += hexlen; + + /* copy the prefix to the buffer */ + memcpy(conn->upload_fromhere, hexbuffer, hexlen); + if(nread>0) { + /* append CRLF to the data */ + memcpy(conn->upload_fromhere + + nread, "\r\n", 2); + nread+=2; + } + else { + /* mark this as done once this chunk is transfered */ + k->upload_done = TRUE; + } + } + } + else + nread = 0; /* we're done uploading/reading */ /* the signed int typecase of nread of for systems that has unsigned size_t */ @@ -967,6 +1002,12 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* we've uploaded that buffer now */ conn->upload_fromhere = k->uploadbuf; conn->upload_present = 0; /* no more bytes left */ + + if(k->upload_done) { + /* switch off writing, we're done! */ + k->keepon &= ~KEEP_WRITE; /* we're done writing */ + FD_ZERO(&k->wkeepfd); + } } if(data->set.verbose) diff --git a/lib/url.c b/lib/url.c index 92c4dd9..0274cb0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1769,6 +1769,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, is later set "for real" using Curl_pgrsStartNow(). */ conn->data->progress.start = conn->created; + conn->upload_chunky = + ((conn->protocol&PROT_HTTP) && + data->set.upload && + (data->set.infilesize == -1) && + (data->set.httpversion != CURL_HTTP_VERSION_1_0))? + /* HTTP, upload, unknown file size and not HTTP 1.0 */ + TRUE: + /* else, no chunky upload */ + FALSE; + /*********************************************************** * We need to allocate memory to store the path in. We get the size of the * full URL to be sure, and we need to make it at least 256 bytes since diff --git a/lib/urldata.h b/lib/urldata.h index e521d32..523b58f 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -285,6 +285,8 @@ struct Curl_transfer_keeper { fd_set wkeepfd; int keepon; + bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload + and we're uploading the last chunk */ }; @@ -450,6 +452,9 @@ struct connectdata { bool do_more; /* this is set TRUE if the ->curl_do_more() function is supposed to be called, after ->curl_do() */ + + bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding + on upload */ }; /* The end of connectdata. 08/27/02 jhrg */