aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/http.c15
-rw-r--r--lib/transfer.c45
-rw-r--r--lib/url.c10
-rw-r--r--lib/urldata.h5
4 files changed, 71 insertions, 4 deletions
diff --git a/lib/http.c b/lib/http.c
index 35cae48e8..460ce0a86 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> <CRLF> */
+ (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */,
+ te
);
if(co) {
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)
diff --git a/lib/url.c b/lib/url.c
index 92c4dd926..0274cb0f9 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 e521d325c..523b58f2e 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 */