Unverified Commit 55dbcb06 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

http: made Curl_add_buffer functions take a pointer-pointer

... so that they can clear the original pointer on failure, which makes
the error-paths and their cleanups easier.

Closes #2992
parent 130c53b6
Loading
Loading
Loading
Loading
+60 −52
Original line number Diff line number Diff line
@@ -1094,11 +1094,13 @@ Curl_send_buffer *Curl_add_buffer_init(void)
/*
 * Curl_add_buffer_free() frees all associated resources.
 */
void Curl_add_buffer_free(Curl_send_buffer *buff)
void Curl_add_buffer_free(Curl_send_buffer **inp)
{
  if(buff) /* deal with NULL input */
    free(buff->buffer);
  free(buff);
  Curl_send_buffer *in = *inp;
  if(in) /* deal with NULL input */
    free(in->buffer);
  free(in);
  *inp = NULL;
}

/*
@@ -1107,7 +1109,7 @@ void Curl_add_buffer_free(Curl_send_buffer *buff)
 *
 * Returns CURLcode
 */
CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
                              struct connectdata *conn,

                               /* add the number of sent bytes to this
@@ -1128,6 +1130,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
  size_t sendsize;
  curl_socket_t sockfd;
  size_t headersize;
  Curl_send_buffer *in = *inp;

  DEBUGASSERT(socketindex <= SECONDARYSOCKET);

@@ -1148,7 +1151,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
  /* Curl_convert_to_network calls failf if unsuccessful */
  if(result) {
    /* conversion failed, free memory and return to the caller */
    Curl_add_buffer_free(in);
    Curl_add_buffer_free(inp);
    return result;
  }

@@ -1172,7 +1175,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
    result = Curl_get_upload_buffer(data);
    if(result) {
      /* malloc failed, free memory and return to the caller */
      Curl_add_buffer_free(in);
      Curl_add_buffer_free(&in);
      return result;
    }
    memcpy(data->state.ulbuf, ptr, sendsize);
@@ -1256,7 +1259,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
      Curl_pipeline_leave_write(conn);
    }
  }
  Curl_add_buffer_free(in);
  Curl_add_buffer_free(&in);

  return result;
}
@@ -1265,31 +1268,35 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
/*
 * add_bufferf() add the formatted input to the buffer.
 */
CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...)
{
  char *s;
  va_list ap;
  Curl_send_buffer *in = *inp;
  va_start(ap, fmt);
  s = vaprintf(fmt, ap); /* this allocs a new string to append */
  va_end(ap);

  if(s) {
    CURLcode result = Curl_add_buffer(in, s, strlen(s));
    CURLcode result = Curl_add_buffer(inp, s, strlen(s));
    free(s);
    return result;
  }
  /* If we failed, we cleanup the whole buffer and return error */
  free(in->buffer);
  free(in);
  *inp = NULL;
  return CURLE_OUT_OF_MEMORY;
}

/*
 * add_buffer() appends a memory chunk to the existing buffer
 * Curl_add_buffer() appends a memory chunk to the existing buffer
 */
CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
                         size_t size)
{
  char *new_rb;
  Curl_send_buffer *in = *inp;

  if(~size < in->size_used) {
    /* If resulting used size of send buffer would wrap size_t, cleanup
@@ -1297,6 +1304,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
       size will fit into a single allocatable memory chunk */
    Curl_safefree(in->buffer);
    free(in);
    *inp = NULL;
    return CURLE_OUT_OF_MEMORY;
  }

@@ -1323,6 +1331,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
    if(!new_rb) {
      /* If we failed, we cleanup the whole buffer and return error */
      free(in);
      *inp = NULL;
      return CURLE_OUT_OF_MEMORY;
    }

@@ -1484,11 +1493,11 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
  if(!req_buffer)
    return CURLE_OUT_OF_MEMORY;

  result = Curl_add_bufferf(req_buffer, proxy_header);
  result = Curl_add_bufferf(&req_buffer, proxy_header);
  if(result)
    return result;

  result = Curl_add_buffer_send(req_buffer,
  result = Curl_add_buffer_send(&req_buffer,
                                conn,
                                &conn->data->info.request_size,
                                0,
@@ -1561,8 +1570,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
    return CURLE_OK;

  if(http->send_buffer) {
    Curl_add_buffer_free(http->send_buffer);
    http->send_buffer = NULL; /* clear the pointer */
    Curl_add_buffer_free(&http->send_buffer);
  }

  Curl_http2_done(conn, premature);
@@ -1653,7 +1661,7 @@ static CURLcode expect100(struct Curl_easy *data,
        Curl_compareheader(ptr, "Expect:", "100-continue");
    }
    else {
      result = Curl_add_bufferf(req_buffer,
      result = Curl_add_bufferf(&req_buffer,
                                "Expect: 100-continue\r\n");
      if(!result)
        data->state.expect100header = TRUE;
@@ -1785,7 +1793,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
                   !strcasecompare(data->state.first_host, conn->host.name)))
            ;
          else {
            result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data);
            result = Curl_add_bufferf(&req_buffer, "%s\r\n", headers->data);
          }
          if(semicolonp)
            *semicolonp = ';'; /* put back the semicolon */
@@ -1854,7 +1862,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
           tm->tm_min,
           tm->tm_sec);

  result = Curl_add_buffer(req_buffer, datestr, strlen(datestr));
  result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr));

  return result;
}
@@ -2419,7 +2427,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)

  /* add the main request stuff */
  /* GET/HEAD/POST/PUT */
  result = Curl_add_bufferf(req_buffer, "%s ", request);
  result = Curl_add_bufferf(&req_buffer, "%s ", request);
  if(result)
    return result;

