Now supports "Transfer-Encoding: chunked" for HTTP PUT operations where the
size of the uploaded file is unknown.
This commit is contained in:
parent
ef749fa9ce
commit
03c22b4576
15
lib/http.c
15
lib/http.c
@ -485,6 +485,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
struct Cookie *co=NULL; /* no cookies from start */
|
struct Cookie *co=NULL; /* no cookies from start */
|
||||||
char *ppath = conn->ppath; /* three previous function arguments */
|
char *ppath = conn->ppath; /* three previous function arguments */
|
||||||
char *host = conn->name;
|
char *host = conn->name;
|
||||||
|
const char *te = ""; /* tranfer-encoding */
|
||||||
|
|
||||||
if(!conn->proto.http) {
|
if(!conn->proto.http) {
|
||||||
/* Only allocate this struct if we don't already have it! */
|
/* 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);
|
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) {
|
if(data->cookies) {
|
||||||
co = Curl_cookie_getlist(data->cookies,
|
co = Curl_cookie_getlist(data->cookies,
|
||||||
host, ppath,
|
host, ppath,
|
||||||
@ -717,7 +726,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
"%s" /* pragma */
|
"%s" /* pragma */
|
||||||
"%s" /* accept */
|
"%s" /* accept */
|
||||||
"%s" /* accept-encoding */
|
"%s" /* accept-encoding */
|
||||||
"%s", /* referer */
|
"%s" /* referer */
|
||||||
|
"%s",/* transfer-encoding */
|
||||||
|
|
||||||
data->set.customrequest?data->set.customrequest:
|
data->set.customrequest?data->set.customrequest:
|
||||||
(data->set.no_body?"HEAD":
|
(data->set.no_body?"HEAD":
|
||||||
@ -739,7 +749,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
http->p_accept?http->p_accept:"",
|
http->p_accept?http->p_accept:"",
|
||||||
(data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
|
(data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
|
||||||
conn->allocptr.accept_encoding:"", /* 08/28/02 jhrg */
|
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) {
|
if(co) {
|
||||||
|
@ -899,11 +899,46 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* only read more data if there's no upload data already
|
/* only read more data if there's no upload data already
|
||||||
present in the upload buffer */
|
present in the upload buffer */
|
||||||
if(0 == conn->upload_present) {
|
if(0 == conn->upload_present) {
|
||||||
|
size_t buffersize = BUFSIZE;
|
||||||
/* init the "upload from here" pointer */
|
/* init the "upload from here" pointer */
|
||||||
conn->upload_fromhere = k->uploadbuf;
|
conn->upload_fromhere = k->uploadbuf;
|
||||||
|
|
||||||
nread = data->set.fread(conn->upload_fromhere, 1,
|
if(!k->upload_done) {
|
||||||
BUFSIZE, data->set.in);
|
|
||||||
|
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
|
/* the signed int typecase of nread of for systems that has
|
||||||
unsigned size_t */
|
unsigned size_t */
|
||||||
@ -967,6 +1002,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* we've uploaded that buffer now */
|
/* we've uploaded that buffer now */
|
||||||
conn->upload_fromhere = k->uploadbuf;
|
conn->upload_fromhere = k->uploadbuf;
|
||||||
conn->upload_present = 0; /* no more bytes left */
|
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)
|
if(data->set.verbose)
|
||||||
|
10
lib/url.c
10
lib/url.c
@ -1769,6 +1769,16 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
is later set "for real" using Curl_pgrsStartNow(). */
|
is later set "for real" using Curl_pgrsStartNow(). */
|
||||||
conn->data->progress.start = conn->created;
|
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
|
* 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
|
* full URL to be sure, and we need to make it at least 256 bytes since
|
||||||
|
@ -285,6 +285,8 @@ struct Curl_transfer_keeper {
|
|||||||
fd_set wkeepfd;
|
fd_set wkeepfd;
|
||||||
int keepon;
|
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
|
bool do_more; /* this is set TRUE if the ->curl_do_more() function is
|
||||||
supposed to be called, after ->curl_do() */
|
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 */
|
/* The end of connectdata. 08/27/02 jhrg */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user