Loading CHANGES +8 −0 Original line number Diff line number Diff line Loading @@ -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. Loading RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -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: Loading TODO-RELEASE +0 −3 Original line number Diff line number Diff line Loading @@ -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 Loading lib/transfer.c +86 −20 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; Loading @@ -177,21 +214,37 @@ 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 */ } *nreadp = nread; nread+=strlen(endofline_native); /* for the added end of line */ #ifdef CURL_DOES_CONVERSIONS if(data->set.prefer_ascii) { } 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 */ Loading @@ -200,6 +253,9 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp) } } #endif /* CURL_DOES_CONVERSIONS */ } *nreadp = nread; return CURLE_OK; } Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading
CHANGES +8 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -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: Loading
TODO-RELEASE +0 −3 Original line number Diff line number Diff line Loading @@ -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 Loading
lib/transfer.c +86 −20 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; Loading @@ -177,21 +214,37 @@ 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 */ } *nreadp = nread; nread+=strlen(endofline_native); /* for the added end of line */ #ifdef CURL_DOES_CONVERSIONS if(data->set.prefer_ascii) { } 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 */ Loading @@ -200,6 +253,9 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp) } } #endif /* CURL_DOES_CONVERSIONS */ } *nreadp = nread; return CURLE_OK; } Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading