diff options
Diffstat (limited to 'Utilities/cmcurl/lib/url.c')
-rw-r--r-- | Utilities/cmcurl/lib/url.c | 165 |
1 files changed, 97 insertions, 68 deletions
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c index 0fb6268..61dad44 100644 --- a/Utilities/cmcurl/lib/url.c +++ b/Utilities/cmcurl/lib/url.c @@ -414,7 +414,7 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_hsts_cleanup(&data->hsts); curl_slist_free_all(data->set.hstslist); /* clean up list */ #endif -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) Curl_http_auth_cleanup_digest(data); #endif Curl_safefree(data->info.contenttype); @@ -457,6 +457,11 @@ CURLcode Curl_close(struct Curl_easy **datap) } #endif + Curl_mime_cleanpart(data->state.formp); +#ifndef CURL_DISABLE_HTTP + Curl_safefree(data->state.formp); +#endif + /* destruct wildcard structures if it is needed */ Curl_wildcard_dtor(&data->wildcard); Curl_freeset(data); @@ -490,7 +495,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->filesize = -1; /* we don't know the size */ set->postfieldsize = -1; /* unknown size */ - set->maxredirs = -1; /* allow any amount by default */ + set->maxredirs = 30; /* sensible default */ set->method = HTTPREQ_GET; /* Default HTTP request */ #ifndef CURL_DISABLE_RTSP @@ -659,6 +664,9 @@ CURLcode Curl_open(struct Curl_easy **curl) /* most recent connection is not yet defined */ data->state.lastconnect_id = -1; + data->state.recent_conn_id = -1; + /* and not assigned an id yet */ + data->id = -1; data->progress.flags |= PGRS_HIDE; data->state.current_speed = -1; /* init to negative == impossible */ @@ -680,7 +688,7 @@ CURLcode Curl_open(struct Curl_easy **curl) static void conn_shutdown(struct Curl_easy *data) { DEBUGASSERT(data); - infof(data, "Closing connection %ld", data->conn->connection_id); + infof(data, "Closing connection"); /* possible left-overs from the async name resolvers */ Curl_resolver_cancel(data); @@ -763,7 +771,8 @@ void Curl_disconnect(struct Curl_easy *data, /* the transfer must be detached from the connection */ DEBUGASSERT(!data->conn); - DEBUGF(infof(data, "Curl_disconnect(conn #%ld, dead=%d)", + DEBUGF(infof(data, "Curl_disconnect(conn #%" + CURL_FORMAT_CURL_OFF_T ", dead=%d)", conn->connection_id, dead_connection)); /* * If this connection isn't marked to force-close, leave it open if there @@ -879,8 +888,8 @@ static bool conn_maxage(struct Curl_easy *data, idletime /= 1000; /* integer seconds is fine */ if(idletime > data->set.maxage_conn) { - infof(data, "Too old connection (%ld seconds idle), disconnect it", - idletime); + infof(data, "Too old connection (%" CURL_FORMAT_TIMEDIFF_T + " seconds idle), disconnect it", idletime); return TRUE; } @@ -889,8 +898,8 @@ static bool conn_maxage(struct Curl_easy *data, if(data->set.maxlifetime_conn && lifetime > data->set.maxlifetime_conn) { infof(data, - "Too old connection (%ld seconds since creation), disconnect it", - lifetime); + "Too old connection (%" CURL_FORMAT_TIMEDIFF_T + " seconds since creation), disconnect it", lifetime); return TRUE; } @@ -937,22 +946,25 @@ static bool extract_if_dead(struct connectdata *conn, else { bool input_pending; + Curl_attach_connection(data, conn); dead = !Curl_conn_is_alive(data, conn, &input_pending); if(input_pending) { /* For reuse, we want a "clean" connection state. The includes * that we expect - in general - no waiting input data. Input * waiting might be a TLS Notify Close, for example. We reject * that. - * For protocols where data from other other end may arrive at + * For protocols where data from other end may arrive at * any time (HTTP/2 PING for example), the protocol handler needs * to install its own `connection_check` callback. */ dead = TRUE; } + Curl_detach_connection(data); } if(dead) { - infof(data, "Connection %ld seems to be dead", conn->connection_id); + infof(data, "Connection %" CURL_FORMAT_CURL_OFF_T " seems to be dead", + conn->connection_id); Curl_conncache_remove_conn(data, conn, FALSE); return TRUE; } @@ -1066,6 +1078,9 @@ ConnectionExists(struct Curl_easy *data, bool wantProxyNTLMhttp = FALSE; #endif #endif + /* plain HTTP with upgrade */ + bool h2upgrade = (data->state.httpwant == CURL_HTTP_VERSION_2_0) && + (needle->handler->protocol & CURLPROTO_HTTP); *force_reuse = FALSE; *waitpipe = FALSE; @@ -1088,7 +1103,7 @@ ConnectionExists(struct Curl_easy *data, infof(data, "Server doesn't support multiplex yet, wait"); *waitpipe = TRUE; CONNCACHE_UNLOCK(data); - return FALSE; /* no re-use */ + return FALSE; /* no reuse */ } infof(data, "Server doesn't support multiplex (yet)"); @@ -1128,7 +1143,7 @@ ConnectionExists(struct Curl_easy *data, } if(data->set.ipver != CURL_IPRESOLVE_WHATEVER - && data->set.ipver != check->ip_version) { + && data->set.ipver != check->ip_version) { /* skip because the connection is not via the requested IP version */ continue; } @@ -1143,23 +1158,18 @@ ConnectionExists(struct Curl_easy *data, continue; } - if(Curl_resolver_asynch()) { - /* primary_ip[0] is NUL only if the resolving of the name hasn't - completed yet and until then we don't re-use this connection */ - if(!check->primary_ip[0]) { - infof(data, - "Connection #%ld is still name resolving, can't reuse", - check->connection_id); - continue; - } - } + if(Curl_resolver_asynch() && + /* primary_ip[0] is NUL only if the resolving of the name hasn't + completed yet and until then we don't reuse this connection */ + !check->primary_ip[0]) + continue; } if(!Curl_conn_is_connected(check, FIRSTSOCKET)) { foundPendingCandidate = TRUE; /* Don't pick a connection that hasn't connected yet */ - infof(data, "Connection #%ld isn't open enough, can't reuse", - check->connection_id); + infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T + " isn't open enough, can't reuse", check->connection_id); continue; } @@ -1231,6 +1241,17 @@ ConnectionExists(struct Curl_easy *data, } #endif + if(h2upgrade && !check->httpversion && canmultiplex) { + if(data->set.pipewait) { + infof(data, "Server upgrade doesn't support multiplex yet, wait"); + *waitpipe = TRUE; + CONNCACHE_UNLOCK(data); + return FALSE; /* no reuse */ + } + infof(data, "Server upgrade cannot be used"); + continue; /* can't be used atm */ + } + if(!canmultiplex && CONN_INUSE(check)) /* this request can't be multiplexed but the checked connection is already in use so we skip it */ @@ -1247,14 +1268,14 @@ ConnectionExists(struct Curl_easy *data, if(needle->localdev || needle->localport) { /* If we are bound to a specific local end (IP+port), we must not - re-use a random other one, although if we didn't ask for a + reuse a random other one, although if we didn't ask for a particular one we can reuse one that was bound. This comparison is a bit rough and too strict. Since the input parameters can be specified in numerous ways and still end up the same it would take a lot of processing to make it really accurate. - Instead, this matching will assume that re-uses of bound connections - will most likely also re-use the exact same binding parameters and + Instead, this matching will assume that reuses of bound connections + will most likely also reuse the exact same binding parameters and missing out a few edge cases shouldn't hurt anyone very much. */ if((check->localport != needle->localport) || @@ -1287,7 +1308,7 @@ ConnectionExists(struct Curl_easy *data, (((check->httpversion >= 20) && (data->state.httpwant < CURL_HTTP_VERSION_2_0)) || ((check->httpversion >= 30) && - (data->state.httpwant < CURL_HTTP_VERSION_3)))) + (data->state.httpwant < CURL_HTTP_VERSION_3)))) continue; #ifdef USE_SSH else if(get_protocol_family(needle->handler) & PROTO_FAMILY_SSH) { @@ -1335,8 +1356,8 @@ ConnectionExists(struct Curl_easy *data, if(!Curl_ssl_config_matches(&needle->ssl_config, &check->ssl_config)) { DEBUGF(infof(data, - "Connection #%ld has different SSL parameters, " - "can't reuse", + "Connection #%" CURL_FORMAT_CURL_OFF_T + " has different SSL parameters, can't reuse", check->connection_id)); continue; } @@ -1477,14 +1498,8 @@ void Curl_verboseconnect(struct Curl_easy *data, struct connectdata *conn) { if(data->set.verbose) - infof(data, "Connected to %s (%s) port %u (#%ld)", -#ifndef CURL_DISABLE_PROXY - conn->bits.socksproxy ? conn->socks_proxy.host.dispname : - conn->bits.httpproxy ? conn->http_proxy.host.dispname : -#endif - conn->bits.conn_to_host ? conn->conn_to_host.dispname : - conn->host.dispname, - conn->primary_ip, conn->port, conn->connection_id); + infof(data, "Connected to %s (%s) port %u", + CURL_CONN_HOST_DISPNAME(conn), conn->primary_ip, conn->port); } #endif @@ -1580,8 +1595,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) if(!conn->localdev) goto error; } +#ifndef CURL_DISABLE_BINDLOCAL conn->localportrange = data->set.localportrange; conn->localport = data->set.localport; +#endif /* the close socket stuff needs to be copied to the connection struct as it may live on without (this specific) Curl_easy */ @@ -1857,7 +1874,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, * User name and password set with their own options override the * credentials possibly set in the URL. */ - if(!data->state.aptr.passwd) { + if(!data->set.str[STRING_PASSWORD]) { uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0); if(!uc) { char *decoded; @@ -2016,13 +2033,13 @@ void Curl_free_request_state(struct Curl_easy *data) { Curl_safefree(data->req.p.http); Curl_safefree(data->req.newurl); - #ifndef CURL_DISABLE_DOH if(data->req.doh) { Curl_close(&data->req.doh->probe[0].easy); Curl_close(&data->req.doh->probe[1].easy); } #endif + Curl_client_cleanup(data); } @@ -2059,7 +2076,6 @@ static char *detect_proxy(struct Curl_easy *data, char proxy_env[128]; const char *protop = conn->handler->scheme; char *envp = proxy_env; - char *prox; #ifdef CURL_DISABLE_VERBOSE_STRINGS (void)data; #endif @@ -2072,7 +2088,7 @@ static char *detect_proxy(struct Curl_easy *data, strcpy(envp, "_proxy"); /* read the protocol proxy: */ - prox = curl_getenv(proxy_env); + proxy = curl_getenv(proxy_env); /* * We don't try the uppercase version of HTTP_PROXY because of @@ -2086,23 +2102,35 @@ static char *detect_proxy(struct Curl_easy *data, * This can cause 'internal' http/ftp requests to be * arbitrarily redirected by any external attacker. */ - if(!prox && !strcasecompare("http_proxy", proxy_env)) { + if(!proxy && !strcasecompare("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); - prox = curl_getenv(proxy_env); + proxy = curl_getenv(proxy_env); } envp = proxy_env; - if(prox) { - proxy = prox; /* use this */ - } - else { - envp = (char *)"all_proxy"; - proxy = curl_getenv(envp); /* default proxy to use */ + if(!proxy) { +#ifdef USE_WEBSOCKETS + /* websocket proxy fallbacks */ + if(strcasecompare("ws_proxy", proxy_env)) { + proxy = curl_getenv("http_proxy"); + } + else if(strcasecompare("wss_proxy", proxy_env)) { + proxy = curl_getenv("https_proxy"); + if(!proxy) + proxy = curl_getenv("HTTPS_PROXY"); + } if(!proxy) { - envp = (char *)"ALL_PROXY"; - proxy = curl_getenv(envp); +#endif + envp = (char *)"all_proxy"; + proxy = curl_getenv(envp); /* default proxy to use */ + if(!proxy) { + envp = (char *)"ALL_PROXY"; + proxy = curl_getenv(envp); + } +#ifdef USE_WEBSOCKETS } +#endif } if(proxy) infof(data, "Uses proxy env variable %s == '%s'", envp, proxy); @@ -2113,7 +2141,7 @@ static char *detect_proxy(struct Curl_easy *data, /* * If this is supposed to use a proxy, we need to figure out the proxy - * host name, so that we can re-use an existing connection + * host name, so that we can reuse an existing connection * that may exist registered to the same proxy host. */ static CURLcode parse_proxy(struct Curl_easy *data, @@ -2434,7 +2462,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, /*********************************************************************** * If this is supposed to use a proxy, we need to figure out the proxy host - * name, proxy type and port number, so that we can re-use an existing + * name, proxy type and port number, so that we can reuse an existing * connection that may exist registered to the same proxy host. ***********************************************************************/ if(proxy || socksproxy) { @@ -2702,7 +2730,9 @@ static CURLcode override_login(struct Curl_easy *data, data->set.str[STRING_NETRC_FILE]); if(ret > 0) { infof(data, "Couldn't find host %s in the %s file; using defaults", - conn->host.name, data->set.str[STRING_NETRC_FILE]); + conn->host.name, + (data->set.str[STRING_NETRC_FILE] ? + data->set.str[STRING_NETRC_FILE] : ".netrc")); } else if(ret < 0) { failf(data, ".netrc parser error"); @@ -3197,8 +3227,8 @@ static CURLcode resolve_host(struct Curl_easy *data, if(rc == CURLRESOLV_PENDING) *async = TRUE; else if(rc == CURLRESOLV_TIMEDOUT) { - failf(data, "Failed to resolve host '%s' with timeout after %ld ms", - connhost->dispname, + failf(data, "Failed to resolve host '%s' with timeout after %" + CURL_FORMAT_TIMEDIFF_T " ms", connhost->dispname, Curl_timediff(Curl_now(), data->progress.t_startsingle)); return CURLE_OPERATION_TIMEDOUT; } @@ -3252,7 +3282,7 @@ static CURLcode resolve_server(struct Curl_easy *data, /* Resolve the name of the server or proxy */ if(conn->bits.reuse) { /* We're reusing the connection - no need to resolve anything, and - idnconvert_hostname() was called already in create_conn() for the re-use + idnconvert_hostname() was called already in create_conn() for the reuse case. */ *async = FALSE; return CURLE_OK; @@ -3271,7 +3301,7 @@ static void reuse_conn(struct Curl_easy *data, struct connectdata *existing) { /* get the user+password information from the temp struct since it may - * be new for this request even when we re-use an existing connection */ + * be new for this request even when we reuse an existing connection */ if(temp->user) { /* use the new user name and password though */ Curl_safefree(existing->user); @@ -3331,14 +3361,14 @@ static void reuse_conn(struct Curl_easy *data, existing->hostname_resolve = temp->hostname_resolve; temp->hostname_resolve = NULL; - /* re-use init */ - existing->bits.reuse = TRUE; /* yes, we're re-using here */ + /* reuse init */ + existing->bits.reuse = TRUE; /* yes, we're reusing here */ conn_free(data, temp); } /** - * create_conn() sets up a new connectdata struct, or re-uses an already + * create_conn() sets up a new connectdata struct, or reuses an already * existing one, and resolves host name. * * if this function returns CURLE_OK and *async is set to TRUE, the resolve @@ -3650,7 +3680,7 @@ static CURLcode create_conn(struct Curl_easy *data, /************************************************************* * Check the current list of connections to see if we can - * re-use an already existing one or if we have to create a + * reuse an already existing one or if we have to create a * new one. *************************************************************/ @@ -3658,7 +3688,7 @@ static CURLcode create_conn(struct Curl_easy *data, DEBUGASSERT(conn->passwd); /* reuse_fresh is TRUE if we are told to use a new connection by force, but - we only acknowledge this option if this is not a re-used connection + we only acknowledge this option if this is not a reused connection already (which happens due to follow-location or during an HTTP authentication phase). CONNECT_ONLY transfers also refuse reuse. */ if((data->set.reuse_fresh && !data->state.followlocation) || @@ -3678,15 +3708,14 @@ static CURLcode create_conn(struct Curl_easy *data, *in_connect = conn; #ifndef CURL_DISABLE_PROXY - infof(data, "Re-using existing connection #%ld with %s %s", - conn->connection_id, + infof(data, "Re-using existing connection with %s %s", conn->bits.proxy?"proxy":"host", conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname : conn->http_proxy.host.name ? conn->http_proxy.host.dispname : conn->host.dispname); #else - infof(data, "Re-using existing connection #%ld with host %s", - conn->connection_id, conn->host.dispname); + infof(data, "Re-using existing connection with host %s", + conn->host.dispname); #endif } else { |