diff options
author | Seonah Moon <seonah1.moon@samsung.com> | 2020-02-24 15:56:49 +0900 |
---|---|---|
committer | Seonah Moon <seonah1.moon@samsung.com> | 2020-02-24 15:57:31 +0900 |
commit | 1127a2d91941b474b346c96a1499f3493a3f0f40 (patch) | |
tree | e6734b853d299aa98a3653cebf0233a712c07009 /lib/urldata.h | |
parent | bc9ddd35af69662a667d983e2484f557f76cf230 (diff) | |
download | curl-upstream/7.68.0.tar.gz curl-upstream/7.68.0.tar.bz2 curl-upstream/7.68.0.zip |
Imported Upstream version 7.68.0upstream/7.68.0
Change-Id: I37422e43c2c4c25904a4fc2a391c4a32ba3b9f5c
Diffstat (limited to 'lib/urldata.h')
-rw-r--r-- | lib/urldata.h | 686 |
1 files changed, 378 insertions, 308 deletions
diff --git a/lib/urldata.h b/lib/urldata.h index 11a6a22c6..3effb1626 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 @@ -68,6 +68,7 @@ #define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S) #define PROTO_FAMILY_SMB (CURLPROTO_SMB|CURLPROTO_SMBS) #define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS) +#define PROTO_FAMILY_SSH (CURLPROTO_SCP|CURLPROTO_SFTP) #define DEFAULT_CONNCACHE_SIZE 5 @@ -77,7 +78,11 @@ /* Default FTP/IMAP etc response timeout in milliseconds. Symbian OS panics when given a timeout much greater than 1/2 hour. */ -#define RESP_TIMEOUT (1800*1000) +#define RESP_TIMEOUT (120*1000) + +/* Max string intput length is a precaution against abuse and to detect junk + input easier and better. */ +#define CURL_MAX_INPUT_LENGTH 8000000 #include "cookie.h" #include "psl.h" @@ -119,22 +124,25 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #include "smtp.h" #include "ftp.h" #include "file.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "http.h" #include "rtsp.h" #include "smb.h" #include "wildcard.h" #include "multihandle.h" +#include "quic.h" #ifdef HAVE_GSSAPI # ifdef HAVE_GSSGNU # include <gss.h> -# elif defined HAVE_GSSMIT +# elif defined HAVE_GSSAPI_GSSAPI_H # include <gssapi/gssapi.h> -# include <gssapi/gssapi_generic.h> # else # include <gssapi.h> # endif +# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H +# include <gssapi/gssapi_generic.h> +# endif #endif #ifdef HAVE_LIBSSH2_H @@ -142,10 +150,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #include <libssh2_sftp.h> #endif /* HAVE_LIBSSH2_H */ - -/* The "master buffer" is for HTTP pipelining */ -#define MASTERBUF_SIZE 16384 - /* Initial size of the buffer to store headers in, it'll be enlarged in case of need. */ #define HEADERSIZE 256 @@ -154,13 +158,22 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #define GOOD_EASY_HANDLE(x) \ ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) +/* the type we use for storing a single boolean bit */ +#ifdef _MSC_VER +typedef bool bit; +#define BIT(x) bool x +#else +typedef unsigned int bit; +#define BIT(x) bit x:1 +#endif + #ifdef HAVE_GSSAPI /* Types needed for krb5-ftp connections */ struct krb5buffer { void *data; size_t size; size_t index; - int eof_flag; + BIT(eof_flag); }; enum protection_level { @@ -198,21 +211,17 @@ struct ssl_connect_data { /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm but at least asked to or meaning to use it. See 'state' for the exact current state of the connection. */ - bool use; ssl_connection_state state; ssl_connect_state connecting_state; #if defined(USE_SSL) struct ssl_backend_data *backend; #endif + BIT(use); }; struct ssl_primary_config { long version; /* what version the client wants to use */ long version_max; /* max supported version the client wants to use*/ - bool verifypeer; /* set TRUE if this is desired */ - bool verifyhost; /* set TRUE if CN/SAN must match hostname */ - bool verifystatus; /* set TRUE if certificate status must be checked */ - bool sessionid; /* cache session IDs or not */ char *CApath; /* certificate dir (doesn't work on windows) */ char *CAfile; /* certificate to verify peer against */ char *clientcert; @@ -220,32 +229,35 @@ struct ssl_primary_config { char *egdsocket; /* path to file containing the EGD daemon socket */ char *cipher_list; /* list of ciphers to use */ char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ + char *pinned_key; + BIT(verifypeer); /* set TRUE if this is desired */ + BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ + BIT(verifystatus); /* set TRUE if certificate status must be checked */ + BIT(sessionid); /* cache session IDs or not */ }; struct ssl_config_data { struct ssl_primary_config primary; - bool enable_beast; /* especially allow this flaw for interoperability's - sake*/ - bool no_revoke; /* disable SSL certificate revocation checks */ long certverifyresult; /* result from the certificate verification */ char *CRLfile; /* CRL to check certificate revocation */ char *issuercert;/* optional issuer certificate filename */ curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ void *fsslctxp; /* parameter for call back */ - bool certinfo; /* gather lots of certificate info */ - bool falsestart; - char *cert; /* client certificate file name */ char *cert_type; /* format for certificate (default: PEM)*/ char *key; /* private key file name */ char *key_type; /* format for private key (default: PEM) */ char *key_passwd; /* plain text private key password */ - #ifdef USE_TLS_SRP char *username; /* TLS username (for, e.g., SRP) */ char *password; /* TLS password (for, e.g., SRP) */ enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ #endif + BIT(certinfo); /* gather lots of certificate info */ + BIT(falsestart); + BIT(enable_beast); /* allow this flaw for interoperability's sake*/ + BIT(no_revoke); /* disable SSL certificate revocation checks */ + BIT(no_partialchain); /* don't accept partial certificate chains */ }; struct ssl_general_config { @@ -284,12 +296,12 @@ struct digestdata { char *cnonce; char *realm; int algo; - bool stale; /* set true for re-negotiation */ char *opaque; char *qop; char *algorithm; int nc; /* nounce count */ - bool userhash; + BIT(stale); /* set true for re-negotiation */ + BIT(userhash); #endif }; @@ -301,6 +313,14 @@ typedef enum { NTLMSTATE_LAST } curlntlm; +typedef enum { + GSS_AUTHNONE, + GSS_AUTHRECV, + GSS_AUTHSENT, + GSS_AUTHDONE, + GSS_AUTHSUCC +} curlnegotiate; + #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) #include <iconv.h> #endif @@ -326,8 +346,13 @@ struct kerberos5data { /* Struct used for NTLM challenge-response authentication */ #if defined(USE_NTLM) struct ntlmdata { - curlntlm state; #ifdef USE_WINDOWS_SSPI +/* The sslContext is used for the Schannel bindings. The + * api is available on the Windows 7 SDK and later. + */ +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif CredHandle *credentials; CtxtHandle *context; SEC_WINNT_AUTH_IDENTITY identity; @@ -346,11 +371,9 @@ struct ntlmdata { }; #endif +/* Struct used for Negotiate (SPNEGO) authentication */ #ifdef USE_SPNEGO struct negotiatedata { - /* When doing Negotiate (SPNEGO) auth, we first need to send a token - and then validate the received one. */ - enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state; #ifdef HAVE_GSSAPI OM_uint32 status; gss_ctx_id_t context; @@ -358,6 +381,9 @@ struct negotiatedata { gss_buffer_desc output_token; #else #ifdef USE_WINDOWS_SSPI +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif DWORD status; CredHandle *credentials; CtxtHandle *context; @@ -369,6 +395,10 @@ struct negotiatedata { size_t output_token_length; #endif #endif + BIT(noauthpersist); + BIT(havenoauthpersist); + BIT(havenegdata); + BIT(havemultiplerequests); }; #endif @@ -378,69 +408,68 @@ struct negotiatedata { */ struct ConnectBits { /* always modify bits.close with the connclose() and connkeep() macros! */ - bool close; /* if set, we close the connection after this request */ - bool reuse; /* if set, this is a re-used connection */ - bool conn_to_host; /* if set, this connection has a "connect to host" + bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy + is complete */ + bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set + the first time on the first connect function call */ + BIT(close); /* if set, we close the connection after this request */ + BIT(reuse); /* if set, this is a re-used connection */ + BIT(altused); /* this is an alt-svc "redirect" */ + BIT(conn_to_host); /* if set, this connection has a "connect to host" that overrides the host in the URL */ - bool conn_to_port; /* if set, this connection has a "connect to port" + BIT(conn_to_port); /* if set, this connection has a "connect to port" that overrides the port in the URL (remote port) */ - bool proxy; /* if set, this transfer is done through a proxy - any type */ - bool httpproxy; /* if set, this transfer is done through a http proxy */ - bool socksproxy; /* if set, this transfer is done through a socks proxy */ - bool user_passwd; /* do we use user+password for this connection? */ - bool proxy_user_passwd; /* user+password for the proxy? */ - bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6 + BIT(proxy); /* if set, this transfer is done through a proxy - any type */ + BIT(httpproxy); /* if set, this transfer is done through a http proxy */ + BIT(socksproxy); /* if set, this transfer is done through a socks proxy */ + BIT(user_passwd); /* do we use user+password for this connection? */ + BIT(proxy_user_passwd); /* user+password for the proxy? */ + BIT(ipv6_ip); /* we communicate with a remote site specified with pure IPv6 IP address */ - bool ipv6; /* we communicate with a site using an IPv6 address */ - - bool do_more; /* this is set TRUE if the ->curl_do_more() function is + BIT(ipv6); /* we communicate with a site using an IPv6 address */ + BIT(do_more); /* this is set TRUE if the ->curl_do_more() function is supposed to be called, after ->curl_do() */ - bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set - the first time on the first connect function call */ - bool protoconnstart;/* the protocol layer has STARTED its operation after + BIT(protoconnstart);/* the protocol layer has STARTED its operation after the TCP layer connect */ - - bool retry; /* this connection is about to get closed and then + BIT(retry); /* this connection is about to get closed and then re-attempted at another connection. */ - bool tunnel_proxy; /* if CONNECT is used to "tunnel" through the proxy. + BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy. This is implicit when SSL-protocols are used through proxies, but can also be enabled explicitly by apps */ - bool authneg; /* TRUE when the auth phase has started, which means + BIT(authneg); /* TRUE when the auth phase has started, which means that we are creating a request with an auth header, but it is not the final request in the auth negotiation. */ - bool rewindaftersend;/* TRUE when the sending couldn't be stopped even + BIT(rewindaftersend);/* TRUE when the sending couldn't be stopped even though it will be discarded. When the whole send operation is done, we must call the data rewind callback. */ - bool ftp_use_epsv; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out +#ifndef CURL_DISABLE_FTP + BIT(ftp_use_epsv); /* As set with CURLOPT_FTP_USE_EPSV, but if we find out EPSV doesn't work we disable it for the forthcoming requests */ - - bool ftp_use_eprt; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out + BIT(ftp_use_eprt); /* As set with CURLOPT_FTP_USE_EPRT, but if we find out EPRT doesn't work we disable it for the forthcoming requests */ - bool ftp_use_data_ssl; /* Enabled SSL for the data connection */ - bool netrc; /* name+password provided by netrc */ - bool userpwd_in_url; /* name+password found in url */ - bool stream_was_rewound; /* Indicates that the stream was rewound after a - request read past the end of its response byte - boundary */ - bool proxy_connect_closed; /* set true if a proxy disconnected the - connection in a CONNECT request with auth, so - that libcurl should reconnect and continue. */ - bool bound; /* set true if bind() has already been done on this socket/ + BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */ +#endif + BIT(netrc); /* name+password provided by netrc */ + BIT(userpwd_in_url); /* name+password found in url */ + BIT(stream_was_rewound); /* The stream was rewound after a request read + past the end of its response byte boundary */ + BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection + in a CONNECT request with auth, so that + libcurl should reconnect and continue. */ + BIT(bound); /* set true if bind() has already been done on this socket/ connection */ - bool type_set; /* type= was used in the URL */ - bool multiplex; /* connection is multiplexed */ - - bool tcp_fastopen; /* use TCP Fast Open */ - bool tls_enable_npn; /* TLS NPN extension? */ - bool tls_enable_alpn; /* TLS ALPN extension? */ - bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy - is complete */ - bool socksproxy_connecting; /* connecting through a socks proxy */ + BIT(type_set); /* type= was used in the URL */ + BIT(multiplex); /* connection is multiplexed */ + BIT(tcp_fastopen); /* use TCP Fast Open */ + BIT(tls_enable_npn); /* TLS NPN extension? */ + BIT(tls_enable_alpn); /* TLS ALPN extension? */ + BIT(socksproxy_connecting); /* connecting through a socks proxy */ + BIT(connect_only); }; struct hostname { @@ -467,14 +496,13 @@ struct hostname { #define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE) #define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE) - struct Curl_async { char *hostname; int port; struct Curl_dns_entry *dns; - bool done; /* set TRUE when the lookup is complete */ int status; /* if done is TRUE, this is the status from the callback */ void *os_specific; /* 'struct thread_data' for Windows */ + BIT(done); /* set TRUE when the lookup is complete */ }; #define FIRSTSOCKET 0 @@ -501,6 +529,24 @@ enum upgrade101 { UPGR101_WORKING /* talking upgraded protocol */ }; +enum doh_slots { + /* Explicit values for first two symbols so as to match hard-coded + * constants in existing code + */ + DOH_PROBE_SLOT_IPADDR_V4 = 0, /* make 'V4' stand out for readability */ + DOH_PROBE_SLOT_IPADDR_V6 = 1, /* 'V6' likewise */ + + /* Space here for (possibly build-specific) additional slot definitions */ + + /* for example */ + /* #ifdef WANT_DOH_FOOBAR_TXT */ + /* DOH_PROBE_SLOT_FOOBAR_TXT, */ + /* #endif */ + + /* AFTER all slot definitions, establish how many we have */ + DOH_PROBE_SLOTS +}; + struct dohresponse { unsigned char *memory; size_t size; @@ -517,7 +563,7 @@ struct dnsprobe { struct dohdata { struct curl_slist *headers; - struct dnsprobe probe[2]; + struct dnsprobe probe[DOH_PROBE_SLOTS]; unsigned int pending; /* still outstanding requests */ const char *host; int port; @@ -532,25 +578,21 @@ struct dohdata { */ struct SingleRequest { curl_off_t size; /* -1 if unknown at this point */ - curl_off_t *bytecountp; /* return number of bytes read or NULL */ - curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, -1 means unlimited */ - curl_off_t *writebytecountp; /* return number of bytes written or NULL */ - curl_off_t bytecount; /* total number of bytes read */ curl_off_t writebytecount; /* number of bytes written */ - long headerbytecount; /* only count received headers */ - long deductheadercount; /* this amount of bytes doesn't count when we check - if anything has been transferred at the end of a - connection. We use this counter to make only a - 100 reply (without a following second response - code) result in a CURLE_GOT_NOTHING error code */ + curl_off_t headerbytecount; /* only count received headers */ + curl_off_t deductheadercount; /* this amount of bytes doesn't count when we + check if anything has been transferred at + the end of a connection. We use this + counter to make only a 100 reply (without a + following second response code) result in a + CURLE_GOT_NOTHING error code */ struct curltime start; /* transfer started at this time */ struct curltime now; /* current time */ - bool header; /* incoming data has HTTP header */ enum { HEADER_NORMAL, /* no bad header at all */ HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest @@ -566,7 +608,6 @@ struct SingleRequest { char *str_start; /* within buf */ char *end_ptr; /* within buf */ char *p; /* within headerbuff */ - bool content_range; /* set TRUE if Content-Range: was found */ curl_off_t offset; /* possible resume offset read from the Content-Range: header */ int httpcode; /* error code from the 'HTTP/1.? XXX' or @@ -579,19 +620,8 @@ struct SingleRequest { /* See sec 3.5, RFC2616. */ time_t timeofdoc; long bodywrites; - char *buf; - curl_socket_t maxfd; - int keepon; - - bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload - and we're uploading the last chunk */ - - bool ignorebody; /* we read a response-body but we ignore it! */ - bool ignorecl; /* This HTTP response has no body so we ignore the Content- - Length: header */ - char *location; /* This points to an allocated version of the Location: header data */ char *newurl; /* Set to the new URL to use when a redirect or a retry is @@ -601,24 +631,30 @@ struct SingleRequest { still left in the buffer, aimed for upload. */ ssize_t upload_present; - /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a - buffer, so the next read should read from where this pointer points to, - and the 'upload_present' contains the number of bytes available at this - position */ + /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a + buffer, so the next read should read from where this pointer points to, + and the 'upload_present' contains the number of bytes available at this + position */ char *upload_fromhere; - - bool chunk; /* if set, this is a chunked transfer-encoding */ - bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding - on upload */ - bool getheader; /* TRUE if header parsing is wanted */ - - bool forbidchunk; /* used only to explicitly forbid chunk-upload for - specific upload buffers. See readmoredata() in - http.c for details. */ - void *protop; /* Allocated protocol-specific data. Each protocol handler makes sure this points to data it needs. */ +#ifndef CURL_DISABLE_DOH struct dohdata doh; /* DoH specific data for this request */ +#endif + BIT(header); /* incoming data has HTTP header */ + BIT(content_range); /* set TRUE if Content-Range: was found */ + BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding + upload and we're uploading the last chunk */ + BIT(ignorebody); /* we read a response-body but we ignore it! */ + BIT(http_bodyless); /* HTTP response status code is between 100 and 199, + 204 or 304 */ + BIT(chunk); /* if set, this is a chunked transfer-encoding */ + BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding + on upload */ + BIT(getheader); /* TRUE if header parsing is wanted */ + BIT(forbidchunk); /* used only to explicitly forbid chunk-upload for + specific upload buffers. See readmoredata() in http.c + for details. */ }; /* @@ -656,27 +692,23 @@ struct Curl_handler { /* Called from the multi interface during the PROTOCONNECT phase, and it should then return a proper fd set */ int (*proto_getsock)(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); + curl_socket_t *socks); /* Called from the multi interface during the DOING phase, and it should then return a proper fd set */ int (*doing_getsock)(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); + curl_socket_t *socks); /* Called from the multi interface during the DO_MORE phase, and it should then return a proper fd set */ int (*domore_getsock)(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); + curl_socket_t *socks); /* Called from the multi interface during the DO_DONE, PERFORM and WAITPERFORM phases, and it should then return a proper fd set. Not setting this will make libcurl use the generic default one. */ int (*perform_getsock)(const struct connectdata *conn, - curl_socket_t *socks, - int numsocks); + curl_socket_t *socks); /* This function *MAY* be set to a protocol-dependent function that is run * by the curl_disconnect(), as a step in the disconnection. If the handler @@ -766,15 +798,17 @@ struct http_connect_state { char *line_start; char *ptr; /* where to store more data */ curl_off_t cl; /* size of content to read and ignore */ - bool chunked_encoding; enum { TUNNEL_INIT, /* init/default/no tunnel state */ TUNNEL_CONNECT, /* CONNECT has been sent off */ TUNNEL_COMPLETE /* CONNECT response received completely */ } tunnel_state; - bool close_connection; + BIT(chunked_encoding); + BIT(close_connection); }; +struct ldapconninfo; + /* * The connectdata struct contains all fields and variables that should be * unique for an entire connection. @@ -796,11 +830,10 @@ struct connectdata { void *closesocket_client; /* This is used by the connection cache logic. If this returns TRUE, this - handle is being used by one or more easy handles and can only used by any + handle is still used by one or more easy handles and can only used by any other easy handle without careful consideration (== only for - pipelining/multiplexing) and it cannot be used by another multi - handle! */ -#define CONN_INUSE(c) ((c)->send_pipe.size + (c)->recv_pipe.size) + multiplexing) and it cannot be used by another multi handle! */ +#define CONN_INUSE(c) ((c)->easyq.size) /**** Fields set when inited and not modified again */ long connection_id; /* Contains a unique number to make it easier to @@ -825,9 +858,19 @@ struct connectdata { unsigned int scope_id; /* Scope id for IPv6 */ - int socktype; /* SOCK_STREAM or SOCK_DGRAM */ + enum { + TRNSPRT_TCP = 3, + TRNSPRT_UDP = 4, + TRNSPRT_QUIC = 5 + } transport; + +#ifdef ENABLE_QUIC + struct quicsocket hequic[2]; /* two, for happy eyeballs! */ + struct quicsocket *quic; +#endif struct hostname host; + char *hostname_resolve; /* host name to resolve to address, allocated */ char *secondaryhostname; /* secondary socket host name (ftp) */ struct hostname conn_to_host; /* the host to connect to. valid only if bits.conn_to_host is set */ @@ -863,13 +906,15 @@ struct connectdata { char *passwd; /* password string, allocated */ char *options; /* options string, allocated */ - char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */ + char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */ + char *sasl_authzid; /* authorisation identity string, allocated */ int httpversion; /* the HTTP version*10 reported by the server */ int rtspversion; /* the RTSP version*10 reported by the server */ struct curltime now; /* "current" time */ struct curltime created; /* creation time */ + struct curltime lastused; /* when returned to the connection cache */ curl_socket_t sock[2]; /* two sockets, the second is used for the data transfer when doing FTP */ curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */ @@ -888,8 +933,6 @@ struct connectdata { #endif struct ssl_primary_config ssl_config; struct ssl_primary_config proxy_ssl_config; - bool tls_upgraded; - struct ConnectBits bits; /* various state-flags for this connection */ /* connecttime: when connect() is called on the current IP address. Used to @@ -898,8 +941,8 @@ struct connectdata { struct curltime connecttime; /* The two fields below get set in Curl_connecthost */ int num_addr; /* number of addresses to try to connect to */ - time_t timeoutms_per_addr; /* how long time in milliseconds to spend on - trying to connect to each IP address */ + timediff_t timeoutms_per_addr; /* how long time in milliseconds to spend on + trying to connect to each IP address */ const struct Curl_handler *handler; /* Connection's protocol handler */ const struct Curl_handler *given; /* The protocol first given */ @@ -936,7 +979,7 @@ struct connectdata { } allocptr; #ifdef HAVE_GSSAPI - int sec_complete; /* if Kerberos is enabled for this connection */ + BIT(sec_complete); /* if Kerberos is enabled for this connection */ enum protection_level command_prot; enum protection_level data_prot; enum protection_level request_data_prot; @@ -951,30 +994,19 @@ struct connectdata { struct kerberos5data krb5; /* variables into the structure definition, */ #endif /* however, some of them are ftp specific. */ - /* the two following *_inuse fields are only flags, not counters in any way. - If TRUE it means the channel is in use, and if FALSE it means the channel - is up for grabs by one. */ - - bool readchannel_inuse; /* whether the read channel is in use by an easy - handle */ - bool writechannel_inuse; /* whether the write channel is in use by an easy - handle */ - struct curl_llist send_pipe; /* List of handles waiting to send on this - pipeline */ - struct curl_llist recv_pipe; /* List of handles waiting to read their - responses on this pipeline */ - char *master_buffer; /* The master buffer allocated on-demand; - used for pipelining. */ - size_t read_pos; /* Current read position in the master buffer */ - size_t buf_len; /* Length of the buffer?? */ - - + struct curl_llist easyq; /* List of easy handles using this connection */ curl_seek_callback seek_func; /* function that seeks the input */ void *seek_client; /* pointer to pass to the seek() above */ /*************** Request - specific items ************/ +#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) + CtxtHandle *sslContext; +#endif #if defined(USE_NTLM) + curlntlm http_ntlm_state; + curlntlm proxy_ntlm_state; + struct ntlmdata ntlm; /* NTLM differs from other authentication schemes because it authenticates connections, not single requests! */ @@ -989,7 +1021,14 @@ struct connectdata { #endif #endif - char syserr_buf [256]; /* buffer for Curl_strerror() */ +#ifdef USE_SPNEGO + curlnegotiate http_negotiate_state; + curlnegotiate proxy_negotiate_state; + + struct negotiatedata negotiate; /* state data for host Negotiate auth */ + struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ +#endif + /* data used for the asynch name resolve callback */ struct Curl_async async; @@ -1008,7 +1047,8 @@ struct connectdata { struct smtp_conn smtpc; struct rtsp_conn rtspc; struct smb_conn smbc; - void *generic; /* RTMP and LDAP use this */ + void *rtmp; + struct ldapconninfo *ldapc; } proto; int cselect_bits; /* bitmask of socket events */ @@ -1032,8 +1072,16 @@ struct connectdata { #ifdef USE_UNIX_SOCKETS char *unix_domain_socket; - bool abstract_unix_socket; + BIT(abstract_unix_socket); #endif + BIT(tls_upgraded); + /* the two following *_inuse fields are only flags, not counters in any way. + If TRUE it means the channel is in use, and if FALSE it means the channel + is up for grabs by one. */ + BIT(readchannel_inuse); /* whether the read channel is in use by an easy + handle */ + BIT(writechannel_inuse); /* whether the write channel is in use by an easy + handle */ }; /* The end of connectdata. */ @@ -1048,15 +1096,14 @@ struct PureInfo { int httpversion; /* the http version number X.Y = X*10+Y */ time_t filetime; /* If requested, this is might get set. Set to -1 if the time was unretrievable. */ - bool timecond; /* set to TRUE if the time condition didn't match, which - thus made the document NOT get fetched */ - long header_size; /* size of read header(s) in bytes */ - long request_size; /* the amount of bytes sent in the request(s) */ + curl_off_t header_size; /* size of read header(s) in bytes */ + curl_off_t request_size; /* the amount of bytes sent in the request(s) */ unsigned long proxyauthavail; /* what proxy auth types were announced */ unsigned long httpauthavail; /* what host auth types were announced */ long numconnects; /* how many new connection did libcurl created */ char *contenttype; /* the content type of the object */ char *wouldredirect; /* URL this would've been redirected to if asked to */ + curl_off_t retry_after; /* info from Retry-After: header */ /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip' and, 'conn_local_port' are copied over from the connectdata struct in @@ -1068,16 +1115,16 @@ struct PureInfo { char conn_primary_ip[MAX_IPADR_LEN]; long conn_primary_port; - char conn_local_ip[MAX_IPADR_LEN]; long conn_local_port; - const char *conn_scheme; unsigned int conn_protocol; - struct curl_certinfo certs; /* info about the certs, only populated in - OpenSSL builds. Asked for with - CURLOPT_CERTINFO / CURLINFO_CERTINFO */ + OpenSSL, GnuTLS, Schannel, NSS and GSKit + builds. Asked for with CURLOPT_CERTINFO + / CURLINFO_CERTINFO */ + BIT(timecond); /* set to TRUE if the time condition didn't match, which + thus made the document NOT get fetched */ }; @@ -1091,28 +1138,26 @@ struct Progress { curl_off_t current_speed; /* uses the currently fastest transfer */ - bool callback; /* set when progress callback is used */ int width; /* screen width at download start */ int flags; /* see progress.h */ - time_t timespent; + timediff_t timespent; curl_off_t dlspeed; curl_off_t ulspeed; - time_t t_nslookup; - time_t t_connect; - time_t t_appconnect; - time_t t_pretransfer; - time_t t_starttransfer; - time_t t_redirect; + timediff_t t_nslookup; + timediff_t t_connect; + timediff_t t_appconnect; + timediff_t t_pretransfer; + timediff_t t_starttransfer; + timediff_t t_redirect; struct curltime start; struct curltime t_startsingle; struct curltime t_startop; struct curltime t_acceptdata; - bool is_t_startransfer_set; /* upload speed limit */ struct curltime ul_limit_start; @@ -1126,6 +1171,8 @@ struct Progress { curl_off_t speeder[ CURR_TIME ]; struct curltime speeder_time[ CURR_TIME ]; int speeder_c; + BIT(callback); /* set when progress callback is used */ + BIT(is_t_startransfer_set); }; typedef enum { @@ -1137,7 +1184,6 @@ typedef enum { HTTPREQ_PUT, HTTPREQ_HEAD, HTTPREQ_OPTIONS, - HTTPREQ_CUSTOM, HTTPREQ_LAST /* last in list */ } Curl_HttpReq; @@ -1174,12 +1220,12 @@ struct auth { unsigned long picked; unsigned long avail; /* Bitmask for what the server reports to support for this resource */ - bool done; /* TRUE when the auth phase is done and ready to do the *actual* - request */ - bool multipass; /* TRUE if this is not yet authenticated but within the + BIT(done); /* TRUE when the auth phase is done and ready to do the + actual request */ + BIT(multipass); /* TRUE if this is not yet authenticated but within the auth multipass negotiation */ - bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should - be RFC compliant */ + BIT(iestyle); /* TRUE if digest should be done IE-style or FALSE if it + should be RFC compliant */ }; struct Curl_http2_dep { @@ -1206,15 +1252,26 @@ typedef enum { EXPIRE_ASYNC_NAME, EXPIRE_CONNECTTIMEOUT, EXPIRE_DNS_PER_NAME, + EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */ EXPIRE_HAPPY_EYEBALLS, EXPIRE_MULTI_PENDING, EXPIRE_RUN_NOW, EXPIRE_SPEEDCHECK, EXPIRE_TIMEOUT, EXPIRE_TOOFAST, + EXPIRE_QUIC, EXPIRE_LAST /* not an actual timer, used as a marker only */ } expire_id; + +typedef enum { + TRAILERS_NONE, + TRAILERS_INITIALIZED, + TRAILERS_SENDING, + TRAILERS_DONE +} trailers_state; + + /* * One instance for each timeout an easy handle can set. */ @@ -1241,11 +1298,6 @@ struct UrlState { /* Points to the connection cache */ struct conncache *conn_cache; - /* when curl_easy_perform() is called, the multi handle is "owned" by - the easy handle so curl_easy_cleanup() on such an easy handle will - also close the multi handle! */ - bool multi_owned_by_easy; - /* buffers to store authentication data in, as parsed from input options */ struct curltime keeps_speed; /* for the progress meter really */ @@ -1258,8 +1310,6 @@ struct UrlState { char *ulbuf; /* allocated upload buffer or NULL */ curl_off_t current_speed; /* the ProgressShow() function sets this, bytes / second */ - bool this_is_a_follow; /* this is a followed Location: request */ - bool refused_stream; /* this was refused, try again */ char *first_host; /* host name of the first (not followed) request. if set, this should be the host name that we will sent authorization to, no else. Used to make Location: @@ -1272,29 +1322,16 @@ struct UrlState { unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */ struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */ char *scratch; /* huge buffer[set.buffer_size*2] for upload CRLF replacing */ - bool errorbuf; /* Set to TRUE if the error buffer is already filled in. - This must be set to FALSE every time _easy_perform() is - called. */ int os_errno; /* filled in with errno whenever an error occurs */ #ifdef HAVE_SIGNAL /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */ void (*prev_signal)(int sig); #endif - bool allow_port; /* Is set.use_port allowed to take effect or not. This - is always set TRUE when curl_easy_perform() is called. */ struct digestdata digest; /* state data for host Digest auth */ struct digestdata proxydigest; /* state data for proxy Digest auth */ -#ifdef USE_SPNEGO - struct negotiatedata negotiate; /* state data for host Negotiate auth */ - struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ -#endif - struct auth authhost; /* auth details for host */ struct auth authproxy; /* auth details for proxy */ - - bool authproblem; /* TRUE if there's some problem authenticating */ - void *resolver; /* resolver state, if it is used in the URL state - ares_channel f.e. */ @@ -1310,27 +1347,18 @@ struct UrlState { /* a place to store the most recently set FTP entrypath */ char *most_recent_ftp_entrypath; - /* set after initial USER failure, to prevent an authentication loop */ - bool ftp_trying_alternative; - bool wildcardmatch; /* enable wildcard matching */ int httpversion; /* the lowest HTTP version*10 reported by any server involved in this request */ - bool expect100header; /* TRUE if we added Expect: 100-continue */ #if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \ !defined(__SYMBIAN32__) /* do FTP line-end conversions on most platforms */ #define CURL_DO_LINEEND_CONV /* for FTP downloads: track CRLF sequences that span blocks */ - bool prev_block_had_trailing_cr; + BIT(prev_block_had_trailing_cr); /* for FTP downloads: how many CRLFs did we converted to LFs? */ curl_off_t crlf_conversions; #endif - bool slash_removed; /* set TRUE if the 'path' points to a path where the - initial URL slash separator has been taken off */ - bool use_range; - bool rangestringalloc; /* the range string is malloc()'ed */ - char *range; /* range, if used. See README for detailed specification on this syntax. */ curl_off_t resume_from; /* continue [ftp] transfer from here */ @@ -1346,21 +1374,49 @@ struct UrlState { size_t drain; /* Increased when this stream has data to read, even if its socket is not necessarily is readable. Decreased when checked. */ - bool done; /* set to FALSE when Curl_init_do() is called and set to TRUE - when multi_done() is called, to prevent multi_done() to get - invoked twice when the multi interface is used. */ curl_read_callback fread_func; /* read callback/function */ void *in; /* CURLOPT_READDATA */ struct Curl_easy *stream_depends_on; - bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; -#ifdef CURLDEBUG - bool conncache_lock; -#endif CURLU *uh; /* URL handle for the current parsed URL */ struct urlpieces up; +#ifndef CURL_DISABLE_HTTP + size_t trailers_bytes_sent; + Curl_send_buffer *trailers_buf; /* a buffer containing the compiled trailing + headers */ +#endif + trailers_state trailers_state; /* whether we are sending trailers + and what stage are we at */ +#ifdef CURLDEBUG + BIT(conncache_lock); +#endif + /* when curl_easy_perform() is called, the multi handle is "owned" by + the easy handle so curl_easy_cleanup() on such an easy handle will + also close the multi handle! */ + BIT(multi_owned_by_easy); + + BIT(this_is_a_follow); /* this is a followed Location: request */ + BIT(refused_stream); /* this was refused, try again */ + BIT(errorbuf); /* Set to TRUE if the error buffer is already filled in. + This must be set to FALSE every time _easy_perform() is + called. */ + BIT(allow_port); /* Is set.use_port allowed to take effect or not. This + is always set TRUE when curl_easy_perform() is called. */ + BIT(authproblem); /* TRUE if there's some problem authenticating */ + /* set after initial USER failure, to prevent an authentication loop */ + BIT(ftp_trying_alternative); + BIT(wildcardmatch); /* enable wildcard matching */ + BIT(expect100header); /* TRUE if we added Expect: 100-continue */ + BIT(use_range); + BIT(rangestringalloc); /* the range string is malloc()'ed */ + BIT(done); /* set to FALSE when Curl_init_do() is called and set to TRUE + when multi_done() is called, to prevent multi_done() to get + invoked twice when the multi interface is used. */ + BIT(stream_depends_e); /* set or don't set the Exclusive bit */ + BIT(previouslypending); /* this transfer WAS in the multi->pending queue */ + BIT(cookie_engine); }; @@ -1373,13 +1429,15 @@ struct UrlState { struct DynamicStatic { char *url; /* work URL, copied from UserDefined */ - bool url_alloc; /* URL string is malloc()'ed */ char *referer; /* referer string */ - bool referer_alloc; /* referer string is malloc()ed */ struct curl_slist *cookielist; /* list of cookie files set by curl_easy_setopt(COOKIEFILE) calls */ struct curl_slist *resolve; /* set to point to the set.resolve list when this should be dealt with in pretransfer */ + BIT(url_alloc); /* URL string is malloc()'ed */ + BIT(referer_alloc); /* referer string is malloc()ed */ + BIT(wildcard_resolve); /* Set to true if any resolve change is a + wildcard */ }; /* @@ -1449,7 +1507,7 @@ enum dupstring { STRING_RTSP_SESSION_ID, /* Session ID to use */ STRING_RTSP_STREAM_URI, /* Stream URI for this request */ STRING_RTSP_TRANSPORT, /* Transport for this session */ -#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) +#ifdef USE_SSH STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */ STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */ STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */ @@ -1472,6 +1530,13 @@ enum dupstring { #endif STRING_TARGET, /* CURLOPT_REQUEST_TARGET */ STRING_DOH, /* CURLOPT_DOH_URL */ +#ifdef USE_ALTSVC + STRING_ALTSVC, /* CURLOPT_ALTSVC */ +#endif + STRING_SASL_AUTHZID, /* CURLOPT_SASL_AUTHZID */ +#ifndef CURL_DISABLE_PROXY + STRING_TEMP_URL, /* temp URL storage for proxy use */ +#endif /* -- end of zero-terminated strings -- */ STRING_LASTZEROTERMINATED, @@ -1509,8 +1574,6 @@ struct UserDefined { int keep_post; /* keep POSTs as POSTs after a 30x request; each bit represents a request, from 301 to 303 */ - bool free_referer; /* set TRUE if 'referer' points to a string we - allocated */ void *postfields; /* if POST, set the fields' values here */ curl_seek_callback seek_func; /* function that seeks the input */ curl_off_t postfieldsize; /* if POST, this might have a size to use instead @@ -1523,8 +1586,6 @@ struct UserDefined { curl_write_callback fwrite_header; /* function that stores headers */ curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */ curl_read_callback fread_func_set; /* function that reads the input */ - int is_fread_set; /* boolean, has read callback been set to non-NULL? */ - int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */ curl_progress_callback fprogress; /* OLD and deprecated progress callback */ curl_xferinfo_callback fxferinfo; /* progress callback */ curl_debug_callback fdebug; /* function that write informational data */ @@ -1555,8 +1616,9 @@ struct UserDefined { long accepttimeout; /* in milliseconds, 0 means no timeout */ long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */ long server_response_timeout; /* in milliseconds, 0 means no timeout */ + long maxage_conn; /* in seconds, max idle time to allow a connection that + is to be reused */ long tftp_blksize; /* in bytes, 0 means use default */ - bool tftp_no_options; /* do not send TFTP options requests */ curl_off_t filesize; /* size of file to upload, -1 means unknown */ long low_speed_limit; /* bytes/second */ long low_speed_time; /* number of seconds */ @@ -1568,9 +1630,6 @@ struct UserDefined { struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */ struct curl_httppost *httppost; /* linked list of old POST data */ curl_mimepart mimepost; /* MIME/POST data. */ - bool sep_headers; /* handle host and proxy headers separately */ - bool cookiesession; /* new cookie session? */ - bool crlf; /* convert crlf on ftp upload(?) */ struct curl_slist *quote; /* after connection is established */ struct curl_slist *postquote; /* after the transfer */ struct curl_slist *prequote; /* before the transfer, after type */ @@ -1589,7 +1648,6 @@ struct UserDefined { Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ long httpversion; /* when non-zero, a specific HTTP version requested to be used in the library's request(s) */ - bool strip_path_slash; /* strip off initial slash from path */ struct ssl_config_data ssl; /* user defined SSL stuff */ struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */ struct ssl_general_config general_ssl; /* general user defined SSL stuff */ @@ -1599,87 +1657,35 @@ struct UserDefined { size_t upload_buffer_size; /* size of upload buffer to use, keep it >= CURL_MAX_WRITE_SIZE */ void *private_data; /* application-private data */ - struct curl_slist *http200aliases; /* linked list of aliases for http200 */ - long ipver; /* the CURL_IPRESOLVE_* defines in the public header file 0 - whatever, 1 - v2, 2 - v6 */ - curl_off_t max_filesize; /* Maximum file size to download */ - +#ifndef CURL_DISABLE_FTP curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */ - + curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ + curl_ftpccc ftp_ccc; /* FTP CCC options */ +#endif int ftp_create_missing_dirs; /* 1 - create directories that don't exist 2 - the same but also allow MKD to fail once */ - curl_sshkeycallback ssh_keyfunc; /* key matching callback */ void *ssh_keyfunc_userp; /* custom pointer to callback */ - bool ssh_compression; /* enable SSH compression */ - -/* Here follows boolean settings that define how to behave during - this session. They are STATIC, set by libcurl users or at least initially - and they don't change during operations. */ - bool get_filetime; /* get the time and get of the remote file */ - bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */ - bool prefer_ascii; /* ASCII rather than binary */ - bool ftp_append; /* append, not overwrite, on upload */ - bool ftp_list_only; /* switch FTP command for listing directories */ - bool ftp_use_port; /* use the FTP PORT command */ - bool hide_progress; /* don't use the progress meter */ - bool http_fail_on_error; /* fail on HTTP error codes >= 400 */ - bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */ - bool http_follow_location; /* follow HTTP redirects */ - bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */ - bool allow_auth_to_other_hosts; - bool include_header; /* include received protocol headers in data output */ - bool http_set_referer; /* is a custom referer used */ - bool http_auto_referer; /* set "correct" referer when following location: */ - bool opt_no_body; /* as set with CURLOPT_NOBODY */ - bool upload; /* upload request */ enum CURL_NETRC_OPTION use_netrc; /* defined in include/curl.h */ - bool verbose; /* output verbosity */ - bool krb; /* Kerberos connection requested */ - bool reuse_forbid; /* forbidden to be reused, close after use */ - bool reuse_fresh; /* do not re-use an existing connection */ - bool ftp_use_epsv; /* if EPSV is to be attempted or not */ - bool ftp_use_eprt; /* if EPRT is to be attempted or not */ - bool ftp_use_pret; /* if PRET is to be used before PASV or not */ - curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or IMAP or POP3 or others! */ - curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ - curl_ftpccc ftp_ccc; /* FTP CCC options */ - bool no_signal; /* do not use any signal/alarm handler */ - bool global_dns_cache; /* subject for future removal */ - bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */ - bool ignorecl; /* ignore content length */ - bool ftp_skip_ip; /* skip the IP address the FTP server passes on to - us */ - bool connect_only; /* make connection, let application use the socket */ - long ssh_auth_types; /* allowed SSH auth types */ - bool http_te_skip; /* pass the raw body data to the user, even when - transfer-encoded (chunked, compressed) */ - bool http_ce_skip; /* pass the raw body data to the user, even when - content-encoded (chunked, compressed) */ long new_file_perms; /* Permissions to use when creating remote files */ long new_directory_perms; /* Permissions to use when creating remote dirs */ - bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP - via an HTTP proxy */ + long ssh_auth_types; /* allowed SSH auth types */ char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */ unsigned int scope_id; /* Scope id for IPv6 */ long allowed_protocols; long redir_protocols; -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - bool socks5_gssapi_nec; /* Flag to support NEC SOCKS5 server */ -#endif struct curl_slist *mail_rcpt; /* linked list of mail recipients */ - bool sasl_ir; /* Enable/disable SASL initial response */ /* Common RTSP header options */ Curl_RtspReq rtspreq; /* RTSP request type */ long rtspversion; /* like httpversion, for RTSP */ - bool wildcard_enabled; /* enable wildcard matching */ curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer starts */ curl_chunk_end_callback chunk_end; /* called after part transferring @@ -1691,50 +1697,107 @@ struct UserDefined { long gssapi_delegation; /* GSS-API credential delegation, see the documentation of CURLOPT_GSSAPI_DELEGATION */ - bool tcp_keepalive; /* use TCP keepalives */ long tcp_keepidle; /* seconds in idle before sending keepalive probe */ long tcp_keepintvl; /* seconds between TCP keepalive probes */ - bool tcp_fastopen; /* use TCP Fast Open */ - size_t maxconnects; /* Max idle connections in the connection cache */ + size_t maxconnects; /* Max idle connections in the connection cache */ - bool ssl_enable_npn; /* TLS NPN extension? */ - bool ssl_enable_alpn; /* TLS ALPN extension? */ - bool path_as_is; /* allow dotdots? */ - bool pipewait; /* wait for pipe/multiplex status before starting a - new connection */ long expect_100_timeout; /* in milliseconds */ - bool suppress_connect_headers; /* suppress proxy CONNECT response headers - from user callbacks */ - - bool dns_shuffle_addresses; /* whether to shuffle addresses before use */ - struct Curl_easy *stream_depends_on; - bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; - - bool haproxyprotocol; /* whether to send HAProxy PROXY protocol v1 header */ - struct Curl_http2_dep *stream_dependents; - bool abstract_unix_socket; - curl_resolver_start_callback resolver_start; /* optional callback called before resolver start */ void *resolver_start_client; /* pointer to pass to resolver start callback */ - bool disallow_username_in_url; /* disallow username in url */ long upkeep_interval_ms; /* Time between calls for connection upkeep. */ - bool doh; /* DNS-over-HTTPS enabled */ - bool doh_get; /* use GET for DoH requests, instead of POST */ multidone_func fmultidone; struct Curl_easy *dohfor; /* this is a DoH request for that transfer */ + CURLU *uh; /* URL handle for the current parsed URL */ + void *trailer_data; /* pointer to pass to trailer data callback */ + curl_trailer_callback trailer_callback; /* trailing data callback */ + BIT(is_fread_set); /* has read callback been set to non-NULL? */ + BIT(is_fwrite_set); /* has write callback been set to non-NULL? */ + BIT(free_referer); /* set TRUE if 'referer' points to a string we + allocated */ + BIT(tftp_no_options); /* do not send TFTP options requests */ + BIT(sep_headers); /* handle host and proxy headers separately */ + BIT(cookiesession); /* new cookie session? */ + BIT(crlf); /* convert crlf on ftp upload(?) */ + BIT(strip_path_slash); /* strip off initial slash from path */ + BIT(ssh_compression); /* enable SSH compression */ + +/* Here follows boolean settings that define how to behave during + this session. They are STATIC, set by libcurl users or at least initially + and they don't change during operations. */ + BIT(get_filetime); /* get the time and get of the remote file */ + BIT(tunnel_thru_httpproxy); /* use CONNECT through a HTTP proxy */ + BIT(prefer_ascii); /* ASCII rather than binary */ + BIT(ftp_append); /* append, not overwrite, on upload */ + BIT(ftp_list_only); /* switch FTP command for listing directories */ +#ifndef CURL_DISABLE_FTP + BIT(ftp_use_port); /* use the FTP PORT command */ + BIT(ftp_use_epsv); /* if EPSV is to be attempted or not */ + BIT(ftp_use_eprt); /* if EPRT is to be attempted or not */ + BIT(ftp_use_pret); /* if PRET is to be used before PASV or not */ + BIT(ftp_skip_ip); /* skip the IP address the FTP server passes on to + us */ +#endif + BIT(hide_progress); /* don't use the progress meter */ + BIT(http_fail_on_error); /* fail on HTTP error codes >= 400 */ + BIT(http_keep_sending_on_error); /* for HTTP status codes >= 300 */ + BIT(http_follow_location); /* follow HTTP redirects */ + BIT(http_transfer_encoding); /* request compressed HTTP transfer-encoding */ + BIT(allow_auth_to_other_hosts); + BIT(include_header); /* include received protocol headers in data output */ + BIT(http_set_referer); /* is a custom referer used */ + BIT(http_auto_referer); /* set "correct" referer when following + location: */ + BIT(opt_no_body); /* as set with CURLOPT_NOBODY */ + BIT(upload); /* upload request */ + BIT(verbose); /* output verbosity */ + BIT(krb); /* Kerberos connection requested */ + BIT(reuse_forbid); /* forbidden to be reused, close after use */ + BIT(reuse_fresh); /* do not re-use an existing connection */ + BIT(no_signal); /* do not use any signal/alarm handler */ + BIT(tcp_nodelay); /* whether to enable TCP_NODELAY or not */ + BIT(ignorecl); /* ignore content length */ + BIT(connect_only); /* make connection, let application use the socket */ + BIT(http_te_skip); /* pass the raw body data to the user, even when + transfer-encoded (chunked, compressed) */ + BIT(http_ce_skip); /* pass the raw body data to the user, even when + content-encoded (chunked, compressed) */ + BIT(proxy_transfer_mode); /* set transfer mode (;type=<a|i>) when doing + FTP via an HTTP proxy */ +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + BIT(socks5_gssapi_nec); /* Flag to support NEC SOCKS5 server */ +#endif + BIT(sasl_ir); /* Enable/disable SASL initial response */ + BIT(wildcard_enabled); /* enable wildcard matching */ + BIT(tcp_keepalive); /* use TCP keepalives */ + BIT(tcp_fastopen); /* use TCP Fast Open */ + BIT(ssl_enable_npn); /* TLS NPN extension? */ + BIT(ssl_enable_alpn);/* TLS ALPN extension? */ + BIT(path_as_is); /* allow dotdots? */ + BIT(pipewait); /* wait for multiplex status before starting a new + connection */ + BIT(suppress_connect_headers); /* suppress proxy CONNECT response headers + from user callbacks */ + BIT(dns_shuffle_addresses); /* whether to shuffle addresses before use */ + BIT(stream_depends_e); /* set or don't set the Exclusive bit */ + BIT(haproxyprotocol); /* whether to send HAProxy PROXY protocol v1 + header */ + BIT(abstract_unix_socket); + BIT(disallow_username_in_url); /* disallow username in url */ + BIT(doh); /* DNS-over-HTTPS enabled */ + BIT(doh_get); /* use GET for DoH requests, instead of POST */ + BIT(http09_allowed); /* allow HTTP/0.9 responses */ }; struct Names { struct curl_hash *hostcache; enum { HCACHE_NONE, /* not pointing to anything */ - HCACHE_GLOBAL, /* points to the (shrug) global one */ HCACHE_MULTI, /* points to a shared one in the multi handle */ HCACHE_SHARED /* points to a shared one in a shared object */ } hostcachetype; @@ -1755,9 +1818,9 @@ struct Curl_easy { struct Curl_easy *next; struct Curl_easy *prev; - struct connectdata *easy_conn; /* the "unit's" connection */ + struct connectdata *conn; struct curl_llist_element connect_queue; - struct curl_llist_element pipeline_queue; + struct curl_llist_element conn_queue; /* list per connectdata */ CURLMstate mstate; /* the handle's state */ CURLcode result; /* previous result */ @@ -1769,6 +1832,8 @@ struct Curl_easy { the state etc are also kept. This array is mostly used to detect when a socket is to be removed from the hash. See singlesocket(). */ curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE]; + int actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in + sockets[] */ int numsocks; struct Names dns; @@ -1789,10 +1854,15 @@ struct Curl_easy { NOTE that the 'cookie' field in the UserDefined struct defines if the "engine" is to be used or not. */ +#ifdef USE_ALTSVC + struct altsvcinfo *asi; /* the alt-svc cache */ +#endif struct Progress progress; /* for all the progress meter data */ struct UrlState state; /* struct for fields used for state info and other dynamic purposes */ +#ifndef CURL_DISABLE_FTP struct WildcardData wildcard; /* wildcard download state info */ +#endif struct PureInfo info; /* stats, reports and info data */ struct curl_tlssessioninfo tsi; /* Information about the TLS session, only valid after a client has asked for it */ |