1
0
mirror of https://github.com/moparisthebest/curl synced 2024-08-13 17:03:50 -04:00

David McCreedy's "transfer.c fixes for CURL_DO_LINEEND_CONV and non-ASCII platform HTTP requests" patch

This commit is contained in:
Yang Tse 2009-05-04 09:47:02 +00:00
parent cc8c2efff2
commit 4422f80ae7
4 changed files with 95 additions and 23 deletions

View File

@ -6,6 +6,14 @@
Changelog
Yang Tse (4 May 2009)
- Applied David McCreedy's "transfer.c fixes for CURL_DO_LINEEND_CONV and
non-ASCII platform HTTP requests" patch addressing two HTTP PUT problems:
1) On non-ASCII platforms not all of the protocol portions of the PUT are
being translated to ASCII. 2) On all platforms the line endings of part of
the protocol portions are mangled from CRLF to CRCRLF if data->set.crlf or
data->set.prefer_ascii are set (depending on CURL_DO_LINEEND_CONV).
Daniel Fandrich (3 May 2009)
- Added and disabled test case 563 which shows KNOWN_BUGS #59. The bug
report failed to mention that a proxy must be used to reproduce it.

View File

@ -38,6 +38,7 @@ This release includes the following bugfixes:
o Enhanced upload speeds on Windows
o TFTP problems after a failed transfer to the same host
o improved out of the box TPF compatibility
o HTTP PUT protocol line endings portions mangled from CRLF to CRCRLF
This release includes the following known bugs:

View File

@ -9,9 +9,6 @@ To be addressed in 7.19.5 (planned release: May 2009)
228 - rpath problems in linking with custom openssl
232 - [PATCH] transfer.c fixes for CURL_DO_LINEEND_CONV and non-ASCII
platform HTTP requests
233 - [PATCH] Allow Curl test suite test #251 to work if client and server
are on different machines

View File

@ -130,12 +130,19 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
struct SessionHandle *data = conn->data;
size_t buffersize = (size_t)bytes;
int nread;
int sending_http_headers = FALSE;
if(data->req.upload_chunky) {
/* if chunked Transfer-Encoding */
buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */
data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
}
if((data->state.proto.http)
&& (data->state.proto.http->sending == HTTPSEND_REQUEST)) {
/* We're sending the HTTP request headers, not the data.
Remember that so we don't re-translate them into garbage. */
sending_http_headers = TRUE;
}
/* this function returns a size_t, so we typecast to int to prevent warnings
with picky compilers */
@ -166,10 +173,40 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
}
if(!data->req.forbidchunk && data->req.upload_chunky) {
/* if chunked Transfer-Encoding */
/* if chunked Transfer-Encoding
* build chunk:
*
* <HEX SIZE> CRLF
* <DATA> CRLF
*/
/* On non-ASCII platforms the <DATA> may or may not be
translated based on set.prefer_ascii while the protocol
portion must always be translated to the network encoding.
To further complicate matters, line end conversion might be
done later on, so we need to prevent CRLFs from becoming
CRCRLFs if that's the case. To do this we use bare LFs
here, knowing they'll become CRLFs later on.
*/
char hexbuffer[11];
int hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
"%x\r\n", nread);
const char *endofline_native;
const char *endofline_network;
int hexlen;
#ifdef CURL_DO_LINEEND_CONV
if((data->set.crlf) || (data->set.prefer_ascii)) {
#else
if(data->set.crlf) {
#endif /* CURL_DO_LINEEND_CONV */
/* \n will become \r\n later on */
endofline_native = "\n";
endofline_network = "\x0a";
} else {
endofline_native = "\r\n";
endofline_network = "\x0d\x0a";
}
hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
"%x%s", nread, endofline_native);
/* move buffer pointer */
data->req.upload_fromhere -= hexlen;
nread += hexlen;
@ -177,30 +214,49 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
/* copy the prefix to the buffer, leaving out the NUL */
memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
/* always append CRLF to the data */
memcpy(data->req.upload_fromhere + nread, "\r\n", 2);
/* always append ASCII CRLF to the data */
memcpy(data->req.upload_fromhere + nread,
endofline_network,
strlen(endofline_network));
#ifdef CURL_DOES_CONVERSIONS
CURLcode res;
int length;
if(data->set.prefer_ascii) {
/* translate the protocol and data */
length = nread;
} else {
/* just translate the protocol portion */
length = strlen(hexbuffer);
}
res = Curl_convert_to_network(data, data->req.upload_fromhere, length);
/* Curl_convert_to_network calls failf if unsuccessful */
if(res != CURLE_OK) {
return(res);
}
#endif /* CURL_DOES_CONVERSIONS */
if((nread - hexlen) == 0) {
/* mark this as done once this chunk is transfered */
data->req.upload_done = TRUE;
}
nread+=2; /* for the added CRLF */
nread+=strlen(endofline_native); /* for the added end of line */
#ifdef CURL_DOES_CONVERSIONS
} else {
if((data->set.prefer_ascii) && (!sending_http_headers)) {
CURLcode res;
res = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
/* Curl_convert_to_network calls failf if unsuccessful */
if(res != CURLE_OK) {
return(res);
}
}
#endif /* CURL_DOES_CONVERSIONS */
}
*nreadp = nread;
#ifdef CURL_DOES_CONVERSIONS
if(data->set.prefer_ascii) {
CURLcode res;
res = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
/* Curl_convert_to_network calls failf if unsuccessful */
if(res != CURLE_OK) {
return(res);
}
}
#endif /* CURL_DOES_CONVERSIONS */
return CURLE_OK;
}
@ -1404,6 +1460,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
ssize_t bytes_written;
CURLcode result;
ssize_t nread; /* number of bytes read */
int sending_http_headers = FALSE;
if((k->bytecount == 0) && (k->writebytecount == 0))
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
@ -1439,6 +1496,15 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
break;
}
if(data->state.proto.http) {
if(data->state.proto.http->sending == HTTPSEND_REQUEST) {
/* We're sending the HTTP request headers, not the data.
Remember that so we don't change the line endings. */
sending_http_headers = TRUE;
} else {
sending_http_headers = FALSE;
}
}
result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
if(result)
return result;
@ -1470,11 +1536,11 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
/* convert LF to CRLF if so asked */
#ifdef CURL_DO_LINEEND_CONV
/* always convert if we're FTPing in ASCII mode */
if((data->set.crlf) || (data->set.prefer_ascii))
if(((data->set.crlf) || (data->set.prefer_ascii))
#else
if(data->set.crlf)
if((data->set.crlf)
#endif /* CURL_DO_LINEEND_CONV */
{
&& (!sending_http_headers)) {
if(data->state.scratch == NULL)
data->state.scratch = malloc(2*BUFSIZE);
if(data->state.scratch == NULL) {