summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/transfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/transfer.c')
-rw-r--r--Utilities/cmcurl/lib/transfer.c130
1 files changed, 68 insertions, 62 deletions
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index 22704fa..315da87 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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
@@ -73,13 +73,13 @@
#include "select.h"
#include "multiif.h"
#include "connect.h"
-#include "non-ascii.h"
#include "http2.h"
#include "mime.h"
#include "strcase.h"
#include "urlapi-int.h"
#include "hsts.h"
#include "setopt.h"
+#include "headers.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -95,10 +95,10 @@
* Returns a pointer to the first matching header or NULL if none matched.
*/
char *Curl_checkheaders(const struct Curl_easy *data,
- const char *thisheader)
+ const char *thisheader,
+ const size_t thislen)
{
struct curl_slist *head;
- size_t thislen = strlen(thisheader);
DEBUGASSERT(thislen);
DEBUGASSERT(thisheader[thislen-1] != ':');
@@ -165,20 +165,6 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
curl_read_callback readfunc = NULL;
void *extra_data = NULL;
-#ifdef CURL_DOES_CONVERSIONS
- bool sending_http_headers = FALSE;
- struct connectdata *conn = data->conn;
-
- if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
- const struct HTTP *http = data->req.p.http;
-
- if(http->sending == HTTPSEND_REQUEST)
- /* We're sending the HTTP request headers, not the data.
- Remember that so we don't re-translate them into garbage. */
- sending_http_headers = TRUE;
- }
-#endif
-
#ifndef CURL_DISABLE_HTTP
if(data->state.trailers_state == TRAILERS_INITIALIZED) {
struct curl_slist *trailers = NULL;
@@ -260,7 +246,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
/* protocols that work without network cannot be paused. This is
actually only FILE:// just now, and it can't pause since the transfer
isn't done using the "normal" procedure. */
- failf(data, "Read callback asked for PAUSE when not supported!");
+ failf(data, "Read callback asked for PAUSE when not supported");
return CURLE_READ_ERROR;
}
@@ -347,26 +333,6 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
}
}
-#ifdef CURL_DOES_CONVERSIONS
- {
- CURLcode result;
- size_t length;
- if(data->state.prefer_ascii)
- /* translate the protocol and data */
- length = nread;
- else
- /* just translate the protocol portion */
- length = hexlen;
- if(length) {
- result = Curl_convert_to_network(data, data->req.upload_fromhere,
- length);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(result)
- return result;
- }
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
#ifndef CURL_DISABLE_HTTP
if(data->state.trailers_state == TRAILERS_SENDING &&
!trailers_left(data)) {
@@ -391,15 +357,6 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
if(added_crlf)
nread += strlen(endofline_network); /* for the added end of line */
}
-#ifdef CURL_DOES_CONVERSIONS
- else if((data->state.prefer_ascii) && (!sending_http_headers)) {
- CURLcode result;
- result = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(result)
- return result;
- }
-#endif /* CURL_DOES_CONVERSIONS */
*nreadp = nread;
@@ -503,7 +460,7 @@ static int data_pending(const struct Curl_easy *data)
/* in the case of libssh2, we can never be really sure that we have emptied
its internal buffers so we MUST always try until we get EAGAIN back */
return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
-#if defined(USE_NGHTTP2)
+#ifdef USE_NGHTTP2
/* For HTTP/2, we may read up everything including response body
with header fields in Curl_http_readwrite_headers. If no
content-length is provided, curl waits for the connection
@@ -586,15 +543,14 @@ static CURLcode readwrite_data(struct Curl_easy *data,
if(
#ifdef USE_NGHTTP2
- /* For HTTP/2, read data without caring about the content
- length. This is safe because body in HTTP/2 is always
- segmented thanks to its framing layer. Meanwhile, we have to
- call Curl_read to ensure that http2_handle_stream_close is
- called when we read all incoming bytes for a particular
- stream. */
- !is_http2 &&
+ /* For HTTP/2, read data without caring about the content length. This
+ is safe because body in HTTP/2 is always segmented thanks to its
+ framing layer. Meanwhile, we have to call Curl_read to ensure that
+ http2_handle_stream_close is called when we read all incoming bytes
+ for a particular stream. */
+ !is_http2 &&
#endif
- k->size != -1 && !k->header) {
+ k->size != -1 && !k->header) {
/* make sure we don't read too much */
curl_off_t totalleft = k->size - k->bytecount;
if(totalleft < (curl_off_t)bytestoread)
@@ -615,7 +571,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
else {
/* read nothing but since we wanted nothing we consider this an OK
situation to proceed from */
- DEBUGF(infof(data, "readwrite_data: we're done!"));
+ DEBUGF(infof(data, "readwrite_data: we're done"));
nread = 0;
}
@@ -1039,7 +995,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
if(!data->state.scratch) {
data->state.scratch = malloc(2 * data->set.upload_buffer_size);
if(!data->state.scratch) {
- failf(data, "Failed to alloc scratch buffer!");
+ failf(data, "Failed to alloc scratch buffer");
return CURLE_OUT_OF_MEMORY;
}
@@ -1404,7 +1360,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
if(!data->state.url && !data->set.uh) {
/* we can't do anything without URL */
- failf(data, "No URL set!");
+ failf(data, "No URL set");
return CURLE_URL_MALFORMAT;
}
@@ -1421,7 +1377,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
uc = curl_url_get(data->set.uh,
CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
if(uc) {
- failf(data, "No URL set!");
+ failf(data, "No URL set");
return CURLE_URL_MALFORMAT;
}
}
@@ -1533,6 +1489,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
data->set.str[STRING_PROXYPASSWORD]);
data->req.headerbytecount = 0;
+ Curl_headers_cleanup(data);
return result;
}
@@ -1577,6 +1534,8 @@ CURLcode Curl_follow(struct Curl_easy *data,
DEBUGASSERT(type != FOLLOW_NONE);
+ if(type != FOLLOW_FAKE)
+ data->state.requests++; /* count all real follows */
if(type == FOLLOW_REDIR) {
if((data->set.maxredirs != -1) &&
(data->state.followlocation >= data->set.maxredirs)) {
@@ -1652,10 +1611,57 @@ CURLcode Curl_follow(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
else {
-
uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
if(uc)
return Curl_uc_to_curlcode(uc);
+
+ /* Clear auth if this redirects to a different port number or protocol,
+ unless permitted */
+ if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) {
+ char *portnum;
+ int port;
+ bool clear = FALSE;
+
+ if(data->set.use_port && data->state.allow_port)
+ /* a custom port is used */
+ port = (int)data->set.use_port;
+ else {
+ uc = curl_url_get(data->state.uh, CURLUPART_PORT, &portnum,
+ CURLU_DEFAULT_PORT);
+ if(uc) {
+ free(newurl);
+ return Curl_uc_to_curlcode(uc);
+ }
+ port = atoi(portnum);
+ free(portnum);
+ }
+ if(port != data->info.conn_remote_port) {
+ infof(data, "Clear auth, redirects to port from %u to %u",
+ data->info.conn_remote_port, port);
+ clear = TRUE;
+ }
+ else {
+ char *scheme;
+ const struct Curl_handler *p;
+ uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
+ if(uc) {
+ free(newurl);
+ return Curl_uc_to_curlcode(uc);
+ }
+
+ p = Curl_builtin_scheme(scheme);
+ if(p && (p->protocol != data->info.conn_protocol)) {
+ infof(data, "Clear auth, redirects scheme from %s to %s",
+ data->info.conn_scheme, scheme);
+ clear = TRUE;
+ }
+ free(scheme);
+ }
+ if(clear) {
+ Curl_safefree(data->state.aptr.user);
+ Curl_safefree(data->state.aptr.passwd);
+ }
+ }
}
if(type == FOLLOW_FAKE) {