]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
trailers: switch h1-trailer logic to use dynbuf
authorDaniel Stenberg <daniel@haxx.se>
Fri, 5 Jun 2020 12:04:22 +0000 (14:04 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 5 Jun 2020 15:57:24 +0000 (17:57 +0200)
In the continued effort to remove "manual" realloc schemes.

Closes #5524

lib/dynbuf.h
lib/http_chunks.c
lib/url.c
lib/urldata.h

index e21294115629aa4f7131df46c5dd1a18bed1cbaf..7809becfefe01cf1292da11dac460fee6bef4cf0 100644 (file)
@@ -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
index b6ffa41854ab2d87162db00f088d49163d04877f..767f806c81b593c6178115b37725ea25a20b94b3 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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--;
index 524d968c2f8c76a29ad19bb99f8f0792a4362682..27943a3f78a023c9b0221c30c29a6b226668bbab 100644 (file)
--- 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);
index d3cc5356ef4a4e8bac152d13f04449ee2115ab1a..1882914e0d08315c608e16254641b66b03b53ff0 100644 (file)
@@ -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;