Loading CHANGES +6 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,12 @@ Changelog Daniel (12 July 2005) - Adrian Schuur added trailer support in the chunked encoding stream. The trailer is then sent to the normal header callback/stream. I wrote up test case 266 to verify the basic functionality. Do note that test case 34 contains a flawed chunked encoding stream that still works the same. Daniel (5 July 2005) - Gisle Vanem came up with a nice little work-around for bug #1230118. It seems the Windows (MSVC) libc time functions may return data one hour off if Loading RELEASE-NOTES +4 −2 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ Curl and libcurl 7.14.1 This release includes the following changes: o trailer support for chunked encoded data streams o -x/CURL_PROXY strings may now contain user+password o --trace-time now outputs the full microsecond, all 6 digits Loading Loading @@ -41,6 +42,7 @@ This release would not have looked like this without help, code, reports and advice from friends like these: John McGowan, Georg Wicherski, Andres Garcia, Eric Cooper, Todd Kulesza, Tupone Alfredo, Gisle Vanem, David Shaw, Andrew Bushnell, Dan Fandrich Tupone Alfredo, Gisle Vanem, David Shaw, Andrew Bushnell, Dan Fandrich, Adrian Schuur Thanks! (and sorry if I forgot to mention someone) lib/http_chunks.c +69 −4 Original line number Diff line number Diff line Loading @@ -153,12 +153,19 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, if(*datap == '\n') { /* we're now expecting data to come, unless size was zero! */ if(0 == ch->datasize) { ch->state = CHUNK_STOP; /* stop reading! */ if (conn->bits.trailerHdrPresent!=TRUE) { /* No Trailer: header found - revert to original Curl processing */ ch->state = CHUNK_STOP; if (1 == length) { /* This was the final byte, return right now */ /* This is the final byte, return right now */ return CHUNKE_STOP; } } else { ch->state = CHUNK_TRAILER; /* attempt to read trailers */ conn->trlPos=0; } } else ch->state = CHUNK_DATA; } Loading Loading @@ -250,6 +257,64 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, return CHUNKE_BAD_CHUNK; break; case CHUNK_TRAILER: /* conn->trailer is assumed to be freed in url.c on a connection basis */ if (conn->trlPos >= conn->trlMax) { char *ptr; if(conn->trlMax) { conn->trlMax *= 2; ptr = (char*)realloc(conn->trailer,conn->trlMax); } else { conn->trlMax=128; ptr = (char*)malloc(conn->trlMax); } if(!ptr) return CHUNKE_OUT_OF_MEMORY; conn->trailer = ptr; } conn->trailer[conn->trlPos++]=*datap; if(*datap == '\r') ch->state = CHUNK_TRAILER_CR; else { datap++; length--; } break; case CHUNK_TRAILER_CR: if(*datap == '\r') { ch->state = CHUNK_TRAILER_POSTCR; datap++; length--; } else return CHUNKE_BAD_CHUNK; break; case CHUNK_TRAILER_POSTCR: if (*datap == '\n') { conn->trailer[conn->trlPos++]='\n'; conn->trailer[conn->trlPos]=0; if (conn->trlPos==2) { ch->state = CHUNK_STOP; return CHUNKE_STOP; } else { Curl_client_write(conn->data, CLIENTWRITE_HEADER, conn->trailer, conn->trlPos); } ch->state = CHUNK_TRAILER; conn->trlPos=0; datap++; length--; } else return CHUNKE_BAD_CHUNK; break; case CHUNK_STOP: /* If we arrive here, there is data left in the end of the buffer even if there's no more chunks to read */ Loading lib/http_chunks.h +18 −2 Original line number Diff line number Diff line Loading @@ -52,8 +52,8 @@ typedef enum { /* POSTCR should get a CR and nothing else, then move to POSTLF */ CHUNK_POSTCR, /* POSTLF should get a LF and nothing else, then move back to HEX as the CRLF combination marks the end of a chunk */ /* POSTLF should get a LF and nothing else, then move back to HEX as the CRLF combination marks the end of a chunk */ CHUNK_POSTLF, /* This is mainly used to really mark that we're out of the game. Loading @@ -62,7 +62,22 @@ typedef enum { buffer! */ CHUNK_STOP, /* At this point optional trailer headers can be found, unless the next line is CRLF */ CHUNK_TRAILER, /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. Next char must be a LF */ CHUNK_TRAILER_CR, /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be signalled If this is an empty trailer CHUNKE_STOP will be signalled. Otherwise the trailer will be broadcasted via Curl_client_write() and the next state will be CHUNK_TRAILER */ CHUNK_TRAILER_POSTCR, CHUNK_LAST /* never use */ } ChunkyState; typedef enum { Loading @@ -74,6 +89,7 @@ typedef enum { CHUNKE_WRITE_ERROR, CHUNKE_STATE_ERROR, CHUNKE_BAD_ENCODING, CHUNKE_OUT_OF_MEMORY, CHUNKE_LAST } CHUNKcode; Loading lib/transfer.c +15 −0 Original line number Diff line number Diff line Loading @@ -833,6 +833,20 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* init our chunky engine */ Curl_httpchunk_init(conn); } else if (checkprefix("Trailer:", k->p) || checkprefix("Trailers:", k->p)) { /* * This test helps Curl_httpchunk_read() to determine to look * for well formed trailers after the zero chunksize record. In * this case a CRLF is required after the zero chunksize record * when no trailers are sent, or after the last trailer record. * * It seems both Trailer: and Trailers: occur in the wild. */ conn->bits.trailerHdrPresent = TRUE; } else if (checkprefix("Content-Encoding:", k->p) && data->set.encoding) { /* Loading Loading @@ -1074,6 +1088,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, * the name says read, this function both reads and writes away * the data. The returned 'nread' holds the number of actual * data it wrote to the client. */ CHUNKcode res = Curl_httpchunk_read(conn, k->str, nread, &nread); Loading Loading
CHANGES +6 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,12 @@ Changelog Daniel (12 July 2005) - Adrian Schuur added trailer support in the chunked encoding stream. The trailer is then sent to the normal header callback/stream. I wrote up test case 266 to verify the basic functionality. Do note that test case 34 contains a flawed chunked encoding stream that still works the same. Daniel (5 July 2005) - Gisle Vanem came up with a nice little work-around for bug #1230118. It seems the Windows (MSVC) libc time functions may return data one hour off if Loading
RELEASE-NOTES +4 −2 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ Curl and libcurl 7.14.1 This release includes the following changes: o trailer support for chunked encoded data streams o -x/CURL_PROXY strings may now contain user+password o --trace-time now outputs the full microsecond, all 6 digits Loading Loading @@ -41,6 +42,7 @@ This release would not have looked like this without help, code, reports and advice from friends like these: John McGowan, Georg Wicherski, Andres Garcia, Eric Cooper, Todd Kulesza, Tupone Alfredo, Gisle Vanem, David Shaw, Andrew Bushnell, Dan Fandrich Tupone Alfredo, Gisle Vanem, David Shaw, Andrew Bushnell, Dan Fandrich, Adrian Schuur Thanks! (and sorry if I forgot to mention someone)
lib/http_chunks.c +69 −4 Original line number Diff line number Diff line Loading @@ -153,12 +153,19 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, if(*datap == '\n') { /* we're now expecting data to come, unless size was zero! */ if(0 == ch->datasize) { ch->state = CHUNK_STOP; /* stop reading! */ if (conn->bits.trailerHdrPresent!=TRUE) { /* No Trailer: header found - revert to original Curl processing */ ch->state = CHUNK_STOP; if (1 == length) { /* This was the final byte, return right now */ /* This is the final byte, return right now */ return CHUNKE_STOP; } } else { ch->state = CHUNK_TRAILER; /* attempt to read trailers */ conn->trlPos=0; } } else ch->state = CHUNK_DATA; } Loading Loading @@ -250,6 +257,64 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, return CHUNKE_BAD_CHUNK; break; case CHUNK_TRAILER: /* conn->trailer is assumed to be freed in url.c on a connection basis */ if (conn->trlPos >= conn->trlMax) { char *ptr; if(conn->trlMax) { conn->trlMax *= 2; ptr = (char*)realloc(conn->trailer,conn->trlMax); } else { conn->trlMax=128; ptr = (char*)malloc(conn->trlMax); } if(!ptr) return CHUNKE_OUT_OF_MEMORY; conn->trailer = ptr; } conn->trailer[conn->trlPos++]=*datap; if(*datap == '\r') ch->state = CHUNK_TRAILER_CR; else { datap++; length--; } break; case CHUNK_TRAILER_CR: if(*datap == '\r') { ch->state = CHUNK_TRAILER_POSTCR; datap++; length--; } else return CHUNKE_BAD_CHUNK; break; case CHUNK_TRAILER_POSTCR: if (*datap == '\n') { conn->trailer[conn->trlPos++]='\n'; conn->trailer[conn->trlPos]=0; if (conn->trlPos==2) { ch->state = CHUNK_STOP; return CHUNKE_STOP; } else { Curl_client_write(conn->data, CLIENTWRITE_HEADER, conn->trailer, conn->trlPos); } ch->state = CHUNK_TRAILER; conn->trlPos=0; datap++; length--; } else return CHUNKE_BAD_CHUNK; break; case CHUNK_STOP: /* If we arrive here, there is data left in the end of the buffer even if there's no more chunks to read */ Loading
lib/http_chunks.h +18 −2 Original line number Diff line number Diff line Loading @@ -52,8 +52,8 @@ typedef enum { /* POSTCR should get a CR and nothing else, then move to POSTLF */ CHUNK_POSTCR, /* POSTLF should get a LF and nothing else, then move back to HEX as the CRLF combination marks the end of a chunk */ /* POSTLF should get a LF and nothing else, then move back to HEX as the CRLF combination marks the end of a chunk */ CHUNK_POSTLF, /* This is mainly used to really mark that we're out of the game. Loading @@ -62,7 +62,22 @@ typedef enum { buffer! */ CHUNK_STOP, /* At this point optional trailer headers can be found, unless the next line is CRLF */ CHUNK_TRAILER, /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. Next char must be a LF */ CHUNK_TRAILER_CR, /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be signalled If this is an empty trailer CHUNKE_STOP will be signalled. Otherwise the trailer will be broadcasted via Curl_client_write() and the next state will be CHUNK_TRAILER */ CHUNK_TRAILER_POSTCR, CHUNK_LAST /* never use */ } ChunkyState; typedef enum { Loading @@ -74,6 +89,7 @@ typedef enum { CHUNKE_WRITE_ERROR, CHUNKE_STATE_ERROR, CHUNKE_BAD_ENCODING, CHUNKE_OUT_OF_MEMORY, CHUNKE_LAST } CHUNKcode; Loading
lib/transfer.c +15 −0 Original line number Diff line number Diff line Loading @@ -833,6 +833,20 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* init our chunky engine */ Curl_httpchunk_init(conn); } else if (checkprefix("Trailer:", k->p) || checkprefix("Trailers:", k->p)) { /* * This test helps Curl_httpchunk_read() to determine to look * for well formed trailers after the zero chunksize record. In * this case a CRLF is required after the zero chunksize record * when no trailers are sent, or after the last trailer record. * * It seems both Trailer: and Trailers: occur in the wild. */ conn->bits.trailerHdrPresent = TRUE; } else if (checkprefix("Content-Encoding:", k->p) && data->set.encoding) { /* Loading Loading @@ -1074,6 +1088,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, * the name says read, this function both reads and writes away * the data. The returned 'nread' holds the number of actual * data it wrote to the client. */ CHUNKcode res = Curl_httpchunk_read(conn, k->str, nread, &nread); Loading