From d957ed4941d7f90eecc294490adee8055ab251f3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Jun 2020 14:04:22 +0200 Subject: trailers: switch h1-trailer logic to use dynbuf In the continued effort to remove "manual" realloc schemes. Closes #5524 --- lib/dynbuf.h | 1 + lib/http_chunks.c | 49 +++++++++++++++++-------------------------------- lib/url.c | 2 +- lib/urldata.h | 6 ++---- 4 files changed, 21 insertions(+), 37 deletions(-) diff --git a/lib/dynbuf.h b/lib/dynbuf.h index e21294115..7809becfe 100644 --- a/lib/dynbuf.h +++ b/lib/dynbuf.h @@ -59,4 +59,5 @@ size_t Curl_dyn_len(const struct dynbuf *s); #define DYN_TRAILERS (64*1024) #define DYN_PROXY_CONNECT_HEADERS 16384 #define DYN_QLOG_NAME 1024 +#define DYN_H1_TRAILER DYN_H2_TRAILER #endif diff --git a/lib/http_chunks.c b/lib/http_chunks.c index b6ffa4185..767f806c8 100644 --- a/lib/http_chunks.c +++ b/lib/http_chunks.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,7 +26,7 @@ #include "urldata.h" /* it includes http_chunks.h */ #include "sendf.h" /* for the client write stuff */ - +#include "dynbuf.h" #include "content_encoding.h" #include "http.h" #include "non-ascii.h" /* for Curl_convert_to_network prototype */ @@ -93,6 +93,7 @@ void Curl_httpchunk_init(struct connectdata *conn) chunk->hexindex = 0; /* start at 0 */ chunk->dataleft = 0; /* no data left yet! */ chunk->state = CHUNK_HEX; /* we get hex first! */ + Curl_dyn_init(&conn->trailer, DYN_H1_TRAILER); } /* @@ -177,7 +178,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, /* we're now expecting data to come, unless size was zero! */ if(0 == ch->datasize) { ch->state = CHUNK_TRAILER; /* now check for trailers */ - conn->trlPos = 0; } else ch->state = CHUNK_DATA; @@ -229,32 +229,33 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, case CHUNK_TRAILER: if((*datap == 0x0d) || (*datap == 0x0a)) { + char *tr = Curl_dyn_ptr(&conn->trailer); /* this is the end of a trailer, but if the trailer was zero bytes there was no trailer and we move on */ - if(conn->trlPos) { - /* we allocate trailer with 3 bytes extra room to fit this */ - conn->trailer[conn->trlPos++] = 0x0d; - conn->trailer[conn->trlPos++] = 0x0a; - conn->trailer[conn->trlPos] = 0; + if(tr) { + size_t trlen; + result = Curl_dyn_add(&conn->trailer, (char *)"\x0d\x0a"); + if(result) + return CHUNKE_OUT_OF_MEMORY; + tr = Curl_dyn_ptr(&conn->trailer); + trlen = Curl_dyn_len(&conn->trailer); /* Convert to host encoding before calling Curl_client_write */ - result = Curl_convert_from_network(conn->data, conn->trailer, - conn->trlPos); + result = Curl_convert_from_network(conn->data, tr, trlen); if(result) /* Curl_convert_from_network calls failf if unsuccessful */ /* Treat it as a bad chunk */ return CHUNKE_BAD_CHUNK; if(!data->set.http_te_skip) { - result = Curl_client_write(conn, CLIENTWRITE_HEADER, - conn->trailer, conn->trlPos); + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tr, trlen); if(result) { *extrap = result; return CHUNKE_PASSTHRU_ERROR; } } - conn->trlPos = 0; + Curl_dyn_reset(&conn->trailer); ch->state = CHUNK_TRAILER_CR; if(*datap == 0x0a) /* already on the LF */ @@ -267,25 +268,9 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, } } else { - /* conn->trailer is assumed to be freed in url.c on a - connection basis */ - if(conn->trlPos >= conn->trlMax) { - /* we always allocate three extra bytes, just because when the full - header has been received we append CRLF\0 */ - char *ptr; - if(conn->trlMax) { - conn->trlMax *= 2; - ptr = realloc(conn->trailer, conn->trlMax + 3); - } - else { - conn->trlMax = 128; - ptr = malloc(conn->trlMax + 3); - } - if(!ptr) - return CHUNKE_OUT_OF_MEMORY; - conn->trailer = ptr; - } - conn->trailer[conn->trlPos++]=*datap; + result = Curl_dyn_addn(&conn->trailer, datap, 1); + if(result) + return CHUNKE_OUT_OF_MEMORY; } datap++; length--; diff --git a/lib/url.c b/lib/url.c index 524d968c2..27943a3f7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -733,7 +733,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->allocptr.rtsp_transport); - Curl_safefree(conn->trailer); + Curl_dyn_free(&conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */ Curl_safefree(conn->hostname_resolve); diff --git a/lib/urldata.h b/lib/urldata.h index d3cc5356e..1882914e0 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1064,10 +1064,8 @@ struct connectdata { /* data used for the asynch name resolve callback */ struct Curl_async async; - /* These three are used for chunked-encoding trailer support */ - char *trailer; /* allocated buffer to store trailer in */ - int trlMax; /* allocated buffer size */ - int trlPos; /* index of where to store data */ + /* for chunked-encoded trailer */ + struct dynbuf trailer; union { struct ftp_conn ftpc; -- cgit v1.2.3