@@ -2428,16 +2436,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)

  /* url */
  if(paste_ftp_userpwd)
    result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
    result = Curl_add_bufferf(&req_buffer, "ftp://%s:%s@%s",
                              conn->user, conn->passwd,
                              ppath + sizeof("ftp://") - 1);
  else
    result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
    result = Curl_add_buffer(&req_buffer, ppath, strlen(ppath));
  if(result)
    return result;

  result =
    Curl_add_bufferf(req_buffer,
    Curl_add_bufferf(&req_buffer,
                     "%s" /* ftp typecode (;type=x) */
                     " HTTP/%s\r\n" /* HTTP version */
                     "%s" /* host */
@@ -2518,11 +2526,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
      while(co) {
        if(co->value) {
          if(0 == count) {
            result = Curl_add_bufferf(req_buffer, "Cookie: ");
            result = Curl_add_bufferf(&req_buffer, "Cookie: ");
            if(result)
              break;
          }
          result = Curl_add_bufferf(req_buffer,
          result = Curl_add_bufferf(&req_buffer,
                                    "%s%s=%s", count?"; ":"",
                                    co->name, co->value);
          if(result)
@@ -2535,15 +2543,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
    }
    if(addcookies && !result) {
      if(!count)
        result = Curl_add_bufferf(req_buffer, "Cookie: ");
        result = Curl_add_bufferf(&req_buffer, "Cookie: ");
      if(!result) {
        result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
        result = Curl_add_bufferf(&req_buffer, "%s%s", count?"; ":"",
                                  addcookies);
        count++;
      }
    }
    if(count && !result)
      result = Curl_add_buffer(req_buffer, "\r\n", 2);
      result = Curl_add_buffer(&req_buffer, "\r\n", 2);

    if(result)
      return result;
@@ -2577,7 +2585,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
    if((postsize != -1) && !data->req.upload_chunky &&
       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
      /* only add Content-Length if not uploading chunked */
      result = Curl_add_bufferf(req_buffer,
      result = Curl_add_bufferf(&req_buffer,
                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
                                "\r\n", postsize);
      if(result)
@@ -2590,7 +2598,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
        return result;
    }

    result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
    result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers */
    if(result)
      return result;

@@ -2598,7 +2606,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
    Curl_pgrsSetUploadSize(data, postsize);

    /* this sends the buffer and frees all the buffer resources */
    result = Curl_add_buffer_send(req_buffer, conn,
    result = Curl_add_buffer_send(&req_buffer, conn,
                                  &data->info.request_size, 0, FIRSTSOCKET);
    if(result)
      failf(data, "Failed sending PUT request");
@@ -2616,11 +2624,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
    /* This is form posting using mime data. */
    if(conn->bits.authneg) {
      /* nothing to post! */
      result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
      result = Curl_add_bufferf(&req_buffer, "Content-Length: 0\r\n\r\n");
      if(result)
        return result;

      result = Curl_add_buffer_send(req_buffer, conn,
      result = Curl_add_buffer_send(&req_buffer, conn,
                                    &data->info.request_size, 0, FIRSTSOCKET);
      if(result)
        failf(data, "Failed sending POST request");
@@ -2640,7 +2648,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
      /* we allow replacing this header if not during auth negotiation,
         although it isn't very wise to actually set your own */
      result = Curl_add_bufferf(req_buffer,
      result = Curl_add_bufferf(&req_buffer,
                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
                                "\r\n", postsize);
      if(result)
@@ -2652,7 +2660,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
      struct curl_slist *hdr;

      for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
        result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data);
        result = Curl_add_bufferf(&req_buffer, "%s\r\n", hdr->data);
        if(result)
          return result;
      }
@@ -2676,7 +2684,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
      data->state.expect100header = FALSE;

    /* make the request end in a true CRLF */
    result = Curl_add_buffer(req_buffer, "\r\n", 2);
    result = Curl_add_buffer(&req_buffer, "\r\n", 2);
    if(result)
      return result;

@@ -2689,7 +2697,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
    http->sending = HTTPSEND_BODY;

    /* this sends the buffer and frees all the buffer resources */
    result = Curl_add_buffer_send(req_buffer, conn,
    result = Curl_add_buffer_send(&req_buffer, conn,
                                  &data->info.request_size, 0, FIRSTSOCKET);
    if(result)
      failf(data, "Failed sending POST request");
@@ -2719,7 +2727,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
      /* we allow replacing this header if not during auth negotiation,
         although it isn't very wise to actually set your own */
      result = Curl_add_bufferf(req_buffer,
      result = Curl_add_bufferf(&req_buffer,
                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
                                "\r\n", postsize);
      if(result)
@@ -2727,7 +2735,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
    }

    if(!Curl_checkheaders(conn, "Content-Type")) {
      result = Curl_add_bufferf(req_buffer,
      result = Curl_add_bufferf(&req_buffer,
                                "Content-Type: application/"
                                "x-www-form-urlencoded\r\n");
      if(result)
@@ -2765,31 +2773,31 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
           is no magic limit but only set to prevent really huge POSTs to
           get the data duplicated with malloc() and family. */

        result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
        result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
        if(result)
          return result;

        if(!data->req.upload_chunky) {
          /* We're not sending it 'chunked', append it to the request
             already now to reduce the number if send() calls */
          result = Curl_add_buffer(req_buffer, data->set.postfields,
          result = Curl_add_buffer(&req_buffer, data->set.postfields,
                                   (size_t)postsize);
          included_body = postsize;
        }
        else {
          if(postsize) {
            /* Append the POST data chunky-style */
            result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
            result = Curl_add_bufferf(&req_buffer, "%x\r\n", (int)postsize);
            if(!result) {
              result = Curl_add_buffer(req_buffer, data->set.postfields,
              result = Curl_add_buffer(&req_buffer, data->set.postfields,
                                       (size_t)postsize);
              if(!result)
                result = Curl_add_buffer(req_buffer, "\r\n", 2);
                result = Curl_add_buffer(&req_buffer, "\r\n", 2);
              included_body = postsize + 2;
            }
          }
          if(!result)
            result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
            result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
          /* 0  CR  LF  CR  LF */
          included_body += 5;
        }
@@ -2811,20 +2819,20 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
        /* set the upload size to the progress meter */
        Curl_pgrsSetUploadSize(data, http->postsize);

        result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
        result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
        if(result)
          return result;
      }
    }
    else {
      result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
      result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
      if(result)
        return result;

      if(data->req.upload_chunky && conn->bits.authneg) {
        /* Chunky upload is selected and we're negotiating auth still, send
           end-of-data only */
        result = Curl_add_buffer(req_buffer,
        result = Curl_add_buffer(&req_buffer,
                                 "\x30\x0d\x0a\x0d\x0a", 5);
        /* 0  CR  LF  CR  LF */
        if(result)
@@ -2845,7 +2853,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
      }
    }
    /* issue the request */
    result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
    result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size,
                                  (size_t)included_body, FIRSTSOCKET);

    if(result)
@@ -2857,12 +2865,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
    break;

  default:
    result = Curl_add_buffer(req_buffer, "\r\n", 2);
    result = Curl_add_buffer(&req_buffer, "\r\n", 2);
    if(result)
      return result;

    /* issue the request */
    result = Curl_add_buffer_send(req_buffer, conn,
    result = Curl_add_buffer_send(&req_buffer, conn,
                                  &data->info.request_size, 0, FIRSTSOCKET);

    if(result)
+11 −7
Original line number Diff line number Diff line
@@ -58,10 +58,12 @@ struct Curl_send_buffer {
typedef struct Curl_send_buffer Curl_send_buffer;

Curl_send_buffer *Curl_add_buffer_init(void);
void Curl_add_buffer_free(Curl_send_buffer *buff);
CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...);
CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size);
CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
void Curl_add_buffer_free(Curl_send_buffer **inp);
CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...)
  WARN_UNUSED_RESULT;
CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
                         size_t size) WARN_UNUSED_RESULT;
CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
                              struct connectdata *conn,
                              long *bytes_written,
                              size_t included_body_bytes,
@@ -154,9 +156,11 @@ struct HTTP {
    HTTPSEND_LAST     /* never use this */
  } sending;

  void *send_buffer; /* used if the request couldn't be sent in one chunk,
                        points to an allocated send_buffer struct */

#ifndef CURL_DISABLE_HTTP
  Curl_send_buffer *send_buffer; /* used if the request couldn't be sent in
                                    one chunk, points to an allocated
                                    send_buffer struct */
#endif
#ifdef USE_NGHTTP2
  /*********** for HTTP/2 we store stream-local data here *************/
  int32_t stream_id; /* stream we are interested in */
+49 −26
Original line number Diff line number Diff line
@@ -141,10 +141,8 @@ static int http2_getsock(struct connectdata *conn,
static void http2_stream_free(struct HTTP *http)
{
  if(http) {
    Curl_add_buffer_free(http->header_recvbuf);
    http->header_recvbuf = NULL; /* clear the pointer */
    Curl_add_buffer_free(http->trailer_recvbuf);
    http->trailer_recvbuf = NULL; /* clear the pointer */
    Curl_add_buffer_free(&http->header_recvbuf);
    Curl_add_buffer_free(&http->trailer_recvbuf);
    for(; http->push_headers_used > 0; --http->push_headers_used) {
      free(http->push_headers[http->push_headers_used - 1]);
    }
@@ -630,6 +628,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
  int rv;
  size_t left, ncopy;
  int32_t stream_id = frame->hd.stream_id;
  CURLcode result;

  if(!stream_id) {
    /* stream ID zero is for connection-oriented stuff */
@@ -705,7 +704,9 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
      stream->status_code = -1;
    }

    Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
    result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;

    left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
    ncopy = CURLMIN(stream->len, left);
@@ -929,6 +930,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
  struct Curl_easy *data_s;
  int32_t stream_id = frame->hd.stream_id;
  struct connectdata *conn = (struct connectdata *)userp;
  CURLcode result;
  (void)flags;

  DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
@@ -983,11 +985,21 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
    H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
                 value));

    Curl_add_buffer(stream->trailer_recvbuf, &n, sizeof(n));
    Curl_add_buffer(stream->trailer_recvbuf, name, namelen);
    Curl_add_buffer(stream->trailer_recvbuf, ": ", 2);
    Curl_add_buffer(stream->trailer_recvbuf, value, valuelen);
    Curl_add_buffer(stream->trailer_recvbuf, "\r\n\0", 3);
    result = Curl_add_buffer(&stream->trailer_recvbuf, &n, sizeof(n));
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    result = Curl_add_buffer(&stream->trailer_recvbuf, name, namelen);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    result = Curl_add_buffer(&stream->trailer_recvbuf, ": ", 2);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    result = Curl_add_buffer(&stream->trailer_recvbuf, value, valuelen);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    result = Curl_add_buffer(&stream->trailer_recvbuf, "\r\n\0", 3);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;

    return 0;
  }
@@ -1000,10 +1012,16 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
    stream->status_code = decode_status_code(value, valuelen);
    DEBUGASSERT(stream->status_code != -1);

    Curl_add_buffer(stream->header_recvbuf, "HTTP/2 ", 7);
    Curl_add_buffer(stream->header_recvbuf, value, valuelen);
    result = Curl_add_buffer(&stream->header_recvbuf, "HTTP/2 ", 7);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    /* the space character after the status code is mandatory */
    Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
    result = Curl_add_buffer(&stream->header_recvbuf, " \r\n", 3);
    if(result)
      return NGHTTP2_ERR_CALLBACK_FAILURE;
    /* if we receive data for another handle, wake that up */
    if(conn->data != data_s)
      Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
@@ -1016,10 +1034,18 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
  /* nghttp2 guarantees that namelen > 0, and :status was already
     received, and this is not pseudo-header field . */
  /* convert to a HTTP1-style header */
  Curl_add_buffer(stream->header_recvbuf, name, namelen);
  Curl_add_buffer(stream->header_recvbuf, ": ", 2);
  Curl_add_buffer(stream->header_recvbuf, value, valuelen);
  Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
  result = Curl_add_buffer(&stream->header_recvbuf, name, namelen);
  if(result)
    return NGHTTP2_ERR_CALLBACK_FAILURE;
  result = Curl_add_buffer(&stream->header_recvbuf, ": ", 2);
  if(result)
    return NGHTTP2_ERR_CALLBACK_FAILURE;
  result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
  if(result)
    return NGHTTP2_ERR_CALLBACK_FAILURE;
  result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
  if(result)
    return NGHTTP2_ERR_CALLBACK_FAILURE;
  /* if we receive data for another handle, wake that up */
  if(conn->data != data_s)
    Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
@@ -1123,10 +1149,8 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
    drained_transfer(data, httpc);

  if(http->header_recvbuf) {
    Curl_add_buffer_free(http->header_recvbuf);
    http->header_recvbuf = NULL; /* clear the pointer */
    Curl_add_buffer_free(http->trailer_recvbuf);
    http->trailer_recvbuf = NULL; /* clear the pointer */
    Curl_add_buffer_free(&http->header_recvbuf);
    Curl_add_buffer_free(&http->trailer_recvbuf);
    if(http->push_headers) {
      /* if they weren't used and then freed before */
      for(; http->push_headers_used > 0; --http->push_headers_used) {
@@ -1235,7 +1259,7 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
                                         httpc->local_settings_num);
  if(!binlen) {
    failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
    Curl_add_buffer_free(req);
    Curl_add_buffer_free(&req);
    return CURLE_FAILED_INIT;
  }
  conn->proto.httpc.binlen = binlen;
@@ -1243,11 +1267,11 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
  result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
                                 &base64, &blen);
  if(result) {
    Curl_add_buffer_free(req);
    Curl_add_buffer_free(&req);
    return result;
  }

  result = Curl_add_bufferf(req,
  result = Curl_add_bufferf(&req,
                            "Connection: Upgrade, HTTP2-Settings\r\n"
                            "Upgrade: %s\r\n"
                            "HTTP2-Settings: %s\r\n",
@@ -2108,8 +2132,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)

  result = Curl_http2_init(conn);
  if(result) {
    Curl_add_buffer_free(stream->header_recvbuf);
    stream->header_recvbuf = NULL;
    Curl_add_buffer_free(&stream->header_recvbuf);
    return result;
  }

+7 −7
Original line number Diff line number Diff line
@@ -222,7 +222,7 @@ static CURLcode CONNECT(struct connectdata *conn,

      host_port = aprintf("%s:%d", hostname, remote_port);
      if(!host_port) {
        Curl_add_buffer_free(req_buffer);
        Curl_add_buffer_free(&req_buffer);
        return CURLE_OUT_OF_MEMORY;
      }

@@ -247,7 +247,7 @@ static CURLcode CONNECT(struct connectdata *conn,
          aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
                  remote_port);
        if(!hostheader) {
          Curl_add_buffer_free(req_buffer);
          Curl_add_buffer_free(&req_buffer);
          return CURLE_OUT_OF_MEMORY;
        }

@@ -255,7 +255,7 @@ static CURLcode CONNECT(struct connectdata *conn,
          host = aprintf("Host: %s\r\n", hostheader);
          if(!host) {
            free(hostheader);
            Curl_add_buffer_free(req_buffer);
            Curl_add_buffer_free(&req_buffer);
            return CURLE_OUT_OF_MEMORY;
          }
        }
@@ -267,7 +267,7 @@ static CURLcode CONNECT(struct connectdata *conn,
          useragent = conn->allocptr.uagent;

        result =
          Curl_add_bufferf(req_buffer,
          Curl_add_bufferf(&req_buffer,
                           "CONNECT %s HTTP/%s\r\n"
                           "%s"  /* Host: */
                           "%s"  /* Proxy-Authorization */
@@ -290,13 +290,13 @@ static CURLcode CONNECT(struct connectdata *conn,

        if(!result)
          /* CRLF terminate the request */
          result = Curl_add_bufferf(req_buffer, "\r\n");
          result = Curl_add_bufferf(&req_buffer, "\r\n");

        if(!result) {
          /* Send the connect request to the proxy */
          /* BLOCKING */
          result =
            Curl_add_buffer_send(req_buffer, conn,
            Curl_add_buffer_send(&req_buffer, conn,
                                 &data->info.request_size, 0, sockindex);
        }
        req_buffer = NULL;
@@ -304,7 +304,7 @@ static CURLcode CONNECT(struct connectdata *conn,
          failf(data, "Failed sending CONNECT to proxy");
      }

      Curl_add_buffer_free(req_buffer);
      Curl_add_buffer_free(&req_buffer);
      if(result)
        return result;

+14 −13
Original line number Diff line number Diff line
@@ -462,7 +462,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
    return CURLE_OUT_OF_MEMORY;

  result =
    Curl_add_bufferf(req_buffer,
    Curl_add_bufferf(&req_buffer,
                     "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
                     "CSeq: %ld\r\n", /* CSeq */
                     p_request, p_stream_uri, rtsp->CSeq_sent);
@@ -474,7 +474,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
   * to make comparison easier
   */
  if(p_session_id) {
    result = Curl_add_bufferf(req_buffer, "Session: %s\r\n", p_session_id);
    result = Curl_add_bufferf(&req_buffer, "Session: %s\r\n", p_session_id);
    if(result)
      return result;
  }
@@ -482,7 +482,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
  /*
   * Shared HTTP-like options
   */
  result = Curl_add_bufferf(req_buffer,
  result = Curl_add_bufferf(&req_buffer,
                            "%s" /* transport */
                            "%s" /* accept */
                            "%s" /* accept-encoding */
@@ -541,7 +541,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
      /* As stated in the http comments, it is probably not wise to
       * actually set a custom Content-Length in the headers */
      if(!Curl_checkheaders(conn, "Content-Length")) {
        result = Curl_add_bufferf(req_buffer,
        result =
          Curl_add_bufferf(&req_buffer,
                           "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
                           (data->set.upload ? putsize : postsize));
        if(result)
@@ -551,7 +552,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
      if(rtspreq == RTSPREQ_SET_PARAMETER ||
         rtspreq == RTSPREQ_GET_PARAMETER) {
        if(!Curl_checkheaders(conn, "Content-Type")) {
          result = Curl_add_bufferf(req_buffer,
          result = Curl_add_bufferf(&req_buffer,
                                    "Content-Type: text/parameters\r\n");
          if(result)
            return result;
@@ -560,7 +561,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)

      if(rtspreq == RTSPREQ_ANNOUNCE) {
        if(!Curl_checkheaders(conn, "Content-Type")) {
          result = Curl_add_bufferf(req_buffer,
          result = Curl_add_bufferf(&req_buffer,
                                    "Content-Type: application/sdp\r\n");
          if(result)
            return result;
@@ -579,19 +580,19 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
  /* RTSP never allows chunked transfer */
  data->req.forbidchunk = TRUE;
  /* Finish the request buffer */
  result = Curl_add_buffer(req_buffer, "\r\n", 2);
  result = Curl_add_buffer(&req_buffer, "\r\n", 2);
  if(result)
    return result;

  if(postsize > 0) {
    result = Curl_add_buffer(req_buffer, data->set.postfields,
    result = Curl_add_buffer(&req_buffer, data->set.postfields,
                             (size_t)postsize);
    if(result)
      return result;
  }

  /* issue the request */
  result = Curl_add_buffer_send(req_buffer, conn,
  result = Curl_add_buffer_send(&req_buffer, conn,
                                &data->info.request_size, 0, FIRSTSOCKET);
  if(result) {
    failf(data, "Failed sending RTSP request");