summaryrefslogtreecommitdiff
path: root/lib/http_chunks.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2005-07-12 18:15:34 +0000
committerDaniel Stenberg <daniel@haxx.se>2005-07-12 18:15:34 +0000
commit465e19dbe9603bacba53bd73a607d5fbb37c08a4 (patch)
tree8219b5bd5b34befa4c71e3f9e39bd05f1fbf911d /lib/http_chunks.c
parent86660c73e5d27e8dcd689f7dd10e003299d1d066 (diff)
downloadcurl-465e19dbe9603bacba53bd73a607d5fbb37c08a4.tar.gz
Adrian Schuur added trailer support in the chunked encoding stream. The
trailer is then sent to the normal header callback/stream.
Diffstat (limited to 'lib/http_chunks.c')
-rw-r--r--lib/http_chunks.c73
1 files changed, 69 insertions, 4 deletions
diff --git a/lib/http_chunks.c b/lib/http_chunks.c
index f333f9559..63e136cb7 100644
--- a/lib/http_chunks.c
+++ b/lib/http_chunks.c
@@ -153,10 +153,17 @@ 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(1 == length) {
- /* This was the final byte, return right now */
- return CHUNKE_STOP;
+ if (conn->bits.trailerHdrPresent!=TRUE) {
+ /* No Trailer: header found - revert to original Curl processing */
+ ch->state = CHUNK_STOP;
+ if (1 == length) {
+ /* This is the final byte, return right now */
+ return CHUNKE_STOP;
+ }
+ }
+ else {
+ ch->state = CHUNK_TRAILER; /* attempt to read trailers */
+ conn->trlPos=0;
}
}
else
@@ -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 */