diff options
Diffstat (limited to 'lib/transfer.c')
-rw-r--r-- | lib/transfer.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/lib/transfer.c b/lib/transfer.c index 7c9dda7c7..58ae8c96a 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) |