diff options
Diffstat (limited to 'libs/libcurl/src/transfer.c')
-rw-r--r-- | libs/libcurl/src/transfer.c | 98 |
1 files changed, 50 insertions, 48 deletions
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index b9581d7adf..133a4783c6 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -128,12 +128,13 @@ static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems, void *raw) { struct Curl_easy *data = (struct Curl_easy *)raw; - Curl_send_buffer *trailers_buf = data->state.trailers_buf; - size_t bytes_left = trailers_buf->size_used-data->state.trailers_bytes_sent; + struct dynbuf *trailers_buf = &data->state.trailers_buf; + size_t bytes_left = Curl_dyn_len(trailers_buf) - + data->state.trailers_bytes_sent; size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left; if(to_copy) { memcpy(buffer, - &trailers_buf->buffer[data->state.trailers_bytes_sent], + Curl_dyn_ptr(trailers_buf) + data->state.trailers_bytes_sent, to_copy); data->state.trailers_bytes_sent += to_copy; } @@ -143,8 +144,8 @@ static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems, static size_t Curl_trailers_left(void *raw) { struct Curl_easy *data = (struct Curl_easy *)raw; - Curl_send_buffer *trailers_buf = data->state.trailers_buf; - return trailers_buf->size_used - data->state.trailers_bytes_sent; + struct dynbuf *trailers_buf = &data->state.trailers_buf; + return Curl_dyn_len(trailers_buf) - data->state.trailers_bytes_sent; } #endif @@ -186,11 +187,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, infof(data, "Moving trailers state machine from initialized to sending.\n"); data->state.trailers_state = TRAILERS_SENDING; - data->state.trailers_buf = Curl_add_buffer_init(); - if(!data->state.trailers_buf) { - failf(data, "Unable to allocate trailing headers buffer !"); - return CURLE_OUT_OF_MEMORY; - } + Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS); + data->state.trailers_bytes_sent = 0; Curl_set_in_callback(data, true); trailers_ret_code = data->set.trailer_callback(&trailers, @@ -206,7 +204,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, result = CURLE_ABORTED_BY_CALLBACK; } if(result) { - Curl_add_buffer_free(&data->state.trailers_buf); + Curl_dyn_free(&data->state.trailers_buf); curl_slist_free_all(trailers); return result; } @@ -369,7 +367,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, #ifndef CURL_DISABLE_HTTP if(data->state.trailers_state == TRAILERS_SENDING && !Curl_trailers_left(data)) { - Curl_add_buffer_free(&data->state.trailers_buf); + Curl_dyn_free(&data->state.trailers_buf); data->state.trailers_state = TRAILERS_DONE; data->set.trailer_data = NULL; data->set.trailer_callback = NULL; @@ -435,8 +433,8 @@ CURLcode Curl_readrewind(struct connectdata *conn) } if(data->set.postfields) ; /* do nothing */ - else if(data->set.httpreq == HTTPREQ_POST_MIME || - data->set.httpreq == HTTPREQ_POST_FORM) { + else if(data->state.httpreq == HTTPREQ_POST_MIME || + data->state.httpreq == HTTPREQ_POST_FORM) { if(Curl_mime_rewind(mimepart)) { failf(data, "Cannot rewind mime/post data"); return CURLE_SEND_FAIL_REWIND; @@ -560,6 +558,8 @@ static CURLcode readwrite_data(struct Curl_easy *data, size_t excess = 0; /* excess bytes read */ bool readmore = FALSE; /* used by RTP to signal for more data */ int maxloops = 100; + char *buf = data->state.buffer; + DEBUGASSERT(buf); *done = FALSE; *comeback = FALSE; @@ -594,7 +594,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, if(bytestoread) { /* receive data from the network! */ - result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread); + result = Curl_read(conn, conn->sockfd, buf, bytestoread, &nread); /* read would've blocked */ if(CURLE_AGAIN == result) @@ -621,9 +621,8 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* indicates data of zero size, i.e. empty file */ is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE; - /* NUL terminate, allowing string ops to be used */ if(0 < nread || is_empty_data) { - k->buf[nread] = 0; + buf[nread] = 0; } else { /* if we receive 0 or less here, either the http2 stream is closed or the @@ -640,7 +639,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* Default buffer to use when we write the buffer, it may be changed in the flow below before the actual storing is done. */ - k->str = k->buf; + k->str = buf; if(conn->handler->readwrite) { result = conn->handler->readwrite(data, conn, &nread, &readmore); @@ -689,7 +688,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* This is not an 'else if' since it may be a rest from the header parsing, where the beginning of the buffer is headers and the end is non-headers. */ - if(k->str && !k->header && (nread > 0 || is_empty_data)) { + if(!k->header && (nread > 0 || is_empty_data)) { if(data->set.opt_no_body) { /* data arrives although we want none, bail out */ @@ -720,7 +719,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, infof(data, "Ignoring the response-body\n"); } if(data->state.resume_from && !k->content_range && - (data->set.httpreq == HTTPREQ_GET) && + (data->state.httpreq == HTTPREQ_GET) && !k->ignorebody) { if(k->size == data->state.resume_from) { @@ -770,8 +769,9 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* pass data to the debug function before it gets "dechunked" */ if(data->set.verbose) { if(k->badheader) { - Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff, - (size_t)k->hbuflen); + Curl_debug(data, CURLINFO_DATA_IN, + Curl_dyn_ptr(&data->state.headerb), + Curl_dyn_len(&data->state.headerb)); if(k->badheader == HEADER_PARTHEADER) Curl_debug(data, CURLINFO_DATA_IN, k->str, (size_t)nread); @@ -822,9 +822,9 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* Account for body content stored in the header buffer */ if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) { - DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n", - k->hbuflen)); - k->bytecount += k->hbuflen; + size_t headlen = Curl_dyn_len(&data->state.headerb); + DEBUGF(infof(data, "Increasing bytecount by %zu\n", headlen)); + k->bytecount += headlen; } if((-1 != k->maxdownload) && @@ -839,6 +839,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, ", maxdownload = %" CURL_FORMAT_CURL_OFF_T ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n", excess, k->size, k->maxdownload, k->bytecount); + connclose(conn, "excess found in a read"); } nread = (ssize_t) (k->maxdownload - k->bytecount); @@ -858,15 +859,16 @@ static CURLcode readwrite_data(struct Curl_easy *data, if(k->badheader && !k->ignorebody) { /* we parsed a piece of data wrongly assuming it was a header and now we output it as body instead */ + size_t headlen = Curl_dyn_len(&data->state.headerb); /* Don't let excess data pollute body writes */ - if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload) + if(k->maxdownload == -1 || (curl_off_t)headlen <= k->maxdownload) result = Curl_client_write(conn, CLIENTWRITE_BODY, - data->state.headerbuff, - k->hbuflen); + Curl_dyn_ptr(&data->state.headerb), + headlen); else result = Curl_client_write(conn, CLIENTWRITE_BODY, - data->state.headerbuff, + Curl_dyn_ptr(&data->state.headerb), (size_t)k->maxdownload); if(result) @@ -904,10 +906,10 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* Parse the excess data */ k->str += nread; - if(&k->str[excess] > &k->buf[data->set.buffer_size]) { + if(&k->str[excess] > &buf[data->set.buffer_size]) { /* the excess amount was too excessive(!), make sure it doesn't read out of buffer */ - excess = &k->buf[data->set.buffer_size] - k->str; + excess = &buf[data->set.buffer_size] - k->str; } nread = (ssize_t)excess; @@ -1447,6 +1449,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) } } + data->state.httpreq = data->set.method; data->change.url = data->set.str[STRING_SET_URL]; /* Init the SSL session ID cache here. We do it here since we want to do it @@ -1466,12 +1469,11 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) data->state.authhost.want = data->set.httpauth; data->state.authproxy.want = data->set.proxyauth; Curl_safefree(data->info.wouldredirect); - data->info.wouldredirect = NULL; - if(data->set.httpreq == HTTPREQ_PUT) + if(data->state.httpreq == HTTPREQ_PUT) data->state.infilesize = data->set.filesize; - else if((data->set.httpreq != HTTPREQ_GET) && - (data->set.httpreq != HTTPREQ_HEAD)) { + else if((data->state.httpreq != HTTPREQ_GET) && + (data->state.httpreq != HTTPREQ_HEAD)) { data->state.infilesize = data->set.postfieldsize; if(data->set.postfields && (data->state.infilesize == -1)) data->state.infilesize = (curl_off_t)strlen(data->set.postfields); @@ -1682,12 +1684,12 @@ CURLcode Curl_follow(struct Curl_easy *data, * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and * can be overridden with CURLOPT_POSTREDIR. */ - if((data->set.httpreq == HTTPREQ_POST - || data->set.httpreq == HTTPREQ_POST_FORM - || data->set.httpreq == HTTPREQ_POST_MIME) + if((data->state.httpreq == HTTPREQ_POST + || data->state.httpreq == HTTPREQ_POST_FORM + || data->state.httpreq == HTTPREQ_POST_MIME) && !(data->set.keep_post & CURL_REDIR_POST_301)) { infof(data, "Switch from POST to GET\n"); - data->set.httpreq = HTTPREQ_GET; + data->state.httpreq = HTTPREQ_GET; } break; case 302: /* Found */ @@ -1707,12 +1709,12 @@ CURLcode Curl_follow(struct Curl_easy *data, * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and * can be overridden with CURLOPT_POSTREDIR. */ - if((data->set.httpreq == HTTPREQ_POST - || data->set.httpreq == HTTPREQ_POST_FORM - || data->set.httpreq == HTTPREQ_POST_MIME) + if((data->state.httpreq == HTTPREQ_POST + || data->state.httpreq == HTTPREQ_POST_FORM + || data->state.httpreq == HTTPREQ_POST_MIME) && !(data->set.keep_post & CURL_REDIR_POST_302)) { infof(data, "Switch from POST to GET\n"); - data->set.httpreq = HTTPREQ_GET; + data->state.httpreq = HTTPREQ_GET; } break; @@ -1722,12 +1724,12 @@ CURLcode Curl_follow(struct Curl_easy *data, * method is POST and the user specified to keep it as POST. * https://github.com/curl/curl/issues/5237#issuecomment-614641049 */ - if(data->set.httpreq != HTTPREQ_GET && - ((data->set.httpreq != HTTPREQ_POST && - data->set.httpreq != HTTPREQ_POST_FORM && - data->set.httpreq != HTTPREQ_POST_MIME) || + if(data->state.httpreq != HTTPREQ_GET && + ((data->state.httpreq != HTTPREQ_POST && + data->state.httpreq != HTTPREQ_POST_FORM && + data->state.httpreq != HTTPREQ_POST_MIME) || !(data->set.keep_post & CURL_REDIR_POST_303))) { - data->set.httpreq = HTTPREQ_GET; + data->state.httpreq = HTTPREQ_GET; data->set.upload = false; infof(data, "Switch to %s\n", data->set.opt_no_body?"HEAD":"GET"); |