diff options
Diffstat (limited to 'libs/libcurl/src/http.c')
| -rw-r--r-- | libs/libcurl/src/http.c | 641 |
1 files changed, 467 insertions, 174 deletions
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index ed8a3598f1..1d6248a042 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -47,10 +47,6 @@ #include <sys/param.h>
#endif
-#ifdef USE_HYPER
-#include <hyper.h>
-#endif
-
#include "urldata.h"
#include <curl/curl.h>
#include "transfer.h"
@@ -68,6 +64,7 @@ #include "http_negotiate.h"
#include "http_aws_sigv4.h"
#include "url.h"
+#include "urlapi-int.h"
#include "share.h"
#include "hostip.h"
#include "dynhds.h"
@@ -88,7 +85,6 @@ #include "altsvc.h"
#include "hsts.h"
#include "ws.h"
-#include "c-hyper.h"
#include "curl_ctype.h"
/* The last 3 #include files should be in this order */
@@ -104,6 +100,30 @@ static bool http_should_fail(struct Curl_easy *data, int httpcode); static bool http_exp100_is_waiting(struct Curl_easy *data);
static CURLcode http_exp100_add_reader(struct Curl_easy *data);
static void http_exp100_send_anyway(struct Curl_easy *data);
+static bool http_exp100_is_selected(struct Curl_easy *data);
+static void http_exp100_got100(struct Curl_easy *data);
+static CURLcode http_firstwrite(struct Curl_easy *data);
+static CURLcode http_header(struct Curl_easy *data,
+ const char *hd, size_t hdlen);
+static CURLcode http_host(struct Curl_easy *data, struct connectdata *conn);
+static CURLcode http_range(struct Curl_easy *data,
+ Curl_HttpReq httpreq);
+static CURLcode http_req_complete(struct Curl_easy *data,
+ struct dynbuf *r, int httpversion,
+ Curl_HttpReq httpreq);
+static CURLcode http_req_set_reader(struct Curl_easy *data,
+ Curl_HttpReq httpreq, int httpversion,
+ const char **tep);
+static CURLcode http_size(struct Curl_easy *data);
+static CURLcode http_statusline(struct Curl_easy *data,
+ struct connectdata *conn);
+static CURLcode http_target(struct Curl_easy *data, struct connectdata *conn,
+ struct dynbuf *req);
+static CURLcode http_useragent(struct Curl_easy *data);
+#ifdef HAVE_LIBZ
+static CURLcode http_transferencode(struct Curl_easy *data);
+#endif
+
/*
* HTTP handler interface.
@@ -126,6 +146,7 @@ const struct Curl_handler Curl_handler_http = { Curl_http_write_resp_hd, /* write_resp_hd */
ZERO_NULL, /* connection_check */
ZERO_NULL, /* attach connection */
+ Curl_http_follow, /* follow */
PORT_HTTP, /* defport */
CURLPROTO_HTTP, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -155,6 +176,7 @@ const struct Curl_handler Curl_handler_https = { Curl_http_write_resp_hd, /* write_resp_hd */
ZERO_NULL, /* connection_check */
ZERO_NULL, /* attach connection */
+ Curl_http_follow, /* follow */
PORT_HTTPS, /* defport */
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -473,7 +495,6 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, ongoing_auth ? " send, " : "");
/* We decided to abort the ongoing transfer */
streamclose(conn, "Mid-auth HTTP and much data left to send");
- /* FIXME: questionable manipulation here, can we do this differently? */
data->req.size = 0; /* do not download any more than 0 bytes */
}
return CURLE_OK;
@@ -510,8 +531,10 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) pickhost = pickoneauth(&data->state.authhost, authmask);
if(!pickhost)
data->state.authproblem = TRUE;
+ else
+ data->info.httpauthpicked = data->state.authhost.picked;
if(data->state.authhost.picked == CURLAUTH_NTLM &&
- conn->httpversion > 11) {
+ (data->req.httpversion_sent > 11)) {
infof(data, "Forcing HTTP/1.1 for NTLM");
connclose(conn, "Force HTTP/1.1 connection");
data->state.httpwant = CURL_HTTP_VERSION_1_1;
@@ -525,6 +548,9 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) authmask & ~CURLAUTH_BEARER);
if(!pickproxy)
data->state.authproblem = TRUE;
+ else
+ data->info.proxyauthpicked = data->state.authproxy.picked;
+
}
#endif
@@ -831,12 +857,12 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, struct connectdata *conn = data->conn;
#ifdef USE_SPNEGO
curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
- &conn->http_negotiate_state;
+ &conn->http_negotiate_state;
#endif
-#if defined(USE_SPNEGO) || \
- defined(USE_NTLM) || \
- !defined(CURL_DISABLE_DIGEST_AUTH) || \
- !defined(CURL_DISABLE_BASIC_AUTH) || \
+#if defined(USE_SPNEGO) || \
+ defined(USE_NTLM) || \
+ !defined(CURL_DISABLE_DIGEST_AUTH) || \
+ !defined(CURL_DISABLE_BASIC_AUTH) || \
!defined(CURL_DISABLE_BEARER_AUTH)
unsigned long *availp;
@@ -967,7 +993,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, authp->avail |= CURLAUTH_BEARER;
if(authp->picked == CURLAUTH_BEARER) {
/* We asked for Bearer authentication but got a 40X back
- anyway, which basically means our token is not valid. */
+ anyway, which basically means our token is not valid. */
authp->avail = CURLAUTH_NONE;
infof(data, "Authentication problem. Ignoring this.");
data->state.authproblem = TRUE;
@@ -1067,6 +1093,283 @@ static bool http_should_fail(struct Curl_easy *data, int httpcode) return data->state.authproblem;
}
+CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
+ followtype type)
+{
+ bool disallowport = FALSE;
+ bool reachedmax = FALSE;
+ char *follow_url = NULL;
+ CURLUcode uc;
+
+ 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)) {
+ reachedmax = TRUE;
+ type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected
+ to URL */
+ }
+ else {
+ data->state.followlocation++; /* count redirect-followings, including
+ auth reloads */
+
+ if(data->set.http_auto_referer) {
+ CURLU *u;
+ char *referer = NULL;
+
+ /* We are asked to automatically set the previous URL as the referer
+ when we get the next URL. We pick the ->url field, which may or may
+ not be 100% correct */
+
+ if(data->state.referer_alloc) {
+ Curl_safefree(data->state.referer);
+ data->state.referer_alloc = FALSE;
+ }
+
+ /* Make a copy of the URL without credentials and fragment */
+ u = curl_url();
+ if(!u)
+ return CURLE_OUT_OF_MEMORY;
+
+ uc = curl_url_set(u, CURLUPART_URL, data->state.url, 0);
+ if(!uc)
+ uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0);
+ if(!uc)
+ uc = curl_url_set(u, CURLUPART_USER, NULL, 0);
+ if(!uc)
+ uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0);
+ if(!uc)
+ uc = curl_url_get(u, CURLUPART_URL, &referer, 0);
+
+ curl_url_cleanup(u);
+
+ if(uc || !referer)
+ return CURLE_OUT_OF_MEMORY;
+
+ data->state.referer = referer;
+ data->state.referer_alloc = TRUE; /* yes, free this later */
+ }
+ }
+ }
+
+ if((type != FOLLOW_RETRY) &&
+ (data->req.httpcode != 401) && (data->req.httpcode != 407) &&
+ Curl_is_absolute_url(newurl, NULL, 0, FALSE)) {
+ /* If this is not redirect due to a 401 or 407 response and an absolute
+ URL: do not allow a custom port number */
+ disallowport = TRUE;
+ }
+
+ DEBUGASSERT(data->state.uh);
+ uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, (unsigned int)
+ ((type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME :
+ ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) |
+ CURLU_ALLOW_SPACE |
+ (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)));
+ if(uc) {
+ if(type != FOLLOW_FAKE) {
+ failf(data, "The redirect target URL could not be parsed: %s",
+ curl_url_strerror(uc));
+ return Curl_uc_to_curlcode(uc);
+ }
+
+ /* the URL could not be parsed for some reason, but since this is FAKE
+ mode, just duplicate the field as-is */
+ follow_url = strdup(newurl);
+ if(!follow_url)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else {
+ uc = curl_url_get(data->state.uh, CURLUPART_URL, &follow_url, 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(follow_url);
+ 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(follow_url);
+ return Curl_uc_to_curlcode(uc);
+ }
+
+ p = Curl_get_scheme_handler(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);
+ }
+ }
+ }
+ DEBUGASSERT(follow_url);
+
+ if(type == FOLLOW_FAKE) {
+ /* we are only figuring out the new URL if we would have followed locations
+ but now we are done so we can get out! */
+ data->info.wouldredirect = follow_url;
+
+ if(reachedmax) {
+ failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
+ return CURLE_TOO_MANY_REDIRECTS;
+ }
+ return CURLE_OK;
+ }
+
+ if(disallowport)
+ data->state.allow_port = FALSE;
+
+ if(data->state.url_alloc)
+ Curl_safefree(data->state.url);
+
+ data->state.url = follow_url;
+ data->state.url_alloc = TRUE;
+ Curl_req_soft_reset(&data->req, data);
+ infof(data, "Issue another request to this URL: '%s'", data->state.url);
+
+ /*
+ * We get here when the HTTP code is 300-399 (and 401). We need to perform
+ * differently based on exactly what return code there was.
+ *
+ * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
+ * an HTTP (proxy-) authentication scheme other than Basic.
+ */
+ switch(data->info.httpcode) {
+ /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
+ Authorization: XXXX header in the HTTP request code snippet */
+ /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
+ Proxy-Authorization: XXXX header in the HTTP request code snippet */
+ /* 300 - Multiple Choices */
+ /* 306 - Not used */
+ /* 307 - Temporary Redirect */
+ default: /* for all above (and the unknown ones) */
+ /* Some codes are explicitly mentioned since I have checked RFC2616 and
+ * they seem to be OK to POST to.
+ */
+ break;
+ case 301: /* Moved Permanently */
+ /* (quote from RFC7231, section 6.4.2)
+ *
+ * Note: For historical reasons, a user agent MAY change the request
+ * method from POST to GET for the subsequent request. If this
+ * behavior is undesired, the 307 (Temporary Redirect) status code
+ * can be used instead.
+ *
+ * ----
+ *
+ * Many webservers expect this, so these servers often answers to a POST
+ * request with an error page. To be sure that libcurl gets the page that
+ * most user agents would get, libcurl has to force GET.
+ *
+ * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and
+ * can be overridden with CURLOPT_POSTREDIR.
+ */
+ 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");
+ data->state.httpreq = HTTPREQ_GET;
+ Curl_creader_set_rewind(data, FALSE);
+ }
+ break;
+ case 302: /* Found */
+ /* (quote from RFC7231, section 6.4.3)
+ *
+ * Note: For historical reasons, a user agent MAY change the request
+ * method from POST to GET for the subsequent request. If this
+ * behavior is undesired, the 307 (Temporary Redirect) status code
+ * can be used instead.
+ *
+ * ----
+ *
+ * Many webservers expect this, so these servers often answers to a POST
+ * request with an error page. To be sure that libcurl gets the page that
+ * most user agents would get, libcurl has to force GET.
+ *
+ * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and
+ * can be overridden with CURLOPT_POSTREDIR.
+ */
+ 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");
+ data->state.httpreq = HTTPREQ_GET;
+ Curl_creader_set_rewind(data, FALSE);
+ }
+ break;
+
+ case 303: /* See Other */
+ /* 'See Other' location is not the resource but a substitute for the
+ * resource. In this case we switch the method to GET/HEAD, unless the
+ * method is POST and the user specified to keep it as POST.
+ * https://github.com/curl/curl/issues/5237#issuecomment-614641049
+ */
+ 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->state.httpreq = HTTPREQ_GET;
+ infof(data, "Switch to %s",
+ data->req.no_body ? "HEAD" : "GET");
+ }
+ break;
+ case 304: /* Not Modified */
+ /* 304 means we did a conditional request and it was "Not modified".
+ * We should not get any Location: header in this response!
+ */
+ break;
+ case 305: /* Use Proxy */
+ /* (quote from RFC2616, section 10.3.6):
+ * "The requested resource MUST be accessed through the proxy given
+ * by the Location field. The Location field gives the URI of the
+ * proxy. The recipient is expected to repeat this single request
+ * via the proxy. 305 responses MUST only be generated by origin
+ * servers."
+ */
+ break;
+ }
+ Curl_pgrsTime(data, TIMER_REDIRECT);
+ Curl_pgrsResetTransferSizes(data);
+
+ return CURLE_OK;
+}
+
/*
* Curl_compareheader()
*
@@ -1169,7 +1472,6 @@ CURLcode Curl_http_done(struct Curl_easy *data, data->state.authproxy.multipass = FALSE;
Curl_dyn_reset(&data->state.headerb);
- Curl_hyper_done(data);
if(status)
return status;
@@ -1193,52 +1495,55 @@ CURLcode Curl_http_done(struct Curl_easy *data, return CURLE_OK;
}
-/*
- * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
- * to avoid it include:
- *
- * - if the user specifically requested HTTP 1.0
- * - if the server we are connected to only supports 1.0
- * - if any server previously contacted to handle this request only supports
- * 1.0.
- */
-bool Curl_use_http_1_1plus(const struct Curl_easy *data,
- const struct connectdata *conn)
+/* Determine if we may use HTTP 1.1 for this request. */
+static bool http_may_use_1_1(const struct Curl_easy *data)
{
- if((data->state.httpversion == 10) || (conn->httpversion == 10))
+ const struct connectdata *conn = data->conn;
+ /* We have seen a previous response for *this* transfer with 1.0,
+ * on another connection or the same one. */
+ if(data->state.httpversion == 10)
+ return FALSE;
+ /* We have seen a previous response on *this* connection with 1.0. */
+ if(conn->httpversion_seen == 10)
return FALSE;
+ /* We want 1.0 and have seen no previous response on *this* connection
+ with a higher version (maybe no response at all yet). */
if((data->state.httpwant == CURL_HTTP_VERSION_1_0) &&
- (conn->httpversion <= 10))
+ (conn->httpversion_seen <= 10))
return FALSE;
- return ((data->state.httpwant == CURL_HTTP_VERSION_NONE) ||
- (data->state.httpwant >= CURL_HTTP_VERSION_1_1));
+ /* We want something newer than 1.0 or have no preferences. */
+ return (data->state.httpwant == CURL_HTTP_VERSION_NONE) ||
+ (data->state.httpwant >= CURL_HTTP_VERSION_1_1);
}
-#ifndef USE_HYPER
-static const char *get_http_string(const struct Curl_easy *data,
- const struct connectdata *conn)
+static unsigned char http_request_version(struct Curl_easy *data)
{
- if(Curl_conn_is_http3(data, conn, FIRSTSOCKET))
- return "3";
- if(Curl_conn_is_http2(data, conn, FIRSTSOCKET))
- return "2";
- if(Curl_use_http_1_1plus(data, conn))
- return "1.1";
-
- return "1.0";
+ unsigned char httpversion = Curl_conn_http_version(data);
+ if(!httpversion) {
+ /* No specific HTTP connection filter installed. */
+ httpversion = http_may_use_1_1(data) ? 11 : 10;
+ }
+ return httpversion;
+}
+
+static const char *get_http_string(int httpversion)
+{
+ switch(httpversion) {
+ case 30:
+ return "3";
+ case 20:
+ return "2";
+ case 11:
+ return "1.1";
+ default:
+ return "1.0";
+ }
}
-#endif
CURLcode Curl_add_custom_headers(struct Curl_easy *data,
- bool is_connect,
-#ifndef USE_HYPER
- struct dynbuf *req
-#else
- void *req
-#endif
- )
+ bool is_connect, int httpversion,
+ struct dynbuf *req)
{
- struct connectdata *conn = data->conn;
char *ptr;
struct curl_slist *h[2];
struct curl_slist *headers;
@@ -1251,7 +1556,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, if(is_connect)
proxy = HEADER_CONNECT;
else
- proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy ?
+ proxy = data->conn->bits.httpproxy && !data->conn->bits.tunnel_proxy ?
HEADER_PROXY : HEADER_SERVER;
switch(proxy) {
@@ -1303,9 +1608,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, /* copy the source */
semicolonp = strdup(headers->data);
if(!semicolonp) {
-#ifndef USE_HYPER
Curl_dyn_free(req);
-#endif
return CURLE_OUT_OF_MEMORY;
}
/* put a colon where the semicolon is */
@@ -1353,7 +1656,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, Connection: */
checkprefix("Connection:", compare))
;
- else if((conn->httpversion >= 20) &&
+ else if((httpversion >= 20) &&
checkprefix("Transfer-Encoding:", compare))
/* HTTP/2 does not support chunked requests */
;
@@ -1364,11 +1667,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, !Curl_auth_allowed_to_host(data))
;
else {
-#ifdef USE_HYPER
- result = Curl_hyper_header(data, req, compare);
-#else
result = Curl_dyn_addf(req, "%s\r\n", compare);
-#endif
}
if(semicolonp)
free(semicolonp);
@@ -1385,12 +1684,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, #ifndef CURL_DISABLE_PARSEDATE
CURLcode Curl_add_timecondition(struct Curl_easy *data,
-#ifndef USE_HYPER
- struct dynbuf *req
-#else
- void *req
-#endif
- )
+ struct dynbuf *req)
{
const struct tm *tm;
struct tm keeptime;
@@ -1453,12 +1747,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data, tm->tm_min,
tm->tm_sec);
-#ifndef USE_HYPER
result = Curl_dyn_add(req, datestr);
-#else
- result = Curl_hyper_header(data, req, datestr);
-#endif
-
return result;
}
#else
@@ -1512,7 +1801,7 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn, *reqp = httpreq;
}
-CURLcode Curl_http_useragent(struct Curl_easy *data)
+static CURLcode http_useragent(struct Curl_easy *data)
{
/* The User-Agent string might have been allocated in url.c already, because
it might have been used in the proxy connect, but if we have got a header
@@ -1526,7 +1815,7 @@ CURLcode Curl_http_useragent(struct Curl_easy *data) }
-CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
+static CURLcode http_host(struct Curl_easy *data, struct connectdata *conn)
{
const char *ptr;
struct dynamically_allocated_data *aptr = &data->state.aptr;
@@ -1616,9 +1905,9 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn) /*
* Append the request-target to the HTTP request
*/
-CURLcode Curl_http_target(struct Curl_easy *data,
- struct connectdata *conn,
- struct dynbuf *r)
+static CURLcode http_target(struct Curl_easy *data,
+ struct connectdata *conn,
+ struct dynbuf *r)
{
CURLcode result = CURLE_OK;
const char *path = data->state.up.path;
@@ -1684,7 +1973,7 @@ CURLcode Curl_http_target(struct Curl_easy *data, data->set.str[STRING_TARGET] : url);
free(url);
if(result)
- return (result);
+ return result;
if(strcasecompare("ftp", data->state.up.scheme)) {
if(data->set.proxy_transfer_mode) {
@@ -1898,9 +2187,9 @@ static CURLcode http_resume(struct Curl_easy *data, Curl_HttpReq httpreq) return CURLE_OK;
}
-CURLcode Curl_http_req_set_reader(struct Curl_easy *data,
- Curl_HttpReq httpreq,
- const char **tep)
+static CURLcode http_req_set_reader(struct Curl_easy *data,
+ Curl_HttpReq httpreq, int httpversion,
+ const char **tep)
{
CURLcode result = CURLE_OK;
const char *ptr;
@@ -1919,12 +2208,10 @@ CURLcode Curl_http_req_set_reader(struct Curl_easy *data, data->req.upload_chunky =
Curl_compareheader(ptr,
STRCONST("Transfer-Encoding:"), STRCONST("chunked"));
- if(data->req.upload_chunky &&
- Curl_use_http_1_1plus(data, data->conn) &&
- (data->conn->httpversion >= 20)) {
- infof(data, "suppressing chunked transfer encoding on connection "
- "using HTTP version 2 or higher");
- data->req.upload_chunky = FALSE;
+ if(data->req.upload_chunky && (httpversion >= 20)) {
+ infof(data, "suppressing chunked transfer encoding on connection "
+ "using HTTP version 2 or higher");
+ data->req.upload_chunky = FALSE;
}
}
else {
@@ -1932,10 +2219,10 @@ CURLcode Curl_http_req_set_reader(struct Curl_easy *data, if(req_clen < 0) {
/* indeterminate request content length */
- if(Curl_use_http_1_1plus(data, data->conn)) {
+ if(httpversion > 10) {
/* On HTTP/1.1, enable chunked, on HTTP/2 and later we do not
* need it */
- data->req.upload_chunky = (data->conn->httpversion < 20);
+ data->req.upload_chunky = (httpversion < 20);
}
else {
failf(data, "Chunky upload is not supported by HTTP 1.0");
@@ -1954,7 +2241,7 @@ CURLcode Curl_http_req_set_reader(struct Curl_easy *data, }
static CURLcode addexpect(struct Curl_easy *data, struct dynbuf *r,
- bool *announced_exp100)
+ int httpversion, bool *announced_exp100)
{
CURLcode result;
char *ptr;
@@ -1973,9 +2260,7 @@ static CURLcode addexpect(struct Curl_easy *data, struct dynbuf *r, *announced_exp100 =
Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
}
- else if(!data->state.disableexpect &&
- Curl_use_http_1_1plus(data, data->conn) &&
- (data->conn->httpversion < 20)) {
+ else if(!data->state.disableexpect && (httpversion == 11)) {
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
Expect: 100-continue to the headers which actually speeds up post
operations (as there is one packet coming back from the web server) */
@@ -1990,21 +2275,20 @@ static CURLcode addexpect(struct Curl_easy *data, struct dynbuf *r, return CURLE_OK;
}
-CURLcode Curl_http_req_complete(struct Curl_easy *data,
- struct dynbuf *r, Curl_HttpReq httpreq)
+static CURLcode http_req_complete(struct Curl_easy *data,
+ struct dynbuf *r, int httpversion,
+ Curl_HttpReq httpreq)
{
CURLcode result = CURLE_OK;
curl_off_t req_clen;
bool announced_exp100 = FALSE;
DEBUGASSERT(data->conn);
-#ifndef USE_HYPER
if(data->req.upload_chunky) {
result = Curl_httpchunk_add_reader(data);
if(result)
return result;
}
-#endif
/* Get the request body length that has been set up */
req_clen = Curl_creader_total_length(data);
@@ -2053,7 +2337,7 @@ CURLcode Curl_http_req_complete(struct Curl_easy *data, goto out;
}
}
- result = addexpect(data, r, &announced_exp100);
+ result = addexpect(data, r, httpversion, &announced_exp100);
if(result)
goto out;
break;
@@ -2079,9 +2363,9 @@ out: #if !defined(CURL_DISABLE_COOKIES)
-CURLcode Curl_http_cookies(struct Curl_easy *data,
- struct connectdata *conn,
- struct dynbuf *r)
+static CURLcode http_cookies(struct Curl_easy *data,
+ struct connectdata *conn,
+ struct dynbuf *r)
{
CURLcode result = CURLE_OK;
char *addcookies = NULL;
@@ -2155,10 +2439,12 @@ CURLcode Curl_http_cookies(struct Curl_easy *data, }
return result;
}
+#else
+#define http_cookies(a,b,c) CURLE_OK
#endif
-CURLcode Curl_http_range(struct Curl_easy *data,
- Curl_HttpReq httpreq)
+static CURLcode http_range(struct Curl_easy *data,
+ Curl_HttpReq httpreq)
{
if(data->state.use_range) {
/*
@@ -2190,7 +2476,7 @@ CURLcode Curl_http_range(struct Curl_easy *data, }
else if(data->state.resume_from) {
/* This is because "resume" was selected */
- /* TODO: not sure if we want to send this header during authentication
+ /* Not sure if we want to send this header during authentication
* negotiation, but test1084 checks for it. In which case we have a
* "null" client reader installed that gives an unexpected length. */
curl_off_t total_len = data->req.authneg ?
@@ -2214,7 +2500,7 @@ CURLcode Curl_http_range(struct Curl_easy *data, return CURLE_OK;
}
-CURLcode Curl_http_firstwrite(struct Curl_easy *data)
+static CURLcode http_firstwrite(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
struct SingleRequest *k = &data->req;
@@ -2277,7 +2563,7 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data) }
#ifdef HAVE_LIBZ
-CURLcode Curl_transferencode(struct Curl_easy *data)
+static CURLcode http_transferencode(struct Curl_easy *data)
{
if(!Curl_checkheaders(data, STRCONST("TE")) &&
data->set.http_transfer_encoding) {
@@ -2309,7 +2595,6 @@ CURLcode Curl_transferencode(struct Curl_easy *data) }
#endif
-#ifndef USE_HYPER
/*
* Curl_http() gets called from the generic multi_do() function when an HTTP
* request is to be performed. This creates and sends a properly constructed
@@ -2326,6 +2611,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) struct dynbuf req;
char *altused = NULL;
const char *p_accept; /* Accept: string */
+ unsigned char httpversion;
/* Always consider the DO phase done after this function call, even if there
may be parts of the request that are not yet sent, since we can deal with
@@ -2334,29 +2620,29 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) switch(conn->alpn) {
case CURL_HTTP_VERSION_3:
- DEBUGASSERT(Curl_conn_is_http3(data, conn, FIRSTSOCKET));
+ DEBUGASSERT(Curl_conn_http_version(data) == 30);
break;
case CURL_HTTP_VERSION_2:
#ifndef CURL_DISABLE_PROXY
- if(!Curl_conn_is_http2(data, conn, FIRSTSOCKET) &&
+ if((Curl_conn_http_version(data) != 20) &&
conn->bits.proxy && !conn->bits.tunnel_proxy
) {
- result = Curl_http2_switch(data, conn, FIRSTSOCKET);
+ result = Curl_http2_switch(data);
if(result)
goto fail;
}
else
#endif
- DEBUGASSERT(Curl_conn_is_http2(data, conn, FIRSTSOCKET));
+ DEBUGASSERT(Curl_conn_http_version(data) == 20);
break;
case CURL_HTTP_VERSION_1_1:
/* continue with HTTP/1.x when explicitly requested */
break;
default:
/* Check if user wants to use HTTP/2 with clear TCP */
- if(Curl_http2_may_switch(data, conn, FIRSTSOCKET)) {
+ if(Curl_http2_may_switch(data)) {
DEBUGF(infof(data, "HTTP/2 over clean TCP"));
- result = Curl_http2_switch(data, conn, FIRSTSOCKET);
+ result = Curl_http2_switch(data);
if(result)
goto fail;
}
@@ -2370,11 +2656,11 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(result)
goto fail;
- result = Curl_http_host(data, conn);
+ result = http_host(data, conn);
if(result)
goto fail;
- result = Curl_http_useragent(data);
+ result = http_useragent(data);
if(result)
goto fail;
@@ -2415,24 +2701,25 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) #ifdef HAVE_LIBZ
/* we only consider transfer-encoding magic if libz support is built-in */
- result = Curl_transferencode(data);
+ result = http_transferencode(data);
if(result)
goto fail;
#endif
- result = Curl_http_req_set_reader(data, httpreq, &te);
+ httpversion = http_request_version(data);
+ httpstring = get_http_string(httpversion);
+
+ result = http_req_set_reader(data, httpreq, httpversion, &te);
if(result)
goto fail;
p_accept = Curl_checkheaders(data,
STRCONST("Accept")) ? NULL : "Accept: */*\r\n";
- result = Curl_http_range(data, httpreq);
+ result = http_range(data, httpreq);
if(result)
goto fail;
- httpstring = get_http_string(data, conn);
-
/* initialize a dynamic send-buffer */
Curl_dyn_init(&req, DYN_HTTP_REQUEST);
@@ -2444,7 +2731,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) /* GET/HEAD/POST/PUT */
result = Curl_dyn_addf(&req, "%s ", request);
if(!result)
- result = Curl_http_target(data, conn, &req);
+ result = http_target(data, conn, &req);
if(result) {
Curl_dyn_free(&req);
goto fail;
@@ -2526,8 +2813,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) goto fail;
}
- if(!(conn->handler->flags&PROTOPT_SSL) &&
- conn->httpversion < 20 &&
+ if(!Curl_conn_is_ssl(conn, FIRSTSOCKET) && (httpversion < 20) &&
(data->state.httpwant == CURL_HTTP_VERSION_2)) {
/* append HTTP2 upgrade magic stuff to the HTTP request if it is not done
over SSL */
@@ -2538,7 +2824,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) }
}
- result = Curl_http_cookies(data, conn, &req);
+ result = http_cookies(data, conn, &req);
#ifndef CURL_DISABLE_WEBSOCKETS
if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS))
result = Curl_ws_request(data, &req);
@@ -2546,19 +2832,19 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!result)
result = Curl_add_timecondition(data, &req);
if(!result)
- result = Curl_add_custom_headers(data, FALSE, &req);
+ result = Curl_add_custom_headers(data, FALSE, httpversion, &req);
if(!result) {
/* req_send takes ownership of the 'req' memory on success */
- result = Curl_http_req_complete(data, &req, httpreq);
+ result = http_req_complete(data, &req, httpversion, httpreq);
if(!result)
- result = Curl_req_send(data, &req);
+ result = Curl_req_send(data, &req, httpversion);
}
Curl_dyn_free(&req);
if(result)
goto fail;
- if((conn->httpversion >= 20) && data->req.upload_chunky)
+ if((httpversion >= 20) && data->req.upload_chunky)
/* upload_chunky was set above to set up the request in a chunky fashion,
but is disabled here again to avoid that the chunked encoded version is
actually used when sending the request body over h2 */
@@ -2569,8 +2855,6 @@ fail: return result;
}
-#endif /* USE_HYPER */
-
typedef enum {
STATUS_UNKNOWN, /* not enough data to tell yet */
STATUS_DONE, /* a status line was read */
@@ -2657,10 +2941,10 @@ checkprotoprefix(struct Curl_easy *data, struct connectdata *conn, Curl_compareheader(hd, STRCONST(n), STRCONST(v)))
/*
- * Curl_http_header() parses a single response header.
+ * http_header() parses a single response header.
*/
-CURLcode Curl_http_header(struct Curl_easy *data,
- const char *hd, size_t hdlen)
+static CURLcode http_header(struct Curl_easy *data,
+ const char *hd, size_t hdlen)
{
struct connectdata *conn = data->conn;
CURLcode result;
@@ -2672,7 +2956,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, case 'A':
#ifndef CURL_DISABLE_ALTSVC
v = (data->asi &&
- ((data->conn->handler->flags & PROTOPT_SSL) ||
+ (Curl_conn_is_ssl(data->conn, FIRSTSOCKET) ||
#ifdef DEBUGBUILD
/* allow debug builds to circumvent the HTTPS restriction */
getenv("CURL_ALTSVC_HTTP")
@@ -2682,8 +2966,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, )) ? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL;
if(v) {
/* the ALPN of the current request */
- enum alpnid id = (conn->httpversion == 30) ? ALPN_h3 :
- (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
+ enum alpnid id = (k->httpversion == 30) ? ALPN_h3 :
+ (k->httpversion == 20) ? ALPN_h2 : ALPN_h1;
return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name,
curlx_uitous((unsigned int)conn->remote_port));
}
@@ -2755,7 +3039,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, streamclose(conn, "Connection: close used");
return CURLE_OK;
}
- if((conn->httpversion == 10) &&
+ if((k->httpversion == 10) &&
HD_IS_AND_SAYS(hd, hdlen, "Connection:", "keep-alive")) {
/*
* An HTTP/1.0 reply with the 'Connection: keep-alive' line
@@ -2845,7 +3129,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, #ifndef CURL_DISABLE_PROXY
v = HD_VAL(hd, hdlen, "Proxy-Connection:");
if(v) {
- if((conn->httpversion == 10) && conn->bits.httpproxy &&
+ if((k->httpversion == 10) && conn->bits.httpproxy &&
HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "keep-alive")) {
/*
* When an HTTP/1.0 reply comes when using a proxy, the
@@ -2856,7 +3140,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, connkeep(conn, "Proxy-Connection keep-alive"); /* do not close */
infof(data, "HTTP/1.0 proxy connection set to keep alive");
}
- else if((conn->httpversion == 11) && conn->bits.httpproxy &&
+ else if((k->httpversion == 11) && conn->bits.httpproxy &&
HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "close")) {
/*
* We get an HTTP/1.1 response from a proxy and it says it will
@@ -2903,11 +3187,19 @@ CURLcode Curl_http_header(struct Curl_easy *data, (void)curlx_strtoofft(v, NULL, 10, &retry_after);
if(!retry_after) {
time_t date = Curl_getdate_capped(v);
- if(-1 != date)
+ time_t current = time(NULL);
+ if((time_t)-1 != date && date > current) {
/* convert date to number of seconds into the future */
- retry_after = date - time(NULL);
+ retry_after = date - current;
+ }
}
- data->info.retry_after = retry_after; /* store it */
+ if(retry_after < 0)
+ retry_after = 0;
+ /* limit to 6 hours max. this is not documented so that it can be changed
+ in the future if necessary. */
+ if(retry_after > 21600)
+ retry_after = 21600;
+ data->info.retry_after = retry_after;
return CURLE_OK;
}
break;
@@ -2938,7 +3230,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, #ifndef CURL_DISABLE_HSTS
/* If enabled, the header is incoming and this is over HTTPS */
v = (data->hsts &&
- ((conn->handler->flags & PROTOPT_SSL) ||
+ (Curl_conn_is_ssl(conn, FIRSTSOCKET) ||
#ifdef DEBUGBUILD
/* allow debug builds to circumvent the HTTPS restriction */
getenv("CURL_HSTS_HTTP")
@@ -3022,8 +3314,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, * Called after the first HTTP response line (the status line) has been
* received and parsed.
*/
-CURLcode Curl_http_statusline(struct Curl_easy *data,
- struct connectdata *conn)
+static CURLcode http_statusline(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct SingleRequest *k = &data->req;
@@ -3037,11 +3329,11 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, case 30:
#endif
/* no major version switch mid-connection */
- if(conn->httpversion &&
- (k->httpversion/10 != conn->httpversion/10)) {
+ if(k->httpversion_sent &&
+ (k->httpversion/10 != k->httpversion_sent/10)) {
failf(data, "Version mismatch (from HTTP/%u to HTTP/%u)",
- conn->httpversion/10, k->httpversion/10);
- return CURLE_UNSUPPORTED_PROTOCOL;
+ k->httpversion_sent/10, k->httpversion/10);
+ return CURLE_WEIRD_SERVER_REPLY;
}
break;
default:
@@ -3052,7 +3344,7 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, data->info.httpcode = k->httpcode;
data->info.httpversion = k->httpversion;
- conn->httpversion = (unsigned char)k->httpversion;
+ conn->httpversion_seen = (unsigned char)k->httpversion;
if(!data->state.httpversion || data->state.httpversion > k->httpversion)
/* store the lowest server version we encounter */
@@ -3116,7 +3408,7 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, figured out here after all headers have been received but before the final
call to the user's header callback, so that a valid content length can be
retrieved by the user in the final call. */
-CURLcode Curl_http_size(struct Curl_easy *data)
+static CURLcode http_size(struct Curl_easy *data)
{
struct SingleRequest *k = &data->req;
if(data->req.ignore_cl || k->chunk) {
@@ -3232,7 +3524,7 @@ static CURLcode http_on_response(struct Curl_easy *data, if(k->upgr101 == UPGR101_RECEIVED) {
/* supposedly upgraded to http2 now */
- if(conn->httpversion != 20)
+ if(data->req.httpversion != 20)
infof(data, "Lying server, not serving HTTP/2");
}
@@ -3264,12 +3556,11 @@ static CURLcode http_on_response(struct Curl_easy *data, * that tells us that the server is OK with this and ready
* to receive the data.
*/
- Curl_http_exp100_got100(data);
+ http_exp100_got100(data);
break;
case 101:
/* Switching Protocols only allowed from HTTP/1.1 */
-
- if(conn->httpversion != 11) {
+ if(k->httpversion_sent != 11) {
/* invalid for other HTTP versions */
failf(data, "unexpected 101 response code");
result = CURLE_WEIRD_SERVER_REPLY;
@@ -3283,6 +3574,7 @@ static CURLcode http_on_response(struct Curl_easy *data, /* We expect more response from HTTP/2 later */
k->header = TRUE;
k->headerline = 0; /* restart the header line counter */
+ k->httpversion_sent = 20; /* It's a HTTP/2 request now */
/* Any remaining `buf` bytes are already HTTP/2 and passed to
* be processed. */
result = Curl_http2_upgrade(data, conn, FIRSTSOCKET, buf, blen);
@@ -3304,10 +3596,9 @@ static CURLcode http_on_response(struct Curl_easy *data, }
#endif
else {
- /* We silently accept this as the final response.
- * TODO: this looks, uhm, wrong. What are we switching to if we
- * did not ask for an Upgrade? Maybe the application provided an
- * `Upgrade: xxx` header? */
+ /* We silently accept this as the final response. What are we
+ * switching to if we did not ask for an Upgrade? Maybe the
+ * application provided an `Upgrade: xxx` header? */
k->header = FALSE;
}
break;
@@ -3331,7 +3622,7 @@ static CURLcode http_on_response(struct Curl_easy *data, }
if((k->size == -1) && !k->chunk && !conn->bits.close &&
- (conn->httpversion == 11) &&
+ (k->httpversion == 11) &&
!(conn->handler->protocol & CURLPROTO_RTSP) &&
data->state.httpreq != HTTPREQ_HEAD) {
/* On HTTP 1.1, when connection is not to get closed, but no
@@ -3423,7 +3714,7 @@ static CURLcode http_on_response(struct Curl_easy *data, * connection for closure after we have read the entire response.
*/
if(!Curl_req_done_sending(data)) {
- if((k->httpcode == 417) && Curl_http_exp100_is_selected(data)) {
+ if((k->httpcode == 417) && http_exp100_is_selected(data)) {
/* 417 Expectation Failed - try again without the Expect
header */
if(!k->writebytecount && http_exp100_is_waiting(data)) {
@@ -3480,19 +3771,17 @@ static CURLcode http_on_response(struct Curl_easy *data, like to call http2_handle_stream_close to properly close a
stream. In order to do this, we keep reading until we
close the stream. */
- if(0 == k->maxdownload
- && !Curl_conn_is_http2(data, conn, FIRSTSOCKET)
- && !Curl_conn_is_http3(data, conn, FIRSTSOCKET))
+ if((0 == k->maxdownload) && (k->httpversion_sent < 20))
k->download_done = TRUE;
/* final response without error, prepare to receive the body */
- result = Curl_http_firstwrite(data);
+ result = http_firstwrite(data);
if(!result)
/* This is the last response that we get for the current request.
* Check on the body size and determine if the response is complete.
*/
- result = Curl_http_size(data);
+ result = http_size(data);
out:
if(last_hd) {
@@ -3567,7 +3856,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, p++;
if((p[0] == '.') && (p[1] == '0' || p[1] == '1')) {
if(ISBLANK(p[2])) {
- k->httpversion = 10 + (p[1] - '0');
+ k->httpversion = (unsigned char)(10 + (p[1] - '0'));
p += 3;
if(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2])) {
k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 +
@@ -3587,7 +3876,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, case '3':
if(!ISBLANK(p[1]))
break;
- k->httpversion = (*p - '0') * 10;
+ k->httpversion = (unsigned char)((*p - '0') * 10);
p += 2;
if(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2])) {
k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 +
@@ -3645,7 +3934,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, }
if(fine_statusline) {
- result = Curl_http_statusline(data, data->conn);
+ result = http_statusline(data, data->conn);
if(result)
return result;
writetype |= CLIENTWRITE_STATUS;
@@ -3660,7 +3949,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, if(result)
return result;
- result = Curl_http_header(data, hd, hdlen);
+ result = http_header(data, hd, hdlen);
if(result)
return result;
@@ -3717,10 +4006,11 @@ static CURLcode http_parse_headers(struct Curl_easy *data, Curl_dyn_len(&data->state.headerb));
if(st == STATUS_BAD) {
- /* this is not the beginning of a protocol first header line */
+ /* this is not the beginning of a protocol first header line.
+ * Cannot be 0.9 if version was detected or connection was reused. */
k->header = FALSE;
streamclose(conn, "bad HTTP: No end-of-message indicator");
- if(conn->httpversion >= 10) {
+ if((k->httpversion >= 10) || conn->bits.reuse) {
failf(data, "Invalid status line");
return CURLE_WEIRD_SERVER_REPLY;
}
@@ -3755,8 +4045,9 @@ static CURLcode http_parse_headers(struct Curl_easy *data, Curl_dyn_len(&data->state.headerb));
if(st == STATUS_BAD) {
streamclose(conn, "bad HTTP: No end-of-message indicator");
- /* this is not the beginning of a protocol first header line */
- if(conn->httpversion >= 10) {
+ /* this is not the beginning of a protocol first header line.
+ * Cannot be 0.9 if version was detected or connection was reused. */
+ if((k->httpversion >= 10) || conn->bits.reuse) {
failf(data, "Invalid status line");
return CURLE_WEIRD_SERVER_REPLY;
}
@@ -4115,7 +4406,9 @@ struct name_const { size_t namelen;
};
+/* keep them sorted by length! */
static struct name_const H2_NON_FIELD[] = {
+ { STRCONST("TE") },
{ STRCONST("Host") },
{ STRCONST("Upgrade") },
{ STRCONST("Connection") },
@@ -4160,7 +4453,7 @@ CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme);
}
else {
- scheme = (data->conn && data->conn->handler->flags & PROTOPT_SSL) ?
+ scheme = Curl_conn_is_ssl(data->conn, FIRSTSOCKET) ?
"https" : "http";
}
}
@@ -4359,7 +4652,7 @@ static CURLcode http_exp100_add_reader(struct Curl_easy *data) return result;
}
-void Curl_http_exp100_got100(struct Curl_easy *data)
+static void http_exp100_got100(struct Curl_easy *data)
{
struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100);
if(r)
@@ -4371,7 +4664,7 @@ static bool http_exp100_is_waiting(struct Curl_easy *data) struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100);
if(r) {
struct cr_exp100_ctx *ctx = r->ctx;
- return (ctx->state == EXP100_AWAITING_CONTINUE);
+ return ctx->state == EXP100_AWAITING_CONTINUE;
}
return FALSE;
}
@@ -4383,7 +4676,7 @@ static void http_exp100_send_anyway(struct Curl_easy *data) http_exp100_continue(data, r);
}
-bool Curl_http_exp100_is_selected(struct Curl_easy *data)
+static bool http_exp100_is_selected(struct Curl_easy *data)
{
struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100);
return !!r;
|
