summaryrefslogtreecommitdiff
path: root/lib/urldata.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/urldata.h')
-rw-r--r--lib/urldata.h230
1 files changed, 164 insertions, 66 deletions
diff --git a/lib/urldata.h b/lib/urldata.h
index cee3af631..bce51e971 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -333,25 +333,33 @@ typedef enum {
FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the file */
} curl_ftpfile;
+/* This FTP struct is used in the SessionHandle. All FTP data that is
+ connection-oriented must be in FTP_conn to properly deal with the fact that
+ perhaps the SessionHandle is changed between the times the connection is
+ used. */
struct FTP {
curl_off_t *bytecountp;
char *user; /* user name string */
char *passwd; /* password string */
char *urlpath; /* the originally given path part of the URL */
- char **dirs; /* realloc()ed array for path components */
- int dirdepth; /* number of entries used in the 'dirs' array */
- int diralloc; /* number of entries allocated for the 'dirs' array */
char *file; /* decoded file */
+ bool no_transfer; /* nothing was transfered, (possibly because a resumed
+ transfer already was complete) */
+ curl_off_t downloadsize;
+};
+/* ftp_conn is used for striuct connection-oriented data in the connectdata
+ struct */
+struct ftp_conn {
char *entrypath; /* the PWD reply when we logged on */
-
+ char **dirs; /* realloc()ed array for path components */
+ int dirdepth; /* number of entries used in the 'dirs' array */
+ int diralloc; /* number of entries allocated for the 'dirs' array */
char *cache; /* data cache between getresponse()-calls */
curl_off_t cache_size; /* size of cache in bytes */
bool dont_check; /* Set to TRUE to prevent the final (post-transfer)
file size and 226/250 status check. It should still
read the line, just ignore the result. */
- bool no_transfer; /* nothing was transfered, (possibly because a resumed
- transfer already was complete) */
long response_time; /* When no timeout is given, this is the amount of
seconds we await for an FTP response. Initialized
in Curl_ftp_connect() */
@@ -365,7 +373,6 @@ struct FTP {
char *prevpath; /* conn->path from the previous transfer */
char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
and others (A/I or zero) */
-
size_t nread_resp; /* number of bytes currently read of a server response */
char *linestart_resp; /* line start pointer for the FTP server response
reader function */
@@ -380,7 +387,6 @@ struct FTP {
struct timeval response; /* set to Curl_tvnow() when a command has been sent
off, used to time-out response reading */
ftpstate state; /* always use ftp.c:state() to change state! */
- curl_off_t downloadsize;
};
/****************************************************************************
@@ -406,8 +412,6 @@ struct ConnectBits {
bool 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 use_range;
- bool rangestringalloc; /* the range string is malloc()'ed */
bool do_more; /* this is set TRUE if the ->curl_do_more() function is
supposed to be called, after ->curl_do() */
@@ -456,6 +460,8 @@ struct ConnectBits {
when Curl_done() is called, to prevent Curl_done() to
get invoked twice when the multi interface is
used. */
+ bool stream_was_rewound; /* Indicates that the stream was rewound after a request
+ read past the end of its response byte boundary */
};
struct hostname {
@@ -466,14 +472,44 @@ struct hostname {
};
/*
+ * Flags on the keepon member of the Curl_transfer_keeper
+ */
+enum {
+ KEEP_NONE,
+ KEEP_READ,
+ KEEP_WRITE
+};
+
+
+/*
* This struct is all the previously local variables from Curl_perform() moved
* to struct to allow the function to return and get re-invoked better without
* losing state.
*/
struct Curl_transfer_keeper {
+
+ /** Values copied over from the HandleData struct each time on init **/
+
+ 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, 0
+ means unlimited */
+ curl_off_t *writebytecountp; /* return number of bytes written or NULL */
+
+ /** End of HandleData struct copies **/
+
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 transfered 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 timeval start; /* transfer started at this time */
struct timeval now; /* current time */
bool header; /* incoming data has HTTP header */
@@ -555,18 +591,83 @@ struct Curl_async {
typedef CURLcode (*Curl_do_more_func)(struct connectdata *);
typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode);
+
+/*
+ * Store's request specific data in the easy handle (SessionHandle).
+ * Previously, these members were on the connectdata struct but since
+ * a conn struct may now be shared between different SessionHandles,
+ * we store connection-specifc data here.
+ *
+ */
+struct HandleData {
+ char *pathbuffer;/* allocated buffer to store the URL's path part in */
+ char *path; /* path to use, points to somewhere within the pathbuffer
+ area */
+
+ char *newurl; /* This can only be set if a Location: was in the
+ document headers */
+
+ /* This struct is inited when needed */
+ struct Curl_transfer_keeper keep;
+
+ /* 'upload_present' is used to keep a byte counter of how much data there is
+ 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 */
+ char *upload_fromhere;
+
+ 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, 0
+ means unlimited */
+ curl_off_t *writebytecountp; /* return number of bytes written or NULL */
+
+ 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 */
+
+ /* Protocol specific data */
+
+ union {
+ struct HTTP *http;
+ struct HTTP *https; /* alias, just for the sake of being more readable */
+ struct FTP *ftp;
+ void *tftp; /* private for tftp.c-eyes only */
+ struct FILEPROTO *file;
+ void *telnet; /* private for telnet.c-eyes only */
+ void *generic;
+ } proto;
+};
+
/*
* The connectdata struct contains all fields and variables that should be
* unique for an entire connection.
*/
struct connectdata {
- /**** Fields set when inited and not modified again */
- struct SessionHandle *data; /* link to the root CURL struct */
- long connectindex; /* what index in the connects index this particular
- struct has */
+ /* 'data' is the CURRENT SessionHandle using this connection -- take great
+ caution that this might very well vary between different times this
+ connection is used! */
+ struct SessionHandle *data;
+
+ bool inuse; /* This is a marker for the connection cache logic. If this is
+ TRUE this handle is being used by an easy handle and cannot
+ be used by any other easy handle without careful
+ consideration (== only for pipelining). */
+ /**** Fields set when inited and not modified again */
+ long connectindex; /* what index in the connection cache connects index this
+ particular struct has */
long protocol; /* PROT_* flags concerning the protocol set */
#define PROT_MISSING (1<<0)
+#define PROT_CLOSEACTION (1<<1) /* needs action before socket close */
#define PROT_HTTP (1<<2)
#define PROT_HTTPS (1<<3)
#define PROT_FTP (1<<4)
@@ -574,9 +675,9 @@ struct connectdata {
#define PROT_DICT (1<<6)
#define PROT_LDAP (1<<7)
#define PROT_FILE (1<<8)
-#define PROT_TFTP (1<<11)
#define PROT_FTPS (1<<9)
#define PROT_SSL (1<<10) /* protocol requires SSL */
+#define PROT_TFTP (1<<11)
/* 'dns_entry' is the particular host we use. This points to an entry in the
DNS cache and it will not get pruned while locked. It gets unlocked in
@@ -600,23 +701,9 @@ struct connectdata {
struct hostname host;
struct hostname proxy;
- char *pathbuffer;/* allocated buffer to store the URL's path part in */
- char *path; /* path to use, points to somewhere within the pathbuffer
- area */
long port; /* which port to use locally */
unsigned short remote_port; /* what remote port to connect to,
not the proxy port! */
- curl_off_t bytecount;
- long headerbytecount; /* only count received headers */
- long deductheadercount; /* this amount of bytes doesn't count when we check
- if anything has been transfered 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 */
-
- char *range; /* range, if used. See README for detailed specification on
- this syntax. */
- curl_off_t resume_from; /* continue [ftp] transfer from here */
char *user; /* user name string, allocated */
char *passwd; /* password string, allocated */
@@ -628,8 +715,6 @@ struct connectdata {
struct timeval created; /* creation time */
curl_socket_t sock[2]; /* two sockets, the second is used for the data
transfer when doing FTP */
- curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, 0
- means unlimited */
struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
struct ssl_config_data ssl_config;
@@ -683,16 +768,10 @@ struct connectdata {
/**** curl_get() phase fields */
- /* READ stuff */
curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */
- curl_off_t size; /* -1 if unknown at this point */
- curl_off_t *bytecountp; /* return number of bytes read or NULL */
-
- /* WRITE stuff */
curl_socket_t writesockfd; /* socket to write to, it may very
well be the same we read from.
CURL_SOCKET_BAD disables */
- curl_off_t *writebytecountp; /* return number of bytes written or NULL */
/** Dynamicly allocated strings, may need to be freed before this **/
/** struct is killed. **/
@@ -707,9 +786,6 @@ struct connectdata {
char *cookiehost; /* free later if not NULL */
} allocptr;
- char *newurl; /* This can only be set if a Location: was in the
- document headers */
-
int sec_complete; /* if krb4 is enabled for this connection */
#ifdef HAVE_KRB4
enum protection_level command_prot;
@@ -722,31 +798,23 @@ struct connectdata {
struct sockaddr_in local_addr;
#endif
- /*************** Request - specific items ************/
- /* previously this was in the urldata struct */
- union {
- struct HTTP *http;
- struct HTTP *https; /* alias, just for the sake of being more readable */
- struct FTP *ftp;
- void *tftp; /* private for tftp.c-eyes only */
- struct FILEPROTO *file;
- void *telnet; /* private for telnet.c-eyes only */
- void *generic;
- } proto;
+ 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 */
+ bool is_in_pipeline; /* TRUE if this connection is in a pipeline */
- /* This struct is inited when needed */
- struct Curl_transfer_keeper keep;
+ 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 */
- /* 'upload_present' is used to keep a byte counter of how much data there is
- still left in the buffer, aimed for upload. */
- ssize_t upload_present;
+ char master_buffer[BUFSIZE]; /* The master buffer for this connection. */
+ size_t read_pos;
+ size_t buf_len;
- /* '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;
+ /*************** Request - specific items ************/
+
+ /* previously this was in the urldata struct */
curl_read_callback fread; /* function that reads the input */
void *fread_in; /* pointer to pass to the fread() above */
@@ -762,8 +830,11 @@ struct connectdata {
/* data used for the asynch name resolve callback */
struct Curl_async async;
#endif
+
struct connectdata *sec_conn; /* secondary connection for 3rd party
transfer */
+ char *sec_path; /* The source path for FTP 3rd party */
+ char *sec_pathbuffer;
enum { NORMAL, SOURCE3RD, TARGET3RD } xfertype;
@@ -772,6 +843,9 @@ struct connectdata {
int trlMax; /* allocated buffer size */
int trlPos; /* index of where to store data */
+ union {
+ struct ftp_conn ftpc;
+ } proto;
};
/* The end of connectdata. */
@@ -870,6 +944,18 @@ struct auth {
};
+struct conncache {
+ /* 'connects' will be an allocated array with pointers. If the pointer is
+ set, it holds an allocated connection. */
+ struct connectdata **connects;
+ long num; /* size of the 'connects' array */
+ enum {
+ CONNCACHE_PRIVATE, /* used for an easy handle alone */
+ CONNCACHE_MULTI /* shared within a multi handle */
+ } type;
+};
+
+
struct UrlState {
enum {
Curl_if_none,
@@ -877,13 +963,12 @@ struct UrlState {
Curl_if_multi
} used_interface;
+ struct conncache *connc; /* points to the connection cache this handle
+ uses */
+
/* buffers to store authentication data in, as parsed from input options */
struct timeval keeps_speed; /* for the progress meter really */
- /* 'connects' will be an allocated array with pointers. If the pointer is
- set, it holds an allocated connection. */
- struct connectdata **connects;
- long numconnects; /* size of the 'connects' array */
long lastconnect; /* index of most recent connect or -1 if undefined */
char *headerbuff; /* allocated buffer to store headers in */
@@ -895,6 +980,8 @@ struct UrlState {
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
+ bool is_in_pipeline; /* Indicates whether this handle is part of a pipeline */
+
char *first_host; /* if set, this should be the host name that we will
sent authorization to, no else. Used to make Location:
following not keep sending user+password... This is
@@ -927,6 +1014,7 @@ struct UrlState {
struct auth authproxy;
bool authproblem; /* TRUE if there's some problem authenticating */
+
#ifdef USE_ARES
ares_channel areschannel; /* for name resolves */
#endif
@@ -945,6 +1033,10 @@ struct UrlState {
bool expect100header; /* TRUE if we added Expect: 100-continue */
+ bool pipe_broke; /* TRUE if the connection we were pipelined on broke
+ and we need to restart from the beginning */
+ bool cancelled; /* TRUE if the request was cancelled */
+
#ifndef WIN32
/* do FTP line-end conversions on most platforms */
#define CURL_DO_LINEEND_CONV
@@ -953,6 +1045,11 @@ struct UrlState {
/* for FTP downloads: how many CRLFs did we converted to LFs? */
curl_off_t crlf_conversions;
#endif
+ /* If set to non-NULL, there's a connection in a shared connection cache
+ that uses this handle so we can't kill this SessionHandle just yet but
+ must keep it around and add it to the list of handles to kill once all
+ its connections are gone */
+ void *shared_conn;
};
@@ -1179,8 +1276,9 @@ struct Names {
struct SessionHandle {
struct Names dns;
struct Curl_multi *multi; /* if non-NULL, points to the multi handle
- struct of which this "belongs" */
+ struct to which this "belongs" */
struct Curl_share *share; /* Share, handles global variable mutexing */
+ struct HandleData reqdata; /* Request-specific data */
struct UserDefined set; /* values set by the libcurl user */
struct DynamicStatic change; /* possibly modified userdefined data */