be posted in a minute to the libcurl list.
char *nthdef = NULL; /* This is not part of the protocol, but required
by RFC 2229 */
CURLcode result=CURLE_OK;
- struct UrlData *data=conn->data;
+ struct SessionHandle *data=conn->data;
char *path = conn->path;
long *bytecount = &conn->bytecount;
CURL *curl_easy_init(void)
{
CURLcode res;
- struct UrlData *data;
+ struct SessionHandle *data;
/* Make sure we inited the global SSL stuff */
if (!initialized)
if(res != CURLE_OK)
return NULL;
- /* SAC */
- data->device = NULL;
-
return data;
}
func_T param_func = (func_T)0;
long param_long = 0;
void *param_obj = NULL;
- struct UrlData *data = curl;
+ struct SessionHandle *data = curl;
va_start(arg, tag);
CURLcode curl_easy_perform(CURL *curl)
{
- struct UrlData *data = (struct UrlData *)curl;
+ struct SessionHandle *data = (struct SessionHandle *)curl;
return Curl_perform(data);
}
void curl_easy_cleanup(CURL *curl)
{
- struct UrlData *data = (struct UrlData *)curl;
+ struct SessionHandle *data = (struct SessionHandle *)curl;
Curl_close(data);
}
{
va_list arg;
void *paramp;
- struct UrlData *data = (struct UrlData *)curl;
+ struct SessionHandle *data = (struct SessionHandle *)curl;
va_start(arg, info);
paramp = va_arg(arg, void *);
struct stat statbuf;
ssize_t expected_size=-1;
ssize_t nread;
- struct UrlData *data = conn->data;
- char *buf = data->buffer;
+ struct SessionHandle *data = conn->data;
+ char *buf = data->state.buffer;
int bytecount = 0;
struct timeval start = Curl_tvnow();
struct timeval now = start;
/* easy-to-use macro: */
#define ftpsendf Curl_ftpsendf
-static CURLcode AllowServerConnect(struct UrlData *data,
+static CURLcode AllowServerConnect(struct SessionHandle *data,
struct connectdata *conn,
int sock)
{
struct timeval interval;
fd_set rkeepfd;
fd_set readfd;
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
char *line_start;
int code=0; /* default "error code" to return */
if(ftpcode)
*ftpcode=0; /* 0 for errors */
- if(data->timeout) {
+ if(data->set.timeout) {
/* if timeout is requested, find out how much remaining time we have */
- timeout = data->timeout - /* timeout time */
+ timeout = data->set.timeout - /* timeout time */
(Curl_tvlong(Curl_tvnow()) - Curl_tvlong(conn->now)); /* spent time */
if(timeout <=0 ) {
failf(data, "Transfer aborted due to timeout");
the line isn't really terminated until the LF comes */
/* output debug output if that is requested */
- if(data->bits.verbose) {
- fputs("< ", data->err);
- fwrite(line_start, perline, 1, data->err);
+ if(data->set.verbose) {
+ fputs("< ", data->set.err);
+ fwrite(line_start, perline, 1, data->set.err);
/* no need to output LF here, it is part of the data */
}
{
/* this is FTP and no proxy */
int nread;
- struct UrlData *data=conn->data;
- char *buf = data->buffer; /* this is our buffer */
+ struct SessionHandle *data=conn->data;
+ char *buf = data->state.buffer; /* this is our buffer */
struct FTP *ftp;
CURLcode result;
int ftpcode;
/* get some initial data into the ftp struct */
ftp->bytecountp = &conn->bytecount;
- /* duplicate to keep them even when the data struct changes */
- ftp->user = strdup(data->user);
- ftp->passwd = strdup(data->passwd);
+ /* no need to duplicate them, the data struct won't change */
+ ftp->user = data->state.user;
+ ftp->passwd = data->state.passwd;
- if (data->bits.tunnel_thru_httpproxy) {
+ if (data->set.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket,
conn->hostname, conn->remote_port);
#ifdef KRB4
/* if not anonymous login, try a secure login */
- if(data->bits.krb4) {
+ if(data->set.krb4) {
/* request data protection level (default is 'clear') */
Curl_sec_request_prot(conn, "private");
/* We set private first as default, in case the line below fails to
set a valid level */
- Curl_sec_request_prot(conn, data->krb4_level);
+ Curl_sec_request_prot(conn, data->set.krb4_level);
if(Curl_sec_login(conn) != 0)
infof(data, "Logging in with password in cleartext!\n");
/* we may need to issue a KAUTH here to have access to the files
* do it if user supplied a password
*/
- if(conn->data->passwd && *conn->data->passwd)
+ if(conn->data->set.passwd && *conn->data->set.passwd)
Curl_krb_kauth(conn);
#endif
}
/* argument is already checked for validity */
CURLcode Curl_ftp_done(struct connectdata *conn)
{
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
struct FTP *ftp = conn->proto.ftp;
ssize_t nread;
- char *buf = data->buffer; /* this is our buffer */
+ char *buf = data->state.buffer; /* this is our buffer */
int ftpcode;
- if(data->bits.upload) {
- if((-1 != data->infilesize) && (data->infilesize != *ftp->bytecountp)) {
+ if(data->set.upload) {
+ if((-1 != data->set.infilesize) && (data->set.infilesize != *ftp->bytecountp)) {
failf(data, "Wrote only partial file (%d out of %d bytes)",
- *ftp->bytecountp, data->infilesize);
+ *ftp->bytecountp, data->set.infilesize);
return CURLE_PARTIAL_FILE;
}
}
return CURLE_PARTIAL_FILE;
}
else if(!conn->bits.resume_done &&
- !data->bits.no_body &&
+ !data->set.no_body &&
(0 == *ftp->bytecountp)) {
failf(data, "No data was received!");
return CURLE_FTP_COULDNT_RETR_FILE;
sclose(conn->secondarysocket);
conn->secondarysocket = -1;
- if(!data->bits.no_body && !conn->bits.resume_done) {
+ if(!data->set.no_body && !conn->bits.resume_done) {
/* now let's see what the server says about the transfer we
just performed: */
nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode);
conn->bits.resume_done = FALSE; /* clean this for next connection */
/* Send any post-transfer QUOTE strings? */
- if(data->postquote) {
- CURLcode result = _ftp_sendquote(conn, data->postquote);
+ if(data->set.postquote) {
+ CURLcode result = _ftp_sendquote(conn, data->set.postquote);
return result;
}
ftpsendf(conn->firstsocket, conn, "%s", item->data);
nread = Curl_GetFTPResponse(conn->firstsocket,
- conn->data->buffer, conn, &ftpcode);
+ conn->data->state.buffer, conn, &ftpcode);
if (nread < 0)
return CURLE_OPERATION_TIMEOUTED;
ftpsendf(conn->firstsocket, conn, "CWD %s", path);
nread = Curl_GetFTPResponse(conn->firstsocket,
- conn->data->buffer, conn, &ftpcode);
+ conn->data->state.buffer, conn, &ftpcode);
if (nread < 0)
return CURLE_OPERATION_TIMEOUTED;
CURLcode result=CURLE_OK;
int ftpcode; /* for ftp status */
ssize_t nread;
- char *buf = conn->data->buffer;
+ char *buf = conn->data->state.buffer;
/* we have requested to get the modified-time of the file, this is yet
again a grey area as the MDTM is not kosher RFC959 */
sprintf(buf, "%04d%02d%02d %02d:%02d:%02d",
year, month, day, hour, minute, second);
/* now, convert this into a time() value: */
- conn->data->progress.filetime = curl_getdate(buf, &secs);
+ conn->data->info.filetime = curl_getdate(buf, &secs);
}
else {
infof(conn->data, "unsupported MDTM reply format\n");
static CURLcode _ftp_transfertype(struct connectdata *conn,
bool ascii)
{
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
int ftpcode;
ssize_t nread;
- char *buf=data->buffer;
+ char *buf=data->state.buffer;
ftpsendf(conn->firstsocket, conn, "TYPE %s", ascii?"A":"I");
CURLcode _ftp_getsize(struct connectdata *conn, char *file,
ssize_t *size)
{
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
int ftpcode;
ssize_t nread;
- char *buf=data->buffer;
+ char *buf=data->state.buffer;
ftpsendf(conn->firstsocket, conn, "SIZE %s", file);
nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode);
/* this is FTP and no proxy */
ssize_t nread;
CURLcode result;
- struct UrlData *data=conn->data;
- char *buf = data->buffer; /* this is our buffer */
+ struct SessionHandle *data=conn->data;
+ char *buf = data->state.buffer; /* this is our buffer */
/* for the ftp PORT mode */
int portsock=-1;
#if defined (HAVE_INET_NTOA_R)
int ftpcode; /* for ftp status */
/* Send any QUOTE strings? */
- if(data->quote) {
- if ((result = _ftp_sendquote(conn, data->quote)) != CURLE_OK)
+ if(data->set.quote) {
+ if ((result = _ftp_sendquote(conn, data->set.quote)) != CURLE_OK)
return result;
}
}
/* Requested time of file? */
- if(data->bits.get_filetime && ftp->file) {
+ if(data->set.get_filetime && ftp->file) {
result = _ftp_getfiletime(conn, ftp->file);
if(result)
return result;
/* If we have selected NOBODY, it means that we only want file information.
Which in FTP can't be much more than the file size! */
- if(data->bits.no_body) {
+ if(data->set.no_body) {
/* The SIZE command is _not_ RFC 959 specified, and therefor many servers
may not support it! It is however the only way we have to get a file's
size! */
/* Some servers return different sizes for different modes, and thus we
must set the proper type before we check the size */
- result = _ftp_transfertype(conn, data->bits.ftp_ascii);
+ result = _ftp_transfertype(conn, data->set.ftp_ascii);
if(result)
return result;
well, we "emulate" a HTTP-style header in our output. */
#ifdef HAVE_STRFTIME
- if(data->bits.get_filetime && data->progress.filetime) {
+ if(data->set.get_filetime && data->info.filetime) {
struct tm *tm;
#ifdef HAVE_LOCALTIME_R
struct tm buffer;
- tm = (struct tm *)localtime_r(&data->progress.filetime, &buffer);
+ tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
#else
- tm = localtime(&data->progress.filetime);
+ tm = localtime(&data->info.filetime);
#endif
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S %Z\r\n",
}
/* We have chosen to use the PORT command */
- if(data->bits.ftp_use_port) {
+ if(data->set.ftp_use_port) {
#ifdef ENABLE_IPV6
struct addrinfo hints, *res, *ai;
struct sockaddr_storage ss;
unsigned short porttouse;
char myhost[256] = "";
- if(data->ftpport) {
- if(Curl_if2ip(data->ftpport, myhost, sizeof(myhost))) {
+ if(data->set.ftpport) {
+ if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
h = Curl_gethost(data, myhost, &hostdataptr);
}
else {
- if(strlen(data->ftpport)>1)
- h = Curl_gethost(data, data->ftpport, &hostdataptr);
+ if(strlen(data->set.ftpport)>1)
+ h = Curl_gethost(data, data->set.ftpport, &hostdataptr);
if(h)
- strcpy(myhost, data->ftpport); /* buffer overflow risk */
+ strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
}
}
if(! *myhost) {
sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
newport = (port[0]<<8) + port[1];
- if(data->bits.httpproxy) {
+ if(data->change.proxy) {
/*
* This is a tunnel through a http proxy and we need to connect to the
* proxy again here. We already have the name info for it since the
if (conn->secondarysocket < 0)
continue;
- if(data->bits.verbose) {
+ if(data->set.verbose) {
char hbuf[NI_MAXHOST];
char nbuf[NI_MAXHOST];
char sbuf[NI_MAXSERV];
serv_addr.sin_port = htons(connectport);
- if(data->bits.verbose) {
+ if(data->set.verbose) {
struct in_addr in;
struct hostent * answer;
}
#endif /*ENABLE_IPV6*/
- if (data->bits.tunnel_thru_httpproxy) {
+ if (data->set.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket,
newhost, newport);
/* we have the (new) data connection ready */
infof(data, "Connected the data stream!\n");
- if(data->bits.upload) {
+ if(data->set.upload) {
/* Set type to binary (unless specified ASCII) */
- result = _ftp_transfertype(conn, data->bits.ftp_ascii);
+ result = _ftp_transfertype(conn, data->set.ftp_ascii);
if(result)
return result;
/* do we still game? */
int passed=0;
/* enable append instead */
- data->bits.ftp_append = 1;
+ data->set.ftp_append = 1;
/* Now, let's read off the proper amount of bytes from the
input. If we knew it was a proper file we could've just
readthisamountnow = BUFSIZE;
actuallyread =
- data->fread(data->buffer, 1, readthisamountnow, data->in);
+ data->set.fread(data->state.buffer, 1, readthisamountnow,
+ data->set.in);
passed += actuallyread;
if(actuallyread != readthisamountnow) {
while(passed != conn->resume_from);
/* now, decrease the size of the read */
- if(data->infilesize>0) {
- data->infilesize -= conn->resume_from;
+ if(data->set.infilesize>0) {
+ data->set.infilesize -= conn->resume_from;
- if(data->infilesize <= 0) {
+ if(data->set.infilesize <= 0) {
infof(data, "File already completely uploaded\n");
/* no data to transfer */
}
}
- /* Send everything on data->in to the socket */
- if(data->bits.ftp_append)
+ /* Send everything on data->set.in to the socket */
+ if(data->set.ftp_append)
/* we append onto the file instead of rewriting it */
ftpsendf(conn->firstsocket, conn, "APPE %s", ftp->file);
else
return CURLE_FTP_COULDNT_STOR_FILE;
}
- if(data->bits.ftp_use_port) {
+ if(data->set.ftp_use_port) {
/* PORT means we are now awaiting the server to connect to us. */
result = AllowServerConnect(data, conn, portsock);
if( result )
/* When we know we're uploading a specified file, we can get the file
size prior to the actual upload. */
- Curl_pgrsSetUploadSize(data, data->infilesize);
+ Curl_pgrsSetUploadSize(data, data->set.infilesize);
result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
conn->secondarysocket, bytecountp);
from, to, totalsize);
}
- if((data->bits.ftp_list_only) || !ftp->file) {
+ if((data->set.ftp_list_only) || !ftp->file) {
/* The specified path ends with a slash, and therefore we think this
is a directory that is requested, use LIST. But before that we
need to set ASCII transfer mode. */
standard in any way */
ftpsendf(conn->firstsocket, conn, "%s",
- data->customrequest?data->customrequest:
- (data->bits.ftp_list_only?"NLST":"LIST"));
+ data->set.customrequest?data->set.customrequest:
+ (data->set.ftp_list_only?"NLST":"LIST"));
}
else {
/* Set type to binary (unless specified ASCII) */
- result = _ftp_transfertype(conn, data->bits.ftp_ascii);
+ result = _ftp_transfertype(conn, data->set.ftp_ascii);
if(result)
return result;
int size=-1; /* default unknown size */
if(!dirlist &&
- !data->bits.ftp_ascii &&
+ !data->set.ftp_ascii &&
(-1 == downloadsize)) {
/*
* It seems directory listings either don't show the size or very
else if(downloadsize > -1)
size = downloadsize;
- if(data->bits.ftp_use_port) {
+ if(data->set.ftp_use_port) {
result = AllowServerConnect(data, conn, portsock);
if( result )
return result;
{
CURLcode retcode;
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
struct FTP *ftp;
int dirlength=0; /* 0 forces strlen() */
vsnprintf(s, 250, fmt, ap);
va_end(ap);
- if(conn->data->bits.verbose)
- fprintf(conn->data->err, "> %s\n", s);
+ if(conn->data->set.verbose)
+ fprintf(conn->data->set.err, "> %s\n", s);
strcat(s, "\r\n"); /* append a trailing CRLF */
/* The FTP session may or may not have been allocated/setup at this point! */
if(ftp) {
- if(ftp->user)
- free(ftp->user);
- if(ftp->passwd)
- free(ftp->passwd);
if(ftp->entrypath)
free(ftp->entrypath);
}
* This is supposed to be called in the beginning of a permform() session
* and should reset all session-info variables
*/
-CURLcode Curl_initinfo(struct UrlData *data)
+CURLcode Curl_initinfo(struct SessionHandle *data)
{
struct Progress *pro = &data->progress;
+ struct PureInfo *info =&data->info;
pro->t_nslookup = 0;
pro->t_connect = 0;
pro->t_pretransfer = 0;
- pro->httpcode = 0;
- pro->httpversion=0;
- pro->filetime=0;
+ info->httpcode = 0;
+ info->httpversion=0;
+ info->filetime=0;
return CURLE_OK;
}
-CURLcode Curl_getinfo(struct UrlData *data, CURLINFO info, ...)
+CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
{
va_list arg;
long *param_longp;
switch(info) {
case CURLINFO_EFFECTIVE_URL:
- *param_charp = data->url?data->url:(char *)"";
+ *param_charp = data->change.url?data->change.url:(char *)"";
break;
case CURLINFO_HTTP_CODE:
- *param_longp = data->progress.httpcode;
+ *param_longp = data->info.httpcode;
break;
case CURLINFO_FILETIME:
- *param_longp = data->progress.filetime;
+ *param_longp = data->info.filetime;
break;
case CURLINFO_HEADER_SIZE:
- *param_longp = data->header_size;
+ *param_longp = data->info.header_size;
break;
case CURLINFO_REQUEST_SIZE:
- *param_longp = data->request_size;
+ *param_longp = data->info.request_size;
break;
case CURLINFO_TOTAL_TIME:
*param_doublep = data->progress.timespent;
*param_doublep = data->progress.ulspeed;
break;
case CURLINFO_SSL_VERIFYRESULT:
- *param_longp = data->ssl.certverifyresult;
+ *param_longp = data->set.ssl.certverifyresult;
break;
case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
*param_doublep = data->progress.size_dl;
*
* $Id$
*****************************************************************************/
-CURLcode Curl_getinfo(struct UrlData *data, CURLINFO info, ...);
-CURLcode Curl_initinfo(struct UrlData *data);
+CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
+CURLcode Curl_initinfo(struct SessionHandle *data);
#endif
}
#ifdef ENABLE_IPV6
-struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
+struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port)
{
#define INADDR_NONE (unsigned long) ~0
#endif
-struct hostent *Curl_gethost(struct UrlData *data,
+struct hostent *Curl_gethost(struct SessionHandle *data,
char *hostname,
char **bufp)
{
*****************************************************************************/
struct addrinfo;
-struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
+struct addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
int port);
-struct hostent *Curl_gethost(struct UrlData *data,
+struct hostent *Curl_gethost(struct SessionHandle *data,
char *hostname,
char **bufp);
size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in)
{
size_t amount;
- if(conn->data->bits.verbose) {
- fputs("> ", conn->data->err);
+ if(conn->data->set.verbose) {
+ fputs("> ", conn->data->set.err);
/* this data _may_ contain binary stuff */
- fwrite(in->buffer, in->size_used, 1, conn->data->err);
+ fwrite(in->buffer, in->size_used, 1, conn->data->set.err);
}
Curl_write(conn, sockfd, in->buffer, in->size_used, &amount);
ssize_t nread;
int read_rc=1;
char *ptr;
- struct UrlData *data=conn->data;
+ struct SessionHandle *data=conn->data;
ptr=buf;
}
*ptr=0; /* zero terminate */
- if(data->bits.verbose) {
- fputs("< ", data->err);
- fwrite(buf, 1, nread, data->err);
- fputs("\n", data->err);
+ if(data->set.verbose) {
+ fputs("< ", data->set.err);
+ fwrite(buf, 1, nread, data->set.err);
+ fputs("\n", data->set.err);
}
return nread>0?nread:0;
}
* This function checks the linked list of custom HTTP headers for a particular
* header (prefix).
*/
-static bool checkheaders(struct UrlData *data, const char *thisheader)
+static bool checkheaders(struct SessionHandle *data, const char *thisheader)
{
struct curl_slist *head;
size_t thislen = strlen(thisheader);
- for(head = data->headers; head; head=head->next) {
+ for(head = data->set.headers; head; head=head->next) {
if(strnequal(head->data, thisheader, thislen)) {
return TRUE;
}
{
int httperror=0;
int subversion=0;
- struct UrlData *data=conn->data;
+ struct SessionHandle *data=conn->data;
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
"\r\n",
hostname, remote_port,
(conn->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"",
- (data->useragent?conn->allocptr.uagent:"")
+ (data->set.useragent?conn->allocptr.uagent:"")
);
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
- while(GetLine(tunnelsocket, data->buffer, conn)) {
- if('\r' == data->buffer[0])
+ while(GetLine(tunnelsocket, data->state.buffer, conn)) {
+ if('\r' == data->state.buffer[0])
break; /* end of headers */
- if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
+ if(2 == sscanf(data->state.buffer, "HTTP/1.%d %d",
&subversion,
&httperror)) {
;
*/
CURLcode Curl_http_connect(struct connectdata *conn)
{
- struct UrlData *data;
+ struct SessionHandle *data;
CURLcode result;
data=conn->data;
* has occured, can we start talking SSL
*/
if (conn->protocol & PROT_HTTPS) {
- if (data->bits.httpproxy) {
+ if (data->change.proxy) {
/* HTTPS through a proxy can only be done with a tunnel */
result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket,
conn->hostname, conn->remote_port);
return result;
}
- if(conn->bits.user_passwd && !data->bits.this_is_a_follow) {
+ if(conn->bits.user_passwd && !data->state.this_is_a_follow) {
/* Authorization: is requested, this is not a followed location, get the
original host name */
- data->auth_host = strdup(conn->hostname);
+ data->state.auth_host = strdup(conn->hostname);
}
return CURLE_OK;
protocol-specific resources */
CURLcode Curl_http_close(struct connectdata *conn)
{
- if(conn->data->auth_host)
- free(conn->data->auth_host);
+ if(conn->data->state.auth_host)
+ free(conn->data->state.auth_host);
return CURLE_OK;
}
CURLcode Curl_http_done(struct connectdata *conn)
{
- struct UrlData *data;
+ struct SessionHandle *data;
long *bytecount = &conn->bytecount;
struct HTTP *http;
data=conn->data;
http=conn->proto.http;
- if(HTTPREQ_POST_FORM == data->httpreq) {
+ if(HTTPREQ_POST_FORM == data->set.httpreq) {
*bytecount = http->readbytecount + http->writebytecount;
Curl_formclean(http->sendit); /* Now free that whole lot */
- data->fread = http->storefread; /* restore */
- data->in = http->in; /* restore */
+ data->set.fread = http->storefread; /* restore */
+ data->set.in = http->in; /* restore */
}
- else if(HTTPREQ_PUT == data->httpreq) {
+ else if(HTTPREQ_PUT == data->set.httpreq) {
*bytecount = http->readbytecount + http->writebytecount;
}
CURLcode Curl_http(struct connectdata *conn)
{
- struct UrlData *data=conn->data;
- char *buf = data->buffer; /* this is a short cut to the buffer */
+ struct SessionHandle *data=conn->data;
+ char *buf = data->state.buffer; /* this is a short cut to the buffer */
CURLcode result=CURLE_OK;
struct HTTP *http;
struct Cookie *co=NULL; /* no cookies from start */
conn->bits.close = FALSE;
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
- data->bits.upload) {
- data->httpreq = HTTPREQ_PUT;
+ data->set.upload) {
+ data->set.httpreq = HTTPREQ_PUT;
}
/* The User-Agent string has been built in url.c already, because it might
/* To prevent the user+password to get sent to other than the original
host due to a location-follow, we do some weirdo checks here */
- if(!data->bits.this_is_a_follow ||
- !data->auth_host ||
- strequal(data->auth_host, conn->hostname)) {
- sprintf(data->buffer, "%s:%s", data->user, data->passwd);
- if(Curl_base64_encode(data->buffer, strlen(data->buffer),
+ if(!data->state.this_is_a_follow ||
+ !data->state.auth_host ||
+ strequal(data->state.auth_host, conn->hostname)) {
+ sprintf(data->state.buffer, "%s:%s",
+ data->state.user, data->state.passwd);
+ if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
&authorization) >= 0) {
if(conn->allocptr.userpwd)
free(conn->allocptr.userpwd);
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
- authorization);
+ authorization);
free(authorization);
}
}
}
- if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) {
+ if((data->change.referer) && !checkheaders(data, "Referer:")) {
if(conn->allocptr.ref)
free(conn->allocptr.ref);
- conn->allocptr.ref = aprintf("Referer: %s\015\012", data->referer);
+ conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
}
- if(data->cookie && !checkheaders(data, "Cookie:")) {
+ if(data->set.cookie && !checkheaders(data, "Cookie:")) {
if(conn->allocptr.cookie)
free(conn->allocptr.cookie);
- conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->cookie);
+ conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->set.cookie);
}
if(data->cookies) {
co = Curl_cookie_getlist(data->cookies,
- host,
- ppath,
+ host, ppath,
conn->protocol&PROT_HTTPS?TRUE:FALSE);
}
- if ((data->bits.httpproxy) && !(conn->protocol&PROT_HTTPS)) {
+ if ((data->change.proxy) && !(conn->protocol&PROT_HTTPS)) {
/* The path sent to the proxy is in fact the entire URL */
- ppath = data->url;
+ ppath = data->change.url;
}
- if(HTTPREQ_POST_FORM == data->httpreq) {
+ if(HTTPREQ_POST_FORM == data->set.httpreq) {
/* we must build the whole darned post sequence first, so that we have
a size of the whole shebang before we start to send it */
- http->sendit = Curl_getFormData(data->httppost, &http->postsize);
+ http->sendit = Curl_getFormData(data->set.httppost, &http->postsize);
}
if(!checkheaders(data, "Host:")) {
if(!checkheaders(data, "Accept:"))
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
- if(( (HTTPREQ_POST == data->httpreq) ||
- (HTTPREQ_POST_FORM == data->httpreq) ||
- (HTTPREQ_PUT == data->httpreq) ) &&
+ if(( (HTTPREQ_POST == data->set.httpreq) ||
+ (HTTPREQ_POST_FORM == data->set.httpreq) ||
+ (HTTPREQ_PUT == data->set.httpreq) ) &&
conn->resume_from) {
/**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have
readthisamountnow = BUFSIZE;
actuallyread =
- data->fread(data->buffer, 1, readthisamountnow, data->in);
+ data->set.fread(data->state.buffer, 1, readthisamountnow,
+ data->set.in);
passed += actuallyread;
if(actuallyread != readthisamountnow) {
} while(passed != conn->resume_from); /* loop until done */
/* now, decrease the size of the read */
- if(data->infilesize>0) {
- data->infilesize -= conn->resume_from;
+ if(data->set.infilesize>0) {
+ data->set.infilesize -= conn->resume_from;
- if(data->infilesize <= 0) {
+ if(data->set.infilesize <= 0) {
failf(data, "File already completely uploaded\n");
return CURLE_PARTIAL_FILE;
}
* or uploading and we always let customized headers override our internal
* ones if any such are specified.
*/
- if((data->httpreq == HTTPREQ_GET) &&
+ if((data->set.httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) {
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
}
- else if((data->httpreq != HTTPREQ_GET) &&
+ else if((data->set.httpreq != HTTPREQ_GET) &&
!checkheaders(data, "Content-Range:")) {
if(conn->resume_from) {
/* This is because "resume" was selected */
- long total_expected_size= conn->resume_from + data->infilesize;
+ long total_expected_size= conn->resume_from + data->set.infilesize;
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n",
conn->range, total_expected_size-1,
total_expected_size);
/* Range was selected and then we just pass the incoming range and
append total size */
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n",
- conn->range, data->infilesize);
+ conn->range, data->set.infilesize);
}
}
}
do {
send_buffer *req_buffer;
- struct curl_slist *headers=data->headers;
+ struct curl_slist *headers=data->set.headers;
/* initialize a dynamic send-buffer */
req_buffer = add_buffer_init();
"%s" /* accept */
"%s", /* referer */
- data->customrequest?data->customrequest:
- (data->bits.no_body?"HEAD":
- ((HTTPREQ_POST == data->httpreq) ||
- (HTTPREQ_POST_FORM == data->httpreq))?"POST":
- (HTTPREQ_PUT == data->httpreq)?"PUT":"GET"),
+ data->set.customrequest?data->set.customrequest:
+ (data->set.no_body?"HEAD":
+ ((HTTPREQ_POST == data->set.httpreq) ||
+ (HTTPREQ_POST_FORM == data->set.httpreq))?"POST":
+ (HTTPREQ_PUT == data->set.httpreq)?"PUT":"GET"),
ppath,
(conn->bits.proxy_user_passwd &&
conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
conn->allocptr.userpwd:"",
(conn->bits.use_range && conn->allocptr.rangeline)?
conn->allocptr.rangeline:"",
- (data->useragent && *data->useragent && conn->allocptr.uagent)?
+ (data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
conn->allocptr.uagent:"",
(conn->allocptr.cookie?conn->allocptr.cookie:""), /* Cookie: <data> */
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
http->p_pragma?http->p_pragma:"",
http->p_accept?http->p_accept:"",
- (data->bits.http_set_referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */
+ (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */
);
if(co) {
co=NULL;
}
- if(data->timecondition) {
+ if(data->set.timecondition) {
struct tm *thistime;
/* Phil Karn (Fri, 13 Apr 2001) pointed out that the If-Modified-Since
/* We assume that the presense of localtime_r() proves the presense
of gmtime_r() which is a bit ugly but might work */
struct tm keeptime;
- thistime = (struct tm *)gmtime_r(&data->timevalue, &keeptime);
+ thistime = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime);
#else
- thistime = gmtime(&data->timevalue);
+ thistime = gmtime(&data->set.timevalue);
#endif
if(NULL == thistime) {
failf(data, "localtime() failed!");
/* TODO: Right, we *could* write a replacement here */
strcpy(buf, "no strftime() support");
#endif
- switch(data->timecondition) {
+ switch(data->set.timecondition) {
case TIMECOND_IFMODSINCE:
default:
add_bufferf(req_buffer,
headers = headers->next;
}
- if(HTTPREQ_POST_FORM == data->httpreq) {
+ if(HTTPREQ_POST_FORM == data->set.httpreq) {
char contentType[256];
int linelength=0;
if(Curl_FormInit(&http->form, http->sendit)) {
return CURLE_HTTP_POST_ERROR;
}
- http->storefread = data->fread; /* backup */
- http->in = data->in; /* backup */
+ http->storefread = data->set.fread; /* backup */
+ http->in = data->set.in; /* backup */
- data->fread = (curl_read_callback)
+ data->set.fread = (curl_read_callback)
Curl_FormReader; /* set the read function to read from the
generated form data */
- data->in = (FILE *)&http->form;
+ data->set.in = (FILE *)&http->form;
add_bufferf(req_buffer,
"Content-Length: %d\r\n", http->postsize-2);
there is one packet coming back from the web server) */
add_bufferf(req_buffer,
"Expect: 100-continue\r\n");
- data->bits.expect100header = TRUE;
+ data->set.expect100header = TRUE;
/* Get Content-Type: line from Curl_FormReadOneLine, which happens
to always be the first line. We can know this for sure since
Curl_pgrsSetUploadSize(data, http->postsize);
/* fire away the whole request to the server */
- data->request_size =
+ data->info.request_size =
add_buffer_send(conn->firstsocket, conn, req_buffer);
/* setup variables for the upcoming transfer */
return result;
}
}
- else if(HTTPREQ_PUT == data->httpreq) {
+ else if(HTTPREQ_PUT == data->set.httpreq) {
/* Let's PUT the data to the server! */
- if(data->infilesize>0) {
+ if(data->set.infilesize>0) {
add_bufferf(req_buffer,
"Content-Length: %d\r\n\r\n", /* file size */
- data->infilesize );
+ data->set.infilesize );
}
else
add_bufferf(req_buffer, "\015\012");
/* set the upload size to the progress meter */
- Curl_pgrsSetUploadSize(data, data->infilesize);
+ Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* this sends the buffer and frees all the buffer resources */
- data->request_size =
+ data->info.request_size =
add_buffer_send(conn->firstsocket, conn, req_buffer);
/* prepare for transfer */
}
else {
- if(HTTPREQ_POST == data->httpreq) {
+ if(HTTPREQ_POST == data->set.httpreq) {
/* this is the simple POST, using x-www-form-urlencoded style */
- if(!data->postfields) {
+ if(!data->set.postfields) {
/*
* This is an attempt to do a POST without having anything to
* actually send. Let's make a NULL pointer equal "" here. Good/bad
* ?
*/
- data->postfields = (char *)"";
- data->postfieldsize = 0; /* it might been set to something illegal,
+ data->set.postfields = (char *)"";
+ data->set.postfieldsize = 0; /* it might been set to something illegal,
anything > 0 would be! */
}
actually set your own */
add_bufferf(req_buffer,
"Content-Length: %d\r\n",
- (data->postfieldsize?data->postfieldsize:
- strlen(data->postfields)) );
+ (data->set.postfieldsize?data->set.postfieldsize:
+ strlen(data->set.postfields)) );
if(!checkheaders(data, "Content-Type:"))
add_bufferf(req_buffer,
"Content-Type: application/x-www-form-urlencoded\r\n");
/* and here comes the actual data */
- if(data->postfieldsize) {
+ if(data->set.postfieldsize) {
add_buffer(req_buffer, "\r\n", 2);
- add_buffer(req_buffer, data->postfields,
- data->postfieldsize);
+ add_buffer(req_buffer, data->set.postfields,
+ data->set.postfieldsize);
add_buffer(req_buffer, "\r\n", 2);
}
else {
add_bufferf(req_buffer,
"\r\n"
"%s\r\n",
- data->postfields );
+ data->set.postfields );
}
}
else
add_buffer(req_buffer, "\r\n", 2);
/* issue the request */
- data->request_size =
+ data->info.request_size =
add_buffer_send(conn->firstsocket, conn, req_buffer);
/* HTTP GET/HEAD download: */
Curl_ftpsendf(conn->firstsocket, conn, "ADAT %s", p);
nread = Curl_GetFTPResponse(conn->firstsocket,
- conn->data->buffer, conn, NULL);
+ conn->data.set->buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
free(p);
- if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
+ if(/*ret != COMPLETE*/conn->data.set->buffer[0] != '2'){
printf("Server didn't accept auth data.\n");
return AUTH_ERROR;
}
- p = strstr(conn->data->buffer, "ADAT=");
+ p = strstr(conn->data.set->buffer, "ADAT=");
if(!p){
printf("Remote host didn't send adat reply.\n");
return AUTH_ERROR;
save = Curl_set_command_prot(conn, prot_private);
Curl_ftpsendf(conn->firstsocket, conn,
- "SITE KAUTH %s", conn->data->user);
+ "SITE KAUTH %s", conn->data.set->user);
- nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->buffer,
+ nread = Curl_GetFTPResponse(conn->firstsocket, conn->data.set->buffer,
conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/;
- if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
+ if(/*ret != CONTINUE*/conn->data.set->buffer[0] != '3'){
Curl_set_command_prot(conn, save);
/*code = -1;***/
return;
}
- p = strstr(conn->data->buffer, "T=");
+ p = strstr(conn->data.set->buffer, "T=");
if(!p) {
printf("Bad reply from server.\n");
Curl_set_command_prot(conn, save);
tkt.length = tmp;
tktcopy.length = tkt.length;
- p = strstr(conn->data->buffer, "P=");
+ p = strstr(conn->data.set->buffer, "P=");
if(!p) {
printf("Bad reply from server.\n");
Curl_set_command_prot(conn, save);
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
*p = 0;
- des_string_to_key (conn->data->passwd, &key);
+ des_string_to_key (conn->data.set->passwd, &key);
des_key_sched(&key, schedule);
des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
Curl_ftpsendf(conn->firstsocket, conn,
"SITE KAUTH %s %s", name, p);
- nread = Curl_GetFTPResponse(conn->firstsocket, conn->data->buffer,
+ nread = Curl_GetFTPResponse(conn->firstsocket, conn->data.set->buffer,
conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/;
static int WriteProc(void *param, char *text, int len)
{
- struct UrlData *data = (struct UrlData *)param;
+ struct SessionHandle *data = (struct SessionHandle *)param;
len = 0; /* prevent compiler warning */
Curl_client_write(data, CLIENTWRITE_BODY, text, 0);
return 0;
void *entryIterator;
int ldaptext;
- struct UrlData *data=conn->data;
+ struct SessionHandle *data=conn->data;
- infof(data, "LDAP: %s %s\n", data->url);
+ infof(data, "LDAP: %s %s\n", data->change.url);
DynaOpen();
if (libldap == NULL) {
return CURLE_LIBRARY_NOT_FOUND;
}
- ldaptext = data->bits.ftp_ascii; /* This is a dirty hack */
+ ldaptext = data->set.ftp_ascii; /* This is a dirty hack */
/* The types are needed because ANSI C distinguishes between
* pointer-to-object (data) and pointer-to-function.
conn->hostname, conn->port);
status = CURLE_COULDNT_CONNECT;
} else {
- rc = ldap_simple_bind_s(server, data->user, data->passwd);
+ rc = ldap_simple_bind_s(server, data->state.user, data->state.passwd);
if (rc != 0) {
failf(data, "LDAP: %s", ldap_err2string(rc));
status = CURLE_LDAP_CANNOT_BIND;
} else {
- rc = ldap_url_search_s(server, data->url, 0, &result);
+ rc = ldap_url_search_s(server, data->change.url, 0, &result);
if (rc != 0) {
failf(data, "LDAP: %s", ldap_err2string(rc));
status = CURLE_LDAP_SEARCH_FAILED;
void Curl_pgrsDone(struct connectdata *conn)
{
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
if(!(data->progress.flags & PGRS_HIDE)) {
data->progress.lastshow=0;
Curl_pgrsUpdate(conn); /* the final (forced) update */
if(!data->progress.callback)
/* only output if we don't use progress callback */
- fprintf(data->err, "\n");
+ fprintf(data->set.err, "\n");
}
}
-void Curl_pgrsTime(struct UrlData *data, timerid timer)
+void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
{
switch(timer) {
default:
}
}
-void Curl_pgrsStartNow(struct UrlData *data)
+void Curl_pgrsStartNow(struct SessionHandle *data)
{
data->progress.speeder_c = 0; /* reset the progress meter display */
data->progress.start = Curl_tvnow();
}
-void Curl_pgrsSetDownloadCounter(struct UrlData *data, double size)
+void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, double size)
{
data->progress.downloaded = size;
}
-void Curl_pgrsSetUploadCounter(struct UrlData *data, double size)
+void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size)
{
data->progress.uploaded = size;
}
-void Curl_pgrsSetDownloadSize(struct UrlData *data, double size)
+void Curl_pgrsSetDownloadSize(struct SessionHandle *data, double size)
{
if(size > 0) {
data->progress.size_dl = size;
}
}
-void Curl_pgrsSetUploadSize(struct UrlData *data, double size)
+void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size)
{
if(size > 0) {
data->progress.size_ul = size;
double total_transfer;
double total_expected_transfer;
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
int nowindex = data->progress.speeder_c% CURR_TIME;
int checkindex;
else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
if (!data->progress.callback) {
if(conn->resume_from)
- fprintf(data->err, "** Resuming transfer from byte position %d\n",
+ fprintf(data->set.err, "** Resuming transfer from byte position %d\n",
conn->resume_from);
- fprintf(data->err,
+ fprintf(data->set.err,
" %% Total %% Received %% Xferd Average Speed Time Curr.\n"
" Dload Upload Total Current Left Speed\n");
}
if(data->progress.flags & PGRS_HIDE)
return 0;
- else if(data->fprogress) {
- result= data->fprogress(data->progress_client,
- data->progress.size_dl,
- data->progress.downloaded,
- data->progress.size_ul,
- data->progress.uploaded);
+ else if(data->set.fprogress) {
+ result= data->set.fprogress(data->set.progress_client,
+ data->progress.size_dl,
+ data->progress.downloaded,
+ data->progress.size_ul,
+ data->progress.uploaded);
if(result)
failf(data, "Callback aborted");
return result;
if(total_expected_transfer)
total_percen=(double)(total_transfer/total_expected_transfer)*100;
- fprintf(data->err,
+ fprintf(data->set.err,
"\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
(int)total_percen, /* total % */
max5data(total_expected_transfer, max5[2]), /* total size */
);
/* we flush the output stream to make it appear as soon as possible */
- fflush(data->err);
+ fflush(data->set.err);
return 0;
}
} timerid;
void Curl_pgrsDone(struct connectdata *);
-void Curl_pgrsStartNow(struct UrlData *data);
-void Curl_pgrsSetDownloadSize(struct UrlData *data, double size);
-void Curl_pgrsSetUploadSize(struct UrlData *data, double size);
-void Curl_pgrsSetDownloadCounter(struct UrlData *data, double size);
-void Curl_pgrsSetUploadCounter(struct UrlData *data, double size);
+void Curl_pgrsStartNow(struct SessionHandle *data);
+void Curl_pgrsSetDownloadSize(struct SessionHandle *data, double size);
+void Curl_pgrsSetUploadSize(struct SessionHandle *data, double size);
+void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, double size);
+void Curl_pgrsSetUploadCounter(struct SessionHandle *data, double size);
int Curl_pgrsUpdate(struct connectdata *);
-void Curl_pgrsTime(struct UrlData *data, timerid timer);
+void Curl_pgrsTime(struct SessionHandle *data, timerid timer);
/* Don't show progress for sizes smaller than: */
"PBSZ %u", s);
/* wait for feedback */
nread = Curl_GetFTPResponse(conn->firstsocket,
- conn->data->buffer, conn, NULL);
+ conn->data.set->buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
- if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
+ if(/*ret != COMPLETE*/conn->data.set->buffer[0] != '2'){
failf(conn->data, "Failed to set protection buffer size.\n");
return -1;
}
conn->buffer_size = s;
- p = strstr(/*reply_string*/conn->data->buffer, "PBSZ=");
+ p = strstr(/*reply_string*/conn->data.set->buffer, "PBSZ=");
if(p)
sscanf(p, "PBSZ=%u", &s);
if(s < conn->buffer_size)
"PROT %c", level["CSEP"]);
/* wait for feedback */
nread = Curl_GetFTPResponse(conn->firstsocket,
- conn->data->buffer, conn, NULL);
+ conn->data.set->buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
- if(/*ret != COMPLETE*/conn->data->buffer[0] != '2'){
+ if(/*ret != COMPLETE*/conn->data.set->buffer[0] != '2'){
failf(conn->data, "Failed to set protection level.\n");
return -1;
}
int ret;
struct Curl_sec_client_mech **m;
ssize_t nread;
- struct UrlData *data=conn->data;
+ struct SessionHandle *data=conn->data;
for(m = mechs; *m && (*m)->name; m++) {
void *tmp;
"AUTH %s", (*m)->name);
/* wait for feedback */
nread = Curl_GetFTPResponse(conn->firstsocket,
- conn->data->buffer, conn, NULL);
+ conn->data.set->buffer, conn, NULL);
if(nread < 0)
return /*CURLE_OPERATION_TIMEOUTED*/-1;
- if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
- if(/*code == 504*/strncmp(conn->data->buffer,"504",3) == 0) {
+ if(/*ret != CONTINUE*/conn->data.set->buffer[0] != '3'){
+ if(/*code == 504*/strncmp(conn->data.set->buffer,"504",3) == 0) {
infof(data,
"%s is not supported by the server.\n", (*m)->name);
}
- else if(/*code == 534*/strncmp(conn->data->buffer,"534",3) == 0) {
+ else if(/*code == 534*/strncmp(conn->data.set->buffer,"534",3) == 0) {
infof(data, "%s rejected as security mechanism.\n", (*m)->name);
}
- else if(/*ret == ERROR*/conn->data->buffer[0] == '5') {
+ else if(/*ret == ERROR*/conn->data.set->buffer[0] == '5') {
infof(data, "The server doesn't support the FTP "
"security extensions.\n");
return -1;
/* Curl_infof() is for info message along the way */
-void Curl_infof(struct UrlData *data, const char *fmt, ...)
+void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
{
va_list ap;
- if(data->bits.verbose) {
+ if(data->set.verbose) {
va_start(ap, fmt);
- fputs("* ", data->err);
- vfprintf(data->err, fmt, ap);
+ fputs("* ", data->set.err);
+ vfprintf(data->set.err, fmt, ap);
va_end(ap);
}
}
/* Curl_failf() is for messages stating why we failed, the LAST one will be
returned for the user (if requested) */
-void Curl_failf(struct UrlData *data, const char *fmt, ...)
+void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- if(data->errorbuffer)
- vsnprintf(data->errorbuffer, CURL_ERROR_SIZE, fmt, ap);
+ if(data->set.errorbuffer)
+ vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
va_end(ap);
}
size_t Curl_sendf(int sockfd, struct connectdata *conn,
const char *fmt, ...)
{
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
size_t bytes_written;
char *s;
va_list ap;
va_end(ap);
if(!s)
return 0; /* failure */
- if(data->bits.verbose)
- fprintf(data->err, "> %s", s);
+ if(data->set.verbose)
+ fprintf(data->set.err, "> %s", s);
/* Write the buffer to the socket */
Curl_write(conn, sockfd, s, strlen(s), &bytes_written);
The bit pattern defines to what "streams" to write to. Body and/or header.
The defines are in sendf.h of course.
*/
-CURLcode Curl_client_write(struct UrlData *data,
+CURLcode Curl_client_write(struct SessionHandle *data,
int type,
char *ptr,
size_t len)
len = strlen(ptr);
if(type & CLIENTWRITE_BODY) {
- wrote = data->fwrite(ptr, 1, len, data->out);
+ wrote = data->set.fwrite(ptr, 1, len, data->set.out);
if(wrote != len) {
failf (data, "Failed writing body");
return CURLE_WRITE_ERROR;
}
}
if((type & CLIENTWRITE_HEADER) &&
- (data->fwrite_header || data->writeheader) ) {
+ (data->set.fwrite_header || data->set.writeheader) ) {
/*
* Write headers to the same callback or to the especially setup
* header callback function (added after version 7.7.1).
*/
curl_write_callback writeit=
- data->fwrite_header?data->fwrite_header:data->fwrite;
+ data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite;
- wrote = writeit(ptr, 1, len, data->writeheader);
+ wrote = writeit(ptr, 1, len, data->set.writeheader);
if(wrote != len) {
failf (data, "Failed writing header");
return CURLE_WRITE_ERROR;
*****************************************************************************/
size_t Curl_sendf(int fd, struct connectdata *, const char *fmt, ...);
-void Curl_infof(struct UrlData *, const char *fmt, ...);
-void Curl_failf(struct UrlData *, const char *fmt, ...);
+void Curl_infof(struct SessionHandle *, const char *fmt, ...);
+void Curl_failf(struct SessionHandle *, const char *fmt, ...);
#define infof Curl_infof
#define failf Curl_failf
#define CLIENTWRITE_HEADER 2
#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
-CURLcode Curl_client_write(struct UrlData *data, int type, char *ptr,
+CURLcode Curl_client_write(struct SessionHandle *data, int type, char *ptr,
size_t len);
/* internal read-function, does plain socket, SSL and krb4 */
#include "sendf.h"
#include "speedcheck.h"
-void Curl_speedinit(struct UrlData *data)
+void Curl_speedinit(struct SessionHandle *data)
{
- memset(&data->keeps_speed, 0, sizeof(struct timeval));
+ memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
}
-CURLcode Curl_speedcheck(struct UrlData *data,
+CURLcode Curl_speedcheck(struct SessionHandle *data,
struct timeval now)
{
if((data->progress.current_speed >= 0) &&
- data->low_speed_time &&
- (Curl_tvlong(data->keeps_speed) != 0) &&
- (data->progress.current_speed < data->low_speed_limit)) {
+ data->set.low_speed_time &&
+ (Curl_tvlong(data->state.keeps_speed) != 0) &&
+ (data->progress.current_speed < data->set.low_speed_limit)) {
/* We are now below the "low speed limit". If we are below it
for "low speed time" seconds we consider that enough reason
to abort the download. */
- if( Curl_tvdiff(now, data->keeps_speed) > data->low_speed_time) {
+ if( Curl_tvdiff(now, data->state.keeps_speed) > data->set.low_speed_time) {
/* we have been this slow for long enough, now die */
failf(data,
"Operation too slow. "
"Less than %d bytes/sec transfered the last %d seconds",
- data->low_speed_limit,
- data->low_speed_time);
+ data->set.low_speed_limit,
+ data->set.low_speed_time);
return CURLE_OPERATION_TIMEOUTED;
}
}
else {
/* we keep up the required speed all right */
- data->keeps_speed = now;
+ data->state.keeps_speed = now;
}
return CURLE_OK;
}
#include "timeval.h"
-void Curl_speedinit(struct UrlData *data);
-CURLcode Curl_speedcheck(struct UrlData *data,
+void Curl_speedinit(struct SessionHandle *data);
+CURLcode Curl_speedcheck(struct SessionHandle *data,
struct timeval now);
#endif
static
int random_the_seed(struct connectdata *conn)
{
- char *buf = conn->data->buffer; /* point to the big buffer */
+ char *buf = conn->data->state.buffer; /* point to the big buffer */
int nread=0;
- struct UrlData *data=conn->data;
+ struct SessionHandle *data=conn->data;
/* Q: should we add support for a random file name as a libcurl option?
A: Yes, it is here */
#ifndef RANDOM_FILE
/* if RANDOM_FILE isn't defined, we only perform this if an option tells
us to! */
- if(data->ssl.random_file)
+ if(data->set.ssl.random_file)
#define RANDOM_FILE "" /* doesn't matter won't be used */
#endif
{
/* let the option override the define */
- nread += RAND_load_file((data->ssl.random_file?
- data->ssl.random_file:RANDOM_FILE),
+ nread += RAND_load_file((data->set.ssl.random_file?
+ data->set.ssl.random_file:RANDOM_FILE),
16384);
if(seed_enough(conn, nread))
return nread;
#ifndef EGD_SOCKET
/* If we don't have the define set, we only do this if the egd-option
is set */
- if(data->ssl.egdsocket)
+ if(data->set.ssl.egdsocket)
#define EGD_SOCKET "" /* doesn't matter won't be used */
#endif
{
/* If there's an option and a define, the option overrides the
define */
- int ret = RAND_egd(data->ssl.egdsocket?data->ssl.egdsocket:EGD_SOCKET);
+ int ret = RAND_egd(data->set.ssl.egdsocket?data->set.ssl.egdsocket:EGD_SOCKET);
if(-1 != ret) {
nread += ret;
if(seed_enough(conn, nread))
char *cert_file,
char *key_file)
{
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
if (cert_file != NULL) {
SSL *ssl;
X509 *x509;
- if(data->cert_passwd) {
+ if(data->set.cert_passwd) {
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
/*
* If password has been given, we store that in the global
* area (*shudder*) for a while:
*/
- strcpy(global_passwd, data->cert_passwd);
+ strcpy(global_passwd, data->set.cert_passwd);
#else
/*
* We set the password in the callback userdata
*/
- SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx, data->cert_passwd);
+ SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx, data->set.cert_passwd);
#endif
/* Set passwd callback: */
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
/*
* This sets up a session cache to the specified size.
*/
-CURLcode Curl_SSL_InitSessions(struct UrlData *data, long amount)
+CURLcode Curl_SSL_InitSessions(struct SessionHandle *data, long amount)
{
struct curl_ssl_session *session;
- if(data->ssl.session)
+ if(data->set.ssl.session)
/* this is just a precaution to prevent multiple inits */
return CURLE_OK;
memset(session, 0, amount * sizeof(struct curl_ssl_session));
/* store the info in the SSL section */
- data->ssl.numsessions = amount;
- data->ssl.session = session;
- data->ssl.sessionage = 1; /* this is brand new */
+ data->set.ssl.numsessions = amount;
+ data->set.ssl.session = session;
+ data->set.ssl.sessionage = 1; /* this is brand new */
return CURLE_OK;
}
SSL_SESSION **ssl_sessionid)
{
struct curl_ssl_session *check;
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
long i;
- for(i=0; i< data->ssl.numsessions; i++) {
- check = &data->ssl.session[i];
+ for(i=0; i< data->set.ssl.numsessions; i++) {
+ check = &data->set.ssl.session[i];
if(!check->sessionid)
/* not session ID means blank entry */
continue;
if(strequal(conn->name, check->name) &&
(conn->remote_port == check->remote_port) ) {
/* yes, we have a session ID! */
- data->ssl.sessionage++; /* increase general age */
- check->age = data->ssl.sessionage; /* set this as used in this age */
+ data->set.ssl.sessionage++; /* increase general age */
+ check->age = data->set.ssl.sessionage; /* set this as used in this age */
*ssl_sessionid = check->sessionid;
return FALSE;
}
* This function is called when the 'data' struct is going away. Close
* down everything and free all resources!
*/
-int Curl_SSL_Close_All(struct UrlData *data)
+int Curl_SSL_Close_All(struct SessionHandle *data)
{
int i;
- for(i=0; i< data->ssl.numsessions; i++)
+ for(i=0; i< data->set.ssl.numsessions; i++)
/* the single-killer function handles empty table slots */
- Kill_Single_Session(&data->ssl.session[i]);
+ Kill_Single_Session(&data->set.ssl.session[i]);
/* free the cache data */
- free(data->ssl.session);
+ free(data->set.ssl.session);
return 0;
}
SSL_SESSION *ssl_sessionid;
struct curl_ssl_session *store;
int i;
- struct UrlData *data=conn->data; /* the mother of all structs */
- int oldest_age=data->ssl.session[0].age; /* zero if unused */
+ struct SessionHandle *data=conn->data; /* the mother of all structs */
+ int oldest_age=data->set.ssl.session[0].age; /* zero if unused */
/* ask OpenSSL, say please */
ssl_sessionid = SSL_get1_session(conn->ssl.handle);
the oldest if necessary) */
/* find an empty slot for us, or find the oldest */
- for(i=0; (i<data->ssl.numsessions) && data->ssl.session[i].sessionid; i++) {
- if(data->ssl.session[i].age < oldest_age) {
- oldest_age = data->ssl.session[i].age;
- store = &data->ssl.session[i];
+ for(i=0; (i<data->set.ssl.numsessions) && data->set.ssl.session[i].sessionid; i++) {
+ if(data->set.ssl.session[i].age < oldest_age) {
+ oldest_age = data->set.ssl.session[i].age;
+ store = &data->set.ssl.session[i];
}
}
- if(i == data->ssl.numsessions)
+ if(i == data->set.ssl.numsessions)
/* cache is full, we must "kill" the oldest entry! */
Kill_Single_Session(store);
else
- store = &data->ssl.session[i]; /* use this slot */
+ store = &data->set.ssl.session[i]; /* use this slot */
/* now init the session struct wisely */
store->sessionid = ssl_sessionid;
- store->age = data->ssl.sessionage; /* set current age */
+ store->age = data->set.ssl.sessionage; /* set current age */
store->name = strdup(conn->name); /* clone host name */
store->remote_port = conn->remote_port; /* port number */
CURLcode retcode = CURLE_OK;
#ifdef USE_SSLEAY
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
int err;
char * str;
SSL_METHOD *req_method;
/* Make funny stuff to get random input */
random_the_seed(conn);
- switch(data->ssl.version) {
+ switch(data->set.ssl.version) {
default:
req_method = SSLv23_client_method();
break;
return CURLE_OUT_OF_MEMORY;
}
- if(data->cert) {
- if (!cert_stuff(conn, data->cert, data->cert)) {
+ if(data->set.cert) {
+ if (!cert_stuff(conn, data->set.cert, data->set.cert)) {
/* failf() is already done in cert_stuff() */
return CURLE_SSL_CONNECT_ERROR;
}
}
- if(data->ssl.verifypeer){
+ if(data->set.ssl.verifypeer){
SSL_CTX_set_verify(conn->ssl.ctx,
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
SSL_VERIFY_CLIENT_ONCE,
cert_verify_callback);
if (!SSL_CTX_load_verify_locations(conn->ssl.ctx,
- data->ssl.CAfile,
- data->ssl.CApath)) {
+ data->set.ssl.CAfile,
+ data->set.ssl.CApath)) {
failf(data,"error setting cerficate verify locations\n");
return CURLE_SSL_CONNECT_ERROR;
}
infof(data, "\t subject: %s\n", str);
CRYPTO_free(str);
- if (data->ssl.verifyhost) {
+ if (data->set.ssl.verifyhost) {
char peer_CN[257];
if (X509_NAME_get_text_by_NID(X509_get_subject_name(conn->ssl.server_cert), NID_commonName, peer_CN, sizeof(peer_CN)) < 0) {
failf(data, "SSL: unable to obtain common name from peer certificate");
}
if (!strequal(peer_CN, conn->hostname)) {
- if (data->ssl.verifyhost > 1) {
+ if (data->set.ssl.verifyhost > 1) {
failf(data, "SSL: certificate subject name '%s' does not match target host name '%s'",
peer_CN, conn->hostname);
X509_free(conn->ssl.server_cert);
/* We could do all sorts of certificate verification stuff here before
deallocating the certificate. */
- if(data->ssl.verifypeer) {
- data->ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);
- if (data->ssl.certverifyresult != X509_V_OK) {
+ if(data->set.ssl.verifypeer) {
+ data->set.ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);
+ if (data->set.ssl.certverifyresult != X509_V_OK) {
failf(data, "SSL certificate verify result: %d\n",
- data->ssl.certverifyresult);
+ data->set.ssl.certverifyresult);
retcode = CURLE_SSL_PEER_CERTIFICATE;
}
}
else
- data->ssl.certverifyresult=0;
+ data->set.ssl.certverifyresult=0;
X509_free(conn->ssl.server_cert);
#else /* USE_SSLEAY */
void Curl_SSL_cleanup(void); /* Global SSL cleanup */
/* init the SSL session ID cache */
-CURLcode Curl_SSL_InitSessions(struct UrlData *, long);
+CURLcode Curl_SSL_InitSessions(struct SessionHandle *, long);
void Curl_SSL_Close(struct connectdata *conn); /* close a SSL connection */
/* tell the SSL stuff to close down all open information regarding
connections (and thus session ID caching etc) */
-int Curl_SSL_Close_All(struct UrlData *data);
+int Curl_SSL_Close_All(struct SessionHandle *data);
#endif
unsigned char *inbuf, /* Data received from socket */
int count); /* Number of bytes received */
-static void printoption(struct UrlData *data,
+static void printoption(struct SessionHandle *data,
const char *direction,
int cmd, int option);
static void set_local_option(struct connectdata *, int cmd, int option);
static void set_remote_option(struct connectdata *, int cmd, int option);
-static void printsub(struct UrlData *data,
+static void printsub(struct SessionHandle *data,
int direction, unsigned char *pointer, int length);
static void suboption(struct connectdata *);
}
}
-static void printoption(struct UrlData *data,
+static void printoption(struct SessionHandle *data,
const char *direction, int cmd, int option)
{
const char *fmt;
const char *opt;
- if (data->bits.verbose)
+ if (data->set.verbose)
{
if (cmd == IAC)
{
}
-static void printsub(struct UrlData *data,
+static void printsub(struct SessionHandle *data,
int direction, /* '<' or '>' */
unsigned char *pointer, /* where suboption data is */
int length) /* length of suboption data */
{
int i = 0;
- if (data->bits.verbose)
+ if (data->set.verbose)
{
if (direction)
{
char option_keyword[128];
char option_arg[256];
char *buf;
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
/* Add the user name as an environment variable if it
if(conn->bits.user_passwd)
{
char *buf = malloc(256);
- sprintf(buf, "USER,%s", data->user);
+ sprintf(buf, "USER,%s", data->state.user);
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
tn->us_preferred[TELOPT_NEW_ENVIRON] = YES;
}
- for(head = data->telnet_options; head; head=head->next) {
+ for(head = data->set.telnet_options; head; head=head->next) {
if(sscanf(head->data, "%127[^= ]%*[ =]%255s",
option_keyword, option_arg) == 2) {
int tmplen;
char varname[128];
char varval[128];
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
printsub(data, '<', (unsigned char *)tn->subbuffer, SB_LEN(tn)+2);
{
unsigned char c;
int index = 0;
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
while(count--)
CURLcode Curl_telnet(struct connectdata *conn)
{
CURLcode code;
- struct UrlData *data = conn->data;
+ struct SessionHandle *data = conn->data;
int sockfd = conn->firstsocket;
fd_set readfd;
fd_set keepfd;
bool keepon = TRUE;
- char *buf = data->buffer;
+ char *buf = data->state.buffer;
ssize_t nread;
struct TELNET *tn;
int writetype;
/* the highest fd we use + 1 */
- struct UrlData *data;
+ struct SessionHandle *data;
struct connectdata *conn = (struct connectdata *)c_conn;
char *buf;
int maxfd;
data = conn->data; /* there's the root struct */
- buf = data->buffer;
+ buf = data->state.buffer;
maxfd = (conn->sockfd>conn->writesockfd?conn->sockfd:conn->writesockfd)+1;
- hbufp = data->headerbuff;
+ hbufp = data->state.headerbuff;
myalarm (0); /* switch off the alarm-style timeout */
}
/* we want header and/or body, if neither then don't do this! */
if(conn->getheader ||
- !data->bits.no_body) {
+ !data->set.no_body) {
fd_set readfd;
fd_set writefd;
fd_set rkeepfd;
FD_ZERO (&writefd); /* clear it */
if(conn->writesockfd != -1) {
- if (data->bits.expect100header)
+ if (data->set.expect100header)
/* wait with write until we either got 100-continue or a timeout */
write_after_100_header = TRUE;
else {
* We enlarge the header buffer if it seems to be too
* smallish
*/
- if (hbuflen + (int)str_length >= data->headersize) {
+ if (hbuflen + (int)str_length >= data->state.headersize) {
char *newbuff;
long newsize=MAX((hbuflen+str_length)*3/2,
- data->headersize*2);
- hbufp_index = hbufp - data->headerbuff;
- newbuff = (char *)realloc(data->headerbuff, newsize);
+ data->state.headersize*2);
+ hbufp_index = hbufp - data->state.headerbuff;
+ newbuff = (char *)realloc(data->state.headerbuff, newsize);
if(!newbuff) {
failf (data, "Failed to alloc memory for big header!");
return CURLE_READ_ERROR;
}
- data->headersize=newsize;
- data->headerbuff = newbuff;
- hbufp = data->headerbuff + hbufp_index;
+ data->state.headersize=newsize;
+ data->state.headerbuff = newbuff;
+ hbufp = data->state.headerbuff + hbufp_index;
}
strcpy (hbufp, str);
hbufp += strlen (str);
* fit in the allocated header buffer, or else we enlarge
* it.
*/
- if (hbuflen + (str - str_start) >= data->headersize) {
+ if (hbuflen + (str - str_start) >= data->state.headersize) {
char *newbuff;
long newsize=MAX((hbuflen+(str-str_start))*3/2,
- data->headersize*2);
- hbufp_index = hbufp - data->headerbuff;
- newbuff = (char *)realloc(data->headerbuff, newsize);
+ data->state.headersize*2);
+ hbufp_index = hbufp - data->state.headerbuff;
+ newbuff = (char *)realloc(data->state.headerbuff, newsize);
if(!newbuff) {
failf (data, "Failed to alloc memory for big header!");
return CURLE_READ_ERROR;
}
- data->headersize= newsize;
- data->headerbuff = newbuff;
- hbufp = data->headerbuff + hbufp_index;
+ data->state.headersize= newsize;
+ data->state.headerbuff = newbuff;
+ hbufp = data->state.headerbuff + hbufp_index;
}
/* copy to end of line */
hbuflen += str - str_start;
*hbufp = 0;
- p = data->headerbuff;
+ p = data->state.headerbuff;
/****
* We now have a FULL header line that p points to
/* now, only output this if the header AND body are requested:
*/
writetype = CLIENTWRITE_HEADER;
- if (data->bits.http_include_header)
+ if (data->set.http_include_header)
writetype |= CLIENTWRITE_BODY;
- urg = Curl_client_write(data, writetype, data->headerbuff,
- p - data->headerbuff);
+ urg = Curl_client_write(data, writetype, data->state.headerbuff,
+ p - data->state.headerbuff);
if(urg)
return urg;
- data->header_size += p - data->headerbuff;
+ data->info.header_size += p - data->state.headerbuff;
if(!header) {
/*
* If we requested a "no body", this is a good time to get
* out and return home.
*/
- if(data->bits.no_body)
+ if(data->set.no_body)
return CURLE_OK;
if(!conn->bits.close) {
/* We continue reading headers, so reset the line-based
header parsing variables hbufp && hbuflen */
- hbufp = data->headerbuff;
+ hbufp = data->state.headerbuff;
hbuflen = 0;
continue;
}
}
if (nc) {
- data->progress.httpcode = httpcode;
- data->progress.httpversion = httpversion;
+ data->info.httpcode = httpcode;
+ data->info.httpversion = httpversion;
/* 404 -> URL not found! */
if (
- ( ((data->bits.http_follow_location) &&
+ ( ((data->set.http_follow_location) &&
(httpcode >= 400))
||
- (!data->bits.http_follow_location &&
+ (!data->set.http_follow_location &&
(httpcode >= 300)))
- && (data->bits.http_fail_on_error)) {
+ && (data->set.http_fail_on_error)) {
/* If we have been told to fail hard on HTTP-errors,
here is the check for that: */
/* serious error, go home! */
}
else if(strnequal("Last-Modified:", p,
strlen("Last-Modified:")) &&
- (data->timecondition || data->bits.get_filetime) ) {
+ (data->set.timecondition || data->set.get_filetime) ) {
time_t secs=time(NULL);
timeofdoc = curl_getdate(p+strlen("Last-Modified:"), &secs);
- if(data->bits.get_filetime)
- data->progress.filetime = timeofdoc;
+ if(data->set.get_filetime)
+ data->info.filetime = timeofdoc;
}
else if ((httpcode >= 300 && httpcode < 400) &&
- (data->bits.http_follow_location) &&
+ (data->set.http_follow_location) &&
strnequal("Location:", p, 9)) {
/* this is the URL that the server advices us to get instead */
char *ptr;
*/
writetype = CLIENTWRITE_HEADER;
- if (data->bits.http_include_header)
+ if (data->set.http_include_header)
writetype |= CLIENTWRITE_BODY;
urg = Curl_client_write(data, writetype, p, hbuflen);
if(urg)
return urg;
- data->header_size += hbuflen;
+ data->info.header_size += hbuflen;
/* reset hbufp pointer && hbuflen */
- hbufp = data->headerbuff;
+ hbufp = data->state.headerbuff;
hbuflen = 0;
}
while (*str); /* header line within buffer */
}
else if (conn->resume_from &&
!content_range &&
- (data->httpreq==HTTPREQ_GET)) {
+ (data->set.httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server
doesn't seem to support this and we did this with a GET
(if it wasn't a GET we did a POST or PUT resume) */
"byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR;
}
- else if(data->timecondition && !conn->range) {
+ else if(data->set.timecondition && !conn->range) {
/* A time condition has been set AND no ranges have been
requested. This seems to be what chapter 13.3.4 of
RFC 2616 defines to be the correct action for a
HTTP/1.1 client */
- if((timeofdoc > 0) && (data->timevalue > 0)) {
- switch(data->timecondition) {
+ if((timeofdoc > 0) && (data->set.timevalue > 0)) {
+ switch(data->set.timecondition) {
case TIMECOND_IFMODSINCE:
default:
- if(timeofdoc < data->timevalue) {
+ if(timeofdoc < data->set.timevalue) {
infof(data,
"The requested document is not new enough\n");
return CURLE_OK;
}
break;
case TIMECOND_IFUNMODSINCE:
- if(timeofdoc > data->timevalue) {
+ if(timeofdoc > data->set.timevalue) {
infof(data,
"The requested document is not old enough\n");
return CURLE_OK;
int i, si;
size_t bytes_written;
- if(data->crlf)
- buf = data->buffer; /* put it back on the buffer */
+ if(data->set.crlf)
+ buf = data->state.buffer; /* put it back on the buffer */
- nread = data->fread(buf, 1, conn->upload_bufsize, data->in);
+ nread = data->set.fread(buf, 1, conn->upload_bufsize, data->set.in);
/* the signed int typecase of nread of for systems that has
unsigned size_t */
Curl_pgrsSetUploadCounter(data, (double)writebytecount);
/* convert LF to CRLF if so asked */
- if (data->crlf) {
+ if (data->set.crlf) {
for(i = 0, si = 0; i < (int)nread; i++, si++) {
if (buf[i] == 0x0a) {
scratch[si++] = 0x0d;
conn->upload_bufsize=(long)min(data->progress.ulspeed, BUFSIZE);
}
- if (data->timeout && (Curl_tvdiff (now, start) > data->timeout)) {
+ if (data->set.timeout && (Curl_tvdiff (now, start) > data->set.timeout)) {
failf (data, "Operation timed out with %d out of %d bytes received",
bytecount, conn->size);
return CURLE_OPERATION_TIMEOUTED;
* returning.
*/
- if(!(data->bits.no_body) && contentlength &&
+ if(!(data->set.no_body) && contentlength &&
(bytecount != contentlength)) {
failf(data, "transfer closed with %d bytes remaining to read",
contentlength-bytecount);
return CURLE_OK;
}
-CURLcode Curl_perform(struct UrlData *data)
+CURLcode Curl_perform(struct SessionHandle *data)
{
CURLcode res;
struct connectdata *conn=NULL;
- bool port=TRUE; /* allow data->use_port to set port to use */
+ bool port=TRUE; /* allow data->set.use_port to set port to use */
char *newurl = NULL; /* possibly a new URL to follow to! */
- if(!data->url)
+ if(!data->change.url)
/* we can't do anything wihout URL */
return CURLE_URL_MALFORMAT;
/* Init the SSL session ID cache here. We do it here since we want to
do it after the *_setopt() calls (that could change the size) but
before any transfer. */
- Curl_SSL_InitSessions(data, data->ssl.numsessions);
+ Curl_SSL_InitSessions(data, data->set.ssl.numsessions);
#endif
- data->followlocation=0; /* reset the location-follow counter */
- data->bits.this_is_a_follow = FALSE; /* reset this */
+ data->set.followlocation=0; /* reset the location-follow counter */
+ data->state.this_is_a_follow = FALSE; /* reset this */
Curl_initinfo(data); /* reset session-specific information "variables" */
port=TRUE; /* by default we use the user set port number even after
a Location: */
- if (data->maxredirs && (data->followlocation >= data->maxredirs)) {
- failf(data,"Maximum (%d) redirects followed", data->maxredirs);
+ if (data->set.maxredirs && (data->set.followlocation >= data->set.maxredirs)) {
+ failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
res=CURLE_TOO_MANY_REDIRECTS;
break;
}
/* mark the next request as a followed location: */
- data->bits.this_is_a_follow = TRUE;
+ data->state.this_is_a_follow = TRUE;
- data->followlocation++; /* count location-followers */
+ data->set.followlocation++; /* count location-followers */
- if(data->bits.http_auto_referer) {
+ if(data->set.http_auto_referer) {
/* 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->free_referer) {
+ if(data->change.referer_alloc)
/* If we already have an allocated referer, free this first */
- free(data->referer);
- }
+ free(data->change.referer);
- data->referer = strdup(data->url);
- data->free_referer = TRUE; /* yes, free this later */
- data->bits.http_set_referer = TRUE; /* might have been false */
+ data->change.referer = strdup(data->change.url);
+ data->change.referer_alloc = TRUE; /* yes, free this later */
}
if(2 != sscanf(newurl, "%15[^:]://%c", prot, &letter)) {
/* we must make our own copy of the URL to play with, as it may
point to read-only data */
- char *url_clone=strdup(data->url);
+ char *url_clone=strdup(data->change.url);
if(!url_clone)
return CURLE_OUT_OF_MEMORY;
port = FALSE;
}
- if(data->bits.urlstringalloc)
- free(data->url);
+ if(data->change.url_alloc)
+ free(data->change.url);
+ else
+ data->change.url_alloc = TRUE; /* the URL is allocated */
/* TBD: set the URL with curl_setopt() */
- data->url = newurl;
+ data->change.url = newurl;
newurl = NULL; /* don't free! */
- data->bits.urlstringalloc = TRUE; /* the URL is allocated */
-
- infof(data, "Follows Location: to new URL: '%s'\n", data->url);
+ infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
/*
* We get here when the HTTP code is 300-399. We need to perform
* Discussed on the curl mailing list and posted about on the 26th
* of January 2001.
*/
- switch(data->progress.httpcode) {
+ switch(data->info.httpcode) {
case 300: /* Multiple Choices */
case 301: /* Moved Permanently */
case 306: /* Not used */
case 303: /* See Other */
/* Disable both types of POSTs, since doing a second POST when
* following isn't what anyone would want! */
- data->httpreq = HTTPREQ_GET; /* enforce GET request */
+ data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
infof(data, "Disables POST, goes with GET\n");
break;
case 304: /* Not Modified */
free(newurl);
/* make sure the alarm is switched off! */
- if(data->timeout || data->connecttimeout)
+ if(data->set.timeout || data->set.connecttimeout)
myalarm(0);
return res;
*
* $Id$
*****************************************************************************/
-CURLcode Curl_perform(struct UrlData *data);
+CURLcode Curl_perform(struct SessionHandle *data);
/* This sets up a forthcoming transfer */
CURLcode
#endif
/* Local static prototypes */
-static int ConnectionKillOne(struct UrlData *data);
-static bool ConnectionExists(struct UrlData *data,
+static int ConnectionKillOne(struct SessionHandle *data);
+static bool ConnectionExists(struct SessionHandle *data,
struct connectdata *needle,
struct connectdata **usethis);
-static unsigned int ConnectionStore(struct UrlData *data,
+static unsigned int ConnectionStore(struct SessionHandle *data,
struct connectdata *conn);
}
#endif
-CURLcode Curl_close(struct UrlData *data)
+CURLcode Curl_close(struct SessionHandle *data)
{
/* Loop through all open connections and kill them one by one */
while(-1 != ConnectionKillOne(data));
Curl_SSL_Close_All(data);
#endif
- if(data->bits.proxystringalloc) {
- data->bits.proxystringalloc=FALSE;;
- free(data->proxy);
- data->proxy=NULL;
+ if(data->change.proxy_alloc)
+ free(data->change.proxy);
+ if(data->change.referer_alloc)
+ free(data->change.referer);
+ if(data->change.url_alloc)
+ free(data->change.url);
- /* Since we allocated the string the previous round, it means that we
- "discovered" the proxy in the environment variables and thus we must
- switch off that knowledge again... */
- data->bits.httpproxy=FALSE;
- }
-
- /* check for allocated [URL] memory to free: */
- if(data->freethis)
- free(data->freethis);
-
- if(data->headerbuff)
- free(data->headerbuff);
+ if(data->state.headerbuff)
+ free(data->state.headerbuff);
- if(data->free_referer)
- free(data->referer);
- if(data->bits.urlstringalloc)
- /* the URL is allocated, free it! */
- free(data->url);
-
- if(data->cookiejar)
+ if(data->set.cookiejar)
/* we have a "destination" for all the cookies to get dumped to */
- Curl_cookie_output(data->cookies, data->cookiejar);
+ Curl_cookie_output(data->cookies, data->set.cookiejar);
Curl_cookie_cleanup(data->cookies);
/* free the connection cache */
- free(data->connects);
+ free(data->state.connects);
free(data);
return CURLE_OK;
}
-CURLcode Curl_open(struct UrlData **curl)
+CURLcode Curl_open(struct SessionHandle **curl)
{
/* We don't yet support specifying the URL at this point */
- struct UrlData *data;
+ struct SessionHandle *data;
#ifdef HAVE_SIGACTION
struct sigaction sigact;
#endif
/* Very simple start-up: alloc the struct, init it with zeroes and return */
- data = (struct UrlData *)malloc(sizeof(struct UrlData));
+ data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle));
if(data) {
- memset(data, 0, sizeof(struct UrlData));
+ memset(data, 0, sizeof(struct SessionHandle));
/* We do some initial setup here, all those fields that can't be just 0 */
- data-> headerbuff=(char*)malloc(HEADERSIZE);
- if(!data->headerbuff) {
+ data->state.headerbuff=(char*)malloc(HEADERSIZE);
+ if(!data->state.headerbuff) {
free(data); /* free the memory again */
return CURLE_OUT_OF_MEMORY;
}
- data->headersize=HEADERSIZE;
+ data->state.headersize=HEADERSIZE;
- data->out = stdout; /* default output to stdout */
- data->in = stdin; /* default input from stdin */
- data->err = stderr; /* default stderr to stderr */
+ data->set.out = stdout; /* default output to stdout */
+ data->set.in = stdin; /* default input from stdin */
+ data->set.err = stderr; /* default stderr to stderr */
/* use fwrite as default function to store output */
- data->fwrite = (curl_write_callback)fwrite;
+ data->set.fwrite = (curl_write_callback)fwrite;
/* use fread as default function to read input */
- data->fread = (curl_read_callback)fread;
+ data->set.fread = (curl_read_callback)fread;
/* set the default passwd function */
- data->fpasswd = my_getpass;
+ data->set.fpasswd = my_getpass;
- data->infilesize = -1; /* we don't know any size */
+ data->set.infilesize = -1; /* we don't know any size */
- data->current_speed = -1; /* init to negative == impossible */
+ data->state.current_speed = -1; /* init to negative == impossible */
- data->httpreq = HTTPREQ_GET; /* Default HTTP request */
+ data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
/* make libcurl quiet by default: */
- data->bits.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
+ data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
data->progress.flags |= PGRS_HIDE;
/* Set the default size of the SSL session ID cache */
- data->ssl.numsessions = 5;
+ data->set.ssl.numsessions = 5;
/* create an array with connection data struct pointers */
- data->numconnects = 5; /* hard-coded right now */
- data->connects = (struct connectdata **)
- malloc(sizeof(struct connectdata *) * data->numconnects);
+ data->state.numconnects = 5; /* hard-coded right now */
+ data->state.connects = (struct connectdata **)
+ malloc(sizeof(struct connectdata *) * data->state.numconnects);
- if(!data->connects) {
+ if(!data->state.connects) {
free(data);
return CURLE_OUT_OF_MEMORY;
}
- memset(data->connects, 0, sizeof(struct connectdata *)*data->numconnects);
+ memset(data->state.connects, 0,
+ sizeof(struct connectdata *)*data->state.numconnects);
*curl = data;
return CURLE_OUT_OF_MEMORY;
}
-CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...)
+CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
{
va_list param;
char *cookiefile;
* This is the path name to a file that contains random data to seed
* the random SSL stuff with. The file is only used for reading.
*/
- data->ssl.random_file = va_arg(param, char *);
+ data->set.ssl.random_file = va_arg(param, char *);
break;
case CURLOPT_EGDSOCKET:
/*
* The Entropy Gathering Daemon socket pathname
*/
- data->ssl.egdsocket = va_arg(param, char *);
+ data->set.ssl.egdsocket = va_arg(param, char *);
break;
case CURLOPT_MAXCONNECTS:
/*
long newconnects= va_arg(param, long);
struct connectdata **newptr;
- if(newconnects < data->numconnects) {
+ if(newconnects < data->state.numconnects) {
/* Since this number is *decreased* from the existing number, we must
close the possibly open connections that live on the indexes that
are being removed! */
int i;
- for(i=newconnects; i< data->numconnects; i++)
- Curl_disconnect(data->connects[i]);
+ for(i=newconnects; i< data->state.numconnects; i++)
+ Curl_disconnect(data->state.connects[i]);
}
if(newconnects) {
newptr= (struct connectdata **)
- realloc(data->connects,
+ realloc(data->state.connects,
sizeof(struct connectdata *) * newconnects);
if(!newptr)
/* we closed a few connections in vain, but so what? */
return CURLE_OUT_OF_MEMORY;
- data->connects = newptr;
- data->numconnects = newconnects;
+ data->state.connects = newptr;
+ data->state.numconnects = newconnects;
}
else {
/* zero makes NO cache at all */
- if(data->connects)
- free(data->connects);
- data->connects=NULL;
- data->numconnects=0;
+ if(data->state.connects)
+ free(data->state.connects);
+ data->state.connects=NULL;
+ data->state.numconnects=0;
}
}
break;
* When this transfer is done, it must not be left to be reused by a
* subsequent transfer but shall be closed immediately.
*/
- data->bits.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
+ data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_FRESH_CONNECT:
/*
* This transfer shall not use a previously cached connection but
* should be made with a fresh new connect!
*/
- data->bits.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
+ data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_VERBOSE:
/*
* Verbose means infof() calls that give a lot of information about
* the connection and transfer procedures as well as internal choices.
*/
- data->bits.verbose = va_arg(param, long)?TRUE:FALSE;
+ data->set.verbose = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_HEADER:
/*
* Set to include the header in the general data output stream.
*/
- data->bits.http_include_header = va_arg(param, long)?TRUE:FALSE;
+ data->set.http_include_header = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_NOPROGRESS:
/*
* Shut off the internal supported progress meter
*/
- data->bits.hide_progress = va_arg(param, long)?TRUE:FALSE;
- if(data->bits.hide_progress)
+ data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
+ if(data->set.hide_progress)
data->progress.flags |= PGRS_HIDE;
else
data->progress.flags &= ~PGRS_HIDE;
/*
* Do not include the body part in the output data stream.
*/
- data->bits.no_body = va_arg(param, long)?TRUE:FALSE;
+ data->set.no_body = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_FAILONERROR:
/*
* Don't output the >=300 error code HTML-page, but instead only
* return error.
*/
- data->bits.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
+ data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_UPLOAD:
/*
* We want to sent data to the remote host
*/
- data->bits.upload = va_arg(param, long)?TRUE:FALSE;
- if(data->bits.upload)
+ data->set.upload = va_arg(param, long)?TRUE:FALSE;
+ if(data->set.upload)
/* If this is HTTP, PUT is what's needed to "upload" */
- data->httpreq = HTTPREQ_PUT;
+ data->set.httpreq = HTTPREQ_PUT;
break;
case CURLOPT_FILETIME:
/*
* Try to get the file time of the remote document. The time will
* later (possibly) become available using curl_easy_getinfo().
*/
- data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE;
+ data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_FTPLISTONLY:
/*
* An FTP option that changes the command to one that asks for a list
* only, no file info details.
*/
- data->bits.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
+ data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_FTPAPPEND:
/*
* We want to upload and append to an existing (FTP) file.
*/
- data->bits.ftp_append = va_arg(param, long)?TRUE:FALSE;
+ data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_NETRC:
/*
* Parse the $HOME/.netrc file
*/
- data->bits.use_netrc = va_arg(param, long)?TRUE:FALSE;
+ data->set.use_netrc = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_FOLLOWLOCATION:
/*
* Follow Location: header hints on a HTTP-server.
*/
- data->bits.http_follow_location = va_arg(param, long)?TRUE:FALSE;
+ data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_TRANSFERTEXT:
/*
*
* Transfer using ASCII (instead of BINARY).
*/
- data->bits.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
+ data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_PUT:
/*
* FALSE, don't set the httpreq. We can't know what to revert it to!
*/
if(va_arg(param, long))
- data->httpreq = HTTPREQ_PUT;
+ data->set.httpreq = HTTPREQ_PUT;
break;
#if 0
/* obsolete stuff, kept here a while for informational purposes */
/*
* Stay absolutely quiet.
*/
- data->bits.mute = va_arg(param, long)?TRUE:FALSE;
+ data->set.mute = va_arg(param, long)?TRUE:FALSE;
break;
#endif
case CURLOPT_TIMECONDITION:
* Set HTTP time condition. This must be one of the defines in the
* curl/curl.h header file.
*/
- data->timecondition = va_arg(param, long);
+ data->set.timecondition = va_arg(param, long);
break;
case CURLOPT_TIMEVALUE:
/*
* This is the value to compare with the remote document with the
* method set with CURLOPT_TIMECONDITION
*/
- data->timevalue = va_arg(param, long);
+ data->set.timevalue = va_arg(param, long);
break;
case CURLOPT_SSLVERSION:
/*
* Set explicit SSL version to try to connect with, as some SSL
* implementations are lame.
*/
- data->ssl.version = va_arg(param, long);
+ data->set.ssl.version = va_arg(param, long);
break;
case CURLOPT_COOKIEFILE:
/*
* Set cookie file name to dump all cookies to when we're done.
*/
- data->cookiejar = cookiefile = (char *)va_arg(param, void *);
+ data->set.cookiejar = cookiefile = (char *)va_arg(param, void *);
break;
case CURLOPT_WRITEHEADER:
/*
* Custom pointer to pass the header write callback function
*/
- data->writeheader = (void *)va_arg(param, void *);
+ data->set.writeheader = (void *)va_arg(param, void *);
break;
case CURLOPT_COOKIE:
/*
* Cookie string to send to the remote server in the request.
*/
- data->cookie = va_arg(param, char *);
+ data->set.cookie = va_arg(param, char *);
break;
case CURLOPT_ERRORBUFFER:
/*
* Error buffer provided by the caller to get the human readable
* error string in.
*/
- data->errorbuffer = va_arg(param, char *);
+ data->set.errorbuffer = va_arg(param, char *);
break;
case CURLOPT_FILE:
/*
* FILE pointer to write to or include in the data write callback
*/
- data->out = va_arg(param, FILE *);
+ data->set.out = va_arg(param, FILE *);
break;
case CURLOPT_FTPPORT:
/*
* Use FTP PORT, this also specifies which IP address to use
*/
- data->ftpport = va_arg(param, char *);
- data->bits.ftp_use_port = data->ftpport?1:0;
+ data->set.ftpport = va_arg(param, char *);
+ data->set.ftp_use_port = data->set.ftpport?1:0;
break;
case CURLOPT_HTTPHEADER:
/*
* Set a list with HTTP headers to use (or replace internals with)
*/
- data->headers = va_arg(param, struct curl_slist *);
+ data->set.headers = va_arg(param, struct curl_slist *);
break;
case CURLOPT_CUSTOMREQUEST:
/*
* Set a custom string to use as request
*/
- data->customrequest = va_arg(param, char *);
- if(data->customrequest)
- data->httpreq = HTTPREQ_CUSTOM;
+ data->set.customrequest = va_arg(param, char *);
+ if(data->set.customrequest)
+ data->set.httpreq = HTTPREQ_CUSTOM;
break;
case CURLOPT_HTTPPOST:
/*
* Set to make us do HTTP POST
*/
- data->httppost = va_arg(param, struct HttpPost *);
- if(data->httppost)
- data->httpreq = HTTPREQ_POST_FORM;
+ data->set.httppost = va_arg(param, struct HttpPost *);
+ if(data->set.httppost)
+ data->set.httpreq = HTTPREQ_POST_FORM;
break;
case CURLOPT_HTTPGET:
* Set to force us do HTTP GET
*/
if(va_arg(param, long))
- data->httpreq = HTTPREQ_GET;
+ data->set.httpreq = HTTPREQ_GET;
break;
case CURLOPT_INFILE:
* FILE pointer to read the file to be uploaded from. Or possibly
* used as argument to the read callback.
*/
- data->in = va_arg(param, FILE *);
+ data->set.in = va_arg(param, FILE *);
break;
case CURLOPT_INFILESIZE:
/*
* If known, this should inform curl about the file size of the
* to-be-uploaded file.
*/
- data->infilesize = va_arg(param, long);
+ data->set.infilesize = va_arg(param, long);
break;
case CURLOPT_LOW_SPEED_LIMIT:
/*
* The low speed limit that if transfers are below this for
* CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
*/
- data->low_speed_limit=va_arg(param, long);
+ data->set.low_speed_limit=va_arg(param, long);
break;
case CURLOPT_LOW_SPEED_TIME:
/*
* The low speed time that if transfers are below the set
* CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
*/
- data->low_speed_time=va_arg(param, long);
+ data->set.low_speed_time=va_arg(param, long);
break;
case CURLOPT_URL:
/*
* The URL to fetch.
*/
- if(data->bits.urlstringalloc) {
+ if(data->change.url_alloc) {
/* the already set URL is allocated, free it first! */
- free(data->url);
- data->bits.urlstringalloc=FALSE;
+ free(data->change.url);
+ data->change.url_alloc=FALSE;
}
- data->url = va_arg(param, char *);
+ data->set.set_url = va_arg(param, char *);
+ data->change.url = data->set.set_url;
break;
case CURLOPT_PORT:
/*
* The port number to use when getting the URL
*/
- data->use_port = va_arg(param, long);
+ data->set.use_port = va_arg(param, long);
break;
case CURLOPT_POST:
/* Does this option serve a purpose anymore? */
if(va_arg(param, long))
- data->httpreq = HTTPREQ_POST;
+ data->set.httpreq = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDS:
/*
* A string with POST data. Makes curl HTTP POST.
*/
- data->postfields = va_arg(param, char *);
- if(data->postfields)
- data->httpreq = HTTPREQ_POST;
+ data->set.postfields = va_arg(param, char *);
+ if(data->set.postfields)
+ data->set.httpreq = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDSIZE:
/*
* The size of the POSTFIELD data, if curl should now do a strlen
* to find out. Enables binary posts.
*/
- data->postfieldsize = va_arg(param, long);
+ data->set.postfieldsize = va_arg(param, long);
break;
case CURLOPT_REFERER:
/*
* String to set in the HTTP Referer: field.
*/
- data->referer = va_arg(param, char *);
- data->bits.http_set_referer = (data->referer && *data->referer)?1:0;
+ if(data->change.referer_alloc) {
+ free(data->change.referer);
+ data->change.referer_alloc = FALSE;
+ }
+ data->set.set_referer = va_arg(param, char *);
+ data->change.referer = data->set.set_referer;
break;
case CURLOPT_AUTOREFERER:
/*
* Switch on automatic referer that gets set if curl follows locations.
*/
- data->bits.http_auto_referer = va_arg(param, long)?1:0;
+ data->set.http_auto_referer = va_arg(param, long)?1:0;
break;
case CURLOPT_PROXY:
/*
* Set proxy server:port to use as HTTP proxy
*/
- if(data->bits.proxystringalloc) {
+ if(data->change.proxy_alloc) {
/*
* The already set string is allocated, free that first
*/
- data->bits.proxystringalloc=FALSE;;
- free(data->proxy);
+ data->change.proxy_alloc=FALSE;;
+ free(data->change.proxy);
}
- data->proxy = va_arg(param, char *);
- data->bits.httpproxy = data->proxy?1:0;
+ data->set.set_proxy = va_arg(param, char *);
+ data->change.proxy = data->set.set_proxy;
break;
case CURLOPT_HTTPPROXYTUNNEL:
/*
* Tunnel operations through the proxy instead of normal proxy use
*/
- data->bits.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
+ data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_PROXYPORT:
/*
* Explicitly set HTTP proxy port number.
*/
- data->proxyport = va_arg(param, long);
+ data->set.proxyport = va_arg(param, long);
break;
case CURLOPT_TIMEOUT:
/*
* The maximum time you allow curl to use for a single transfer
* operation.
*/
- data->timeout = va_arg(param, long);
+ data->set.timeout = va_arg(param, long);
break;
case CURLOPT_CONNECTTIMEOUT:
/*
* The maximum time you allow curl to use to connect.
*/
- data->connecttimeout = va_arg(param, long);
+ data->set.connecttimeout = va_arg(param, long);
break;
case CURLOPT_MAXREDIRS:
/*
* The maximum amount of hops you allow curl to follow Location:
* headers. This should mostly be used to detect never-ending loops.
*/
- data->maxredirs = va_arg(param, long);
+ data->set.maxredirs = va_arg(param, long);
break;
case CURLOPT_USERAGENT:
/*
* String to use in the HTTP User-Agent field
*/
- data->useragent = va_arg(param, char *);
+ data->set.useragent = va_arg(param, char *);
break;
case CURLOPT_USERPWD:
/*
* user:password to use in the operation
*/
- data->userpwd = va_arg(param, char *);
+ data->set.userpwd = va_arg(param, char *);
break;
case CURLOPT_POSTQUOTE:
/*
* List of RAW FTP commands to use after a transfer
*/
- data->postquote = va_arg(param, struct curl_slist *);
+ data->set.postquote = va_arg(param, struct curl_slist *);
break;
case CURLOPT_QUOTE:
/*
* List of RAW FTP commands to use before a transfer
*/
- data->quote = va_arg(param, struct curl_slist *);
+ data->set.quote = va_arg(param, struct curl_slist *);
break;
case CURLOPT_PROGRESSFUNCTION:
/*
* Progress callback function
*/
- data->fprogress = va_arg(param, curl_progress_callback);
+ data->set.fprogress = va_arg(param, curl_progress_callback);
data->progress.callback = TRUE; /* no longer internal */
break;
case CURLOPT_PROGRESSDATA:
/*
* Custom client data to pass to the progress callback
*/
- data->progress_client = va_arg(param, void *);
+ data->set.progress_client = va_arg(param, void *);
break;
case CURLOPT_PASSWDFUNCTION:
/*
* Password prompt callback
*/
- data->fpasswd = va_arg(param, curl_passwd_callback);
+ data->set.fpasswd = va_arg(param, curl_passwd_callback);
break;
case CURLOPT_PASSWDDATA:
/*
* Custom client data to pass to the password callback
*/
- data->passwd_client = va_arg(param, void *);
+ data->set.passwd_client = va_arg(param, void *);
break;
case CURLOPT_PROXYUSERPWD:
/*
* user:password needed to use the proxy
*/
- data->proxyuserpwd = va_arg(param, char *);
+ data->set.proxyuserpwd = va_arg(param, char *);
break;
case CURLOPT_RANGE:
/*
* What range of the file you want to transfer
*/
- data->set_range = va_arg(param, char *);
- data->bits.set_range = data->set_range?1:0;
+ data->set.set_range = va_arg(param, char *);
break;
case CURLOPT_RESUME_FROM:
/*
* Resume transfer at the give file position
*/
- data->set_resume_from = va_arg(param, long);
+ data->set.set_resume_from = va_arg(param, long);
break;
case CURLOPT_STDERR:
/*
* Set to a FILE * that should receive all error writes. This
* defaults to stderr for normal operations.
*/
- data->err = va_arg(param, FILE *);
+ data->set.err = va_arg(param, FILE *);
break;
case CURLOPT_HEADERFUNCTION:
/*
* Set header write callback
*/
- data->fwrite_header = va_arg(param, curl_write_callback);
+ data->set.fwrite_header = va_arg(param, curl_write_callback);
break;
case CURLOPT_WRITEFUNCTION:
/*
* Set data write callback
*/
- data->fwrite = va_arg(param, curl_write_callback);
+ data->set.fwrite = va_arg(param, curl_write_callback);
break;
case CURLOPT_READFUNCTION:
/*
* Read data callback
*/
- data->fread = va_arg(param, curl_read_callback);
+ data->set.fread = va_arg(param, curl_read_callback);
break;
case CURLOPT_SSLCERT:
/*
* String that holds file name of the SSL certificate to use
*/
- data->cert = va_arg(param, char *);
+ data->set.cert = va_arg(param, char *);
break;
case CURLOPT_SSLCERTPASSWD:
/*
* String that holds the SSL certificate password.
*/
- data->cert_passwd = va_arg(param, char *);
+ data->set.cert_passwd = va_arg(param, char *);
break;
case CURLOPT_CRLF:
/*
- * Kludgy option to enable CRLF convertions. Subject for
- * removal.
+ * Kludgy option to enable CRLF convertions. Subject for removal.
*/
- data->crlf = va_arg(param, long);
+ data->set.crlf = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_INTERFACE:
/*
* Set what interface to bind to when performing an operation and thus
* what from-IP your connection will use.
*/
- data->device = va_arg(param, char *);
+ data->set.device = va_arg(param, char *);
break;
case CURLOPT_KRB4LEVEL:
/*
* A string that defines the krb4 security level.
*/
- data->krb4_level = va_arg(param, char *);
- data->bits.krb4=data->krb4_level?TRUE:FALSE;
+ data->set.krb4_level = va_arg(param, char *);
+ data->set.krb4=data->set.krb4_level?TRUE:FALSE;
break;
case CURLOPT_SSL_VERIFYPEER:
/*
* Enable peer SSL verifying.
*/
- data->ssl.verifypeer = va_arg(param, long);
+ data->set.ssl.verifypeer = va_arg(param, long);
break;
case CURLOPT_SSL_VERIFYHOST:
/*
* Enable verification of the CN contained in the peer certificate
*/
- data->ssl.verifyhost = va_arg(param, long);
+ data->set.ssl.verifyhost = va_arg(param, long);
break;
case CURLOPT_CAINFO:
/*
* Set CA info for SSL connection. Specify file name of the CA certificate
*/
- data->ssl.CAfile = va_arg(param, char *);
- data->ssl.CApath = NULL; /*This does not work on windows.*/
+ data->set.ssl.CAfile = va_arg(param, char *);
+ data->set.ssl.CApath = NULL; /*This does not work on windows.*/
break;
case CURLOPT_TELNETOPTIONS:
/*
* Set a linked list of telnet options
*/
- data->telnet_options = va_arg(param, struct curl_slist *);
+ data->set.telnet_options = va_arg(param, struct curl_slist *);
break;
default:
/* unknown tag and its companion, just ignore: */
if(-1 != conn->connectindex) {
/* unlink ourselves! */
infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex);
- conn->data->connects[conn->connectindex] = NULL;
+ conn->data->state.connects[conn->connectindex] = NULL;
}
if(conn->curl_disconnect)
* thus should be used instead.
*/
static bool
-ConnectionExists(struct UrlData *data,
+ConnectionExists(struct SessionHandle *data,
struct connectdata *needle,
struct connectdata **usethis)
{
long i;
struct connectdata *check;
- for(i=0; i< data->numconnects; i++) {
+ for(i=0; i< data->state.numconnects; i++) {
/*
* Note that if we use a HTTP proxy, we check connections to that
* proxy and not to the actual remote server.
*/
- check = data->connects[i];
+ check = data->state.connects[i];
if(!check)
/* NULL pointer means not filled-in entry */
continue;
if(strequal(needle->protostr, "FTP")) {
/* This is FTP, verify that we're using the same name and
password as well */
- if(!strequal(needle->data->user, check->proto.ftp->user) ||
- !strequal(needle->data->passwd, check->proto.ftp->passwd)) {
+ if(!strequal(needle->data->state.user, check->proto.ftp->user) ||
+ !strequal(needle->data->state.passwd, check->proto.ftp->passwd)) {
/* one of them was different */
continue;
}
if(dead) {
infof(data, "Connection %d seems to be dead!\n", i);
Curl_disconnect(check); /* disconnect resources */
- data->connects[i]=NULL; /* nothing here */
+ data->state.connects[i]=NULL; /* nothing here */
continue; /* try another one now */
}
* of the connections to kill.
*/
static int
-ConnectionKillOne(struct UrlData *data)
+ConnectionKillOne(struct SessionHandle *data)
{
long i;
struct connectdata *conn;
now = Curl_tvnow();
- for(i=0; i< data->numconnects; i++) {
- conn = data->connects[i];
+ for(i=0; i< data->state.numconnects; i++) {
+ conn = data->state.connects[i];
if(!conn)
continue;
/*
* By using the set policy, we score each connection.
*/
- switch(data->closepolicy) {
+ switch(data->set.closepolicy) {
case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
default:
/*
if(connindex >= 0) {
/* the winner gets the honour of being disconnected */
- result = Curl_disconnect(data->connects[connindex]);
+ result = Curl_disconnect(data->state.connects[connindex]);
/* clean the array entry */
- data->connects[connindex] = NULL;
+ data->state.connects[connindex] = NULL;
}
return connindex; /* return the available index or -1 */
* this call.
*/
static unsigned int
-ConnectionStore(struct UrlData *data,
+ConnectionStore(struct SessionHandle *data,
struct connectdata *conn)
{
long i;
- for(i=0; i< data->numconnects; i++) {
- if(!data->connects[i])
+ for(i=0; i< data->state.numconnects; i++) {
+ if(!data->state.connects[i])
break;
}
- if(i == data->numconnects) {
+ if(i == data->state.numconnects) {
/* there was no room available, kill one */
i = ConnectionKillOne(data);
infof(data, "Connection (#%d) was killed to make room\n", i);
}
- data->connects[i] = conn; /* fill in this */
+ data->state.connects[i] = conn; /* fill in this */
conn->connectindex = i; /* make the child know where the pointer to this
particular data is stored */
return i;
}
-static CURLcode ConnectPlease(struct UrlData *data,
+static CURLcode ConnectPlease(struct SessionHandle *data,
struct connectdata *conn)
{
#if defined(WIN32)
/*************************************************************
* Select device to bind socket to
*************************************************************/
- if (data->device && (strlen(data->device)<255)) {
+ if (data->set.device && (strlen(data->set.device)<255)) {
struct sockaddr_in sa;
struct hostent *h=NULL;
char *hostdataptr=NULL;
char myhost[256] = "";
unsigned long in;
- if(Curl_if2ip(data->device, myhost, sizeof(myhost))) {
+ if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
h = Curl_gethost(data, myhost, &hostdataptr);
}
else {
- if(strlen(data->device)>1) {
- h = Curl_gethost(data, data->device, &hostdataptr);
+ if(strlen(data->set.device)>1) {
+ h = Curl_gethost(data, data->set.device, &hostdataptr);
}
if(h) {
- /* we know data->device is shorter than the myhost array */
- strcpy(myhost, data->device);
+ /* we know data->set.device is shorter than the myhost array */
+ strcpy(myhost, data->set.device);
}
}
#if defined(WIN32)
FD_ZERO (&connectfd);
FD_SET(conn->firstsocket, &connectfd);
- if (conn->data->connecttimeout > 0) {
+ if (conn->data->set.connecttimeout > 0) {
nonblock = 1;
}
ioctlsocket(conn->firstsocket, FIONBIO, &nonblock);
sizeof(conn->serv_addr)
) < 0) {
#if defined(WIN32)
- conntimeout.tv_sec = conn->data->connecttimeout;
+ conntimeout.tv_sec = conn->data->set.connecttimeout;
conntimeout.tv_usec = 0;
if(-1 != select (conn->firstsocket + 1, NULL, &connectfd, NULL, &conntimeout)) {
if (FD_ISSET(conn->firstsocket, &connectfd)) {
return CURLE_OK;
}
-static CURLcode Connect(struct UrlData *data,
+static CURLcode Connect(struct SessionHandle *data,
struct connectdata **in_connect,
- bool allow_port) /* allow data->use_port ? */
+ bool allow_port) /* allow data->set.use_port ? */
{
char *tmp;
char *buf;
* Check input data
*************************************************************/
- if(!data->url)
+ if(!data->change.url)
return CURLE_URL_MALFORMAT;
/* First, split up the current URL in parts so that we can use the
conn->firstsocket = -1; /* no file descriptor */
conn->secondarysocket = -1; /* no file descriptor */
conn->connectindex = -1; /* no index */
- conn->bits.httpproxy = data->bits.httpproxy; /* proxy-or-not status */
- conn->bits.use_range = data->bits.set_range; /* range status */
- conn->range = data->set_range; /* clone the range setting */
- conn->resume_from = data->set_resume_from; /* inherite resume_from */
+ conn->bits.httpproxy = data->change.proxy?TRUE:FALSE; /* proxy-or-not */
+ conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
+ conn->range = data->set.set_range; /* clone the range setting */
+ conn->resume_from = data->set.set_resume_from; /* inherite resume_from */
/* Default protocol-independent behavior doesn't support persistant
connections, so we set this to force-close. Protocols that support
conn->bits.close = TRUE;
/* inherite initial knowledge from the data struct */
- conn->bits.user_passwd = data->userpwd?1:0;
- conn->bits.proxy_user_passwd = data->proxyuserpwd?1:0;
+ conn->bits.user_passwd = data->set.userpwd?1:0;
+ conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
/* maxdownload must be -1 on init, as 0 is a valid value! */
conn->maxdownload = -1; /* might have been used previously! */
* other parts of the code will rely on this fact
***********************************************************/
#define LEAST_PATH_ALLOC 256
- urllen=strlen(data->url);
+ urllen=strlen(data->change.url);
if(urllen < LEAST_PATH_ALLOC)
urllen=LEAST_PATH_ALLOC;
* proxy -- and we don't know if we will need to use SSL until we parse the
* url ...
************************************************************/
- if((2 == sscanf(data->url, "%64[^:]://%[^\n]",
+ if((2 == sscanf(data->change.url, "%64[^:]://%[^\n]",
conn->protostr,
conn->path)) && strequal(conn->protostr, "file")) {
/*
strcpy(conn->gname, "curl.haxx.se");
strcpy(conn->path, "/");
- if (2 > sscanf(data->url,
+ if (2 > sscanf(data->change.url,
"%64[^\n:]://%256[^\n/]%[^\n]",
conn->protostr, conn->gname, conn->path)) {
* The URL was badly formatted, let's try the browser-style _without_
* protocol specified like 'http://'.
*/
- if((1 > sscanf(data->url, "%256[^\n/]%[^\n]",
+ if((1 > sscanf(data->change.url, "%256[^\n/]%[^\n]",
conn->gname, conn->path)) ) {
/*
* We couldn't even get this format.
}
}
- buf = data->buffer; /* this is our buffer */
+ buf = data->state.buffer; /* this is our buffer */
/*************************************************************
* Take care of user and password authentication stuff
*************************************************************/
- if(conn->bits.user_passwd && !data->bits.use_netrc) {
- data->user[0] =0;
- data->passwd[0]=0;
+ if(conn->bits.user_passwd && !data->set.use_netrc) {
+ data->state.user[0] =0;
+ data->state.passwd[0]=0;
- if(*data->userpwd != ':') {
+ if(*data->set.userpwd != ':') {
/* the name is given, get user+password */
- sscanf(data->userpwd, "%127[^:]:%127[^\n]",
- data->user, data->passwd);
+ sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
+ data->state.user, data->state.passwd);
}
else
/* no name given, get the password only */
- sscanf(data->userpwd+1, "%127[^\n]", data->passwd);
+ sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
/* check for password, if no ask for one */
- if( !data->passwd[0] ) {
- if(!data->fpasswd ||
- data->fpasswd(data->passwd_client,
- "password:", data->passwd, sizeof(data->passwd)))
+ if( !data->state.passwd[0] ) {
+ if(!data->set.fpasswd ||
+ data->set.fpasswd(data->set.passwd_client,
+ "password:", data->state.passwd,
+ sizeof(data->state.passwd)))
return CURLE_BAD_PASSWORD_ENTERED;
}
}
* Take care of proxy authentication stuff
*************************************************************/
if(conn->bits.proxy_user_passwd) {
- data->proxyuser[0] =0;
- data->proxypasswd[0]=0;
+ data->state.proxyuser[0] =0;
+ data->state.proxypasswd[0]=0;
- if(*data->proxyuserpwd != ':') {
+ if(*data->set.proxyuserpwd != ':') {
/* the name is given, get user+password */
- sscanf(data->proxyuserpwd, "%127[^:]:%127[^\n]",
- data->proxyuser, data->proxypasswd);
+ sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
+ data->state.proxyuser, data->state.proxypasswd);
}
else
/* no name given, get the password only */
- sscanf(data->proxyuserpwd+1, "%127[^\n]", data->proxypasswd);
+ sscanf(data->set.proxyuserpwd+1, "%127[^\n]", data->state.proxypasswd);
/* check for password, if no ask for one */
- if( !data->proxypasswd[0] ) {
- if(!data->fpasswd ||
- data->fpasswd( data->passwd_client,
+ if( !data->state.proxypasswd[0] ) {
+ if(!data->set.fpasswd ||
+ data->set.fpasswd( data->set.passwd_client,
"proxy password:",
- data->proxypasswd,
- sizeof(data->proxypasswd)))
+ data->state.proxypasswd,
+ sizeof(data->state.proxypasswd)))
return CURLE_BAD_PASSWORD_ENTERED;
}
/*************************************************************
* Detect what (if any) proxy to use
*************************************************************/
- if(!data->bits.httpproxy) {
+ if(!data->change.proxy) {
/* If proxy was not specified, we check for default proxy environment
* variables, to enable i.e Lynx compliance:
*
if(proxy && *proxy) {
/* we have a proxy here to set */
- data->proxy = proxy;
- data->bits.proxystringalloc=1; /* this needs to be freed later */
- data->bits.httpproxy=1;
+ data->change.proxy = proxy;
+ data->change.proxy_alloc=TRUE; /* this needs to be freed later */
}
} /* if (!nope) - it wasn't specified non-proxy */
} /* NO_PROXY wasn't specified or '*' */
/*************************************************************
* No protocol but proxy usage needs attention
*************************************************************/
- if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) {
+ if((conn->protocol&PROT_MISSING) && data->change.proxy ) {
/* We're guessing prefixes here and since we're told to use a proxy, we
need to add the protocol prefix to the URL string before we continue!
*/
char *reurl;
- reurl = aprintf("%s://%s", conn->protostr, data->url);
+ reurl = aprintf("%s://%s", conn->protostr, data->change.url);
if(!reurl)
return CURLE_OUT_OF_MEMORY;
- data->url = reurl;
- if(data->freethis)
- free(data->freethis);
- data->freethis = reurl;
-
+ data->change.url = reurl;
+ data->change.url_alloc = TRUE; /* free this later */
conn->protocol &= ~PROT_MISSING; /* switch that one off again */
}
/*************************************************************
* Set timeout if that is being used
*************************************************************/
- if(data->timeout || data->connecttimeout) {
+ if(data->set.timeout || data->set.connecttimeout) {
/* We set the timeout on the connection/resolving phase first, separately
* from the download/upload part to allow a maximum time on everything */
/* myalarm() makes a signal get sent when the timeout fires off, and that
will abort system calls */
- if(data->connecttimeout)
- myalarm(data->connecttimeout);
+ if(data->set.connecttimeout)
+ myalarm(data->set.connecttimeout);
else
- myalarm(data->timeout);
+ myalarm(data->set.timeout);
}
/*************************************************************
*************************************************************/
if (strequal(conn->protostr, "HTTP")) {
- conn->port = (data->use_port && allow_port)?data->use_port:PORT_HTTP;
+ conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTP;
conn->remote_port = PORT_HTTP;
conn->protocol |= PROT_HTTP;
conn->curl_do = Curl_http;
else if (strequal(conn->protostr, "HTTPS")) {
#ifdef USE_SSLEAY
- conn->port = (data->use_port && allow_port)?data->use_port:PORT_HTTPS;
+ conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTPS;
conn->remote_port = PORT_HTTPS;
conn->protocol |= PROT_HTTP;
conn->protocol |= PROT_HTTPS;
#endif /* !USE_SSLEAY */
}
else if (strequal(conn->protostr, "GOPHER")) {
- conn->port = (data->use_port && allow_port)?data->use_port:PORT_GOPHER;
+ conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_GOPHER;
conn->remote_port = PORT_GOPHER;
/* Skip /<item-type>/ in path if present */
if (isdigit((int)conn->path[1])) {
#endif /* !USE_SSLEAY */
}
- conn->port = (data->use_port && allow_port)?data->use_port:PORT_FTP;
+ conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_FTP;
conn->remote_port = PORT_FTP;
conn->protocol |= PROT_FTP;
- if(data->bits.httpproxy &&
- !data->bits.tunnel_thru_httpproxy) {
+ if(data->change.proxy &&
+ !data->set.tunnel_thru_httpproxy) {
/* Unless we have asked to tunnel ftp operations through the proxy, we
switch and use HTTP operations only */
if(conn->protocol & PROT_FTPS) {
command = toupper(type[6]);
switch(command) {
case 'A': /* ASCII mode */
- data->bits.ftp_ascii = 1;
+ data->set.ftp_ascii = 1;
break;
case 'D': /* directory mode */
- data->bits.ftp_list_only = 1;
+ data->set.ftp_list_only = 1;
break;
case 'I': /* binary mode */
default:
/* switch off ASCII */
- data->bits.ftp_ascii = 0;
+ data->set.ftp_ascii = 0;
break;
}
}
/* telnet testing factory */
conn->protocol |= PROT_TELNET;
- conn->port = (data->use_port && allow_port)?data->use_port: PORT_TELNET;
+ conn->port = (data->set.use_port && allow_port)?data->set.use_port: PORT_TELNET;
conn->remote_port = PORT_TELNET;
conn->curl_do = Curl_telnet;
conn->curl_done = Curl_telnet_done;
}
else if (strequal(conn->protostr, "DICT")) {
conn->protocol |= PROT_DICT;
- conn->port = (data->use_port && allow_port)?data->use_port:PORT_DICT;
+ conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_DICT;
conn->remote_port = PORT_DICT;
conn->curl_do = Curl_dict;
conn->curl_done = NULL; /* no DICT-specific done */
}
else if (strequal(conn->protostr, "LDAP")) {
conn->protocol |= PROT_LDAP;
- conn->port = (data->use_port && allow_port)?data->use_port:PORT_LDAP;
+ conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_LDAP;
conn->remote_port = PORT_LDAP;
conn->curl_do = Curl_ldap;
conn->curl_done = NULL; /* no LDAP-specific done */
/*************************************************************
* .netrc scanning coming up
*************************************************************/
- if(data->bits.use_netrc) {
- if(Curl_parsenetrc(conn->hostname, data->user, data->passwd)) {
+ if(data->set.use_netrc) {
+ if(Curl_parsenetrc(conn->hostname,
+ data->state.user,
+ data->state.passwd)) {
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
conn->hostname);
}
/* weather we failed or not, we don't know which fields that were filled
in anyway */
- if(!data->user[0])
- strcpy(data->user, CURL_DEFAULT_USER);
- if(!data->passwd[0])
- strcpy(data->passwd, CURL_DEFAULT_PASSWORD);
+ if(!data->state.user[0])
+ strcpy(data->state.user, CURL_DEFAULT_USER);
+ if(!data->state.passwd[0])
+ strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
}
else if(!(conn->bits.user_passwd) &&
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
if((ptr=strchr(conn->name, '@'))) {
/* there's a user+password given here, to the left of the @ */
- data->user[0] =0;
- data->passwd[0]=0;
+ data->state.user[0] =0;
+ data->state.passwd[0]=0;
if(*conn->name != ':') {
/* the name is given, get user+password */
sscanf(conn->name, "%127[^:@]:%127[^@]",
- data->user, data->passwd);
+ data->state.user, data->state.passwd);
}
else
/* no name given, get the password only */
- sscanf(conn->name+1, "%127[^@]", data->passwd);
+ sscanf(conn->name+1, "%127[^@]", data->state.passwd);
- if(data->user[0]) {
- char *newname=curl_unescape(data->user, 0);
- if(strlen(newname) < sizeof(data->user)) {
- strcpy(data->user, newname);
+ if(data->state.user[0]) {
+ char *newname=curl_unescape(data->state.user, 0);
+ if(strlen(newname) < sizeof(data->state.user)) {
+ strcpy(data->state.user, newname);
}
/* if the new name is longer than accepted, then just use
the unconverted name, it'll be wrong but what the heck */
}
/* check for password, if no ask for one */
- if( !data->passwd[0] ) {
- if(!data->fpasswd ||
- data->fpasswd(data->passwd_client,
- "password:",data->passwd,sizeof(data->passwd)))
+ if( !data->state.passwd[0] ) {
+ if(!data->set.fpasswd ||
+ data->set.fpasswd(data->set.passwd_client,
+ "password:", data->state.passwd,
+ sizeof(data->state.passwd)))
return CURLE_BAD_PASSWORD_ENTERED;
}
else {
/* we have a password found in the URL, decode it! */
- char *newpasswd=curl_unescape(data->passwd, 0);
- if(strlen(newpasswd) < sizeof(data->passwd)) {
- strcpy(data->passwd, newpasswd);
+ char *newpasswd=curl_unescape(data->state.passwd, 0);
+ if(strlen(newpasswd) < sizeof(data->state.passwd)) {
+ strcpy(data->state.passwd, newpasswd);
}
free(newpasswd);
}
conn->bits.user_passwd=TRUE; /* enable user+password */
}
else {
- strcpy(data->user, CURL_DEFAULT_USER);
- strcpy(data->passwd, CURL_DEFAULT_PASSWORD);
+ strcpy(data->state.user, CURL_DEFAULT_USER);
+ strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
}
}
conn->remote_port = atoi(tmp);
}
- if(data->bits.httpproxy) {
+ if(data->change.proxy) {
/* If this is supposed to use a proxy, we need to figure out the proxy
host name name, so that we can re-use an existing connection
that may exist registered to the same proxy host. */
/* We need to make a duplicate of the proxy so that we can modify the
string safely. */
- char *proxydup=strdup(data->proxy);
+ char *proxydup=strdup(data->change.proxy);
/* We use 'proxyptr' to point to the proxy name from now on... */
char *proxyptr=proxydup;
/* now set the local port number */
conn->port = atoi(prox_portno);
}
- else if(data->proxyport) {
+ else if(data->set.proxyport) {
/* None given in the proxy string, then get the default one if it is
given */
- conn->port = data->proxyport;
+ conn->port = data->set.proxyport;
}
/* now, clone the cleaned proxy host name */
/* reuse_fresh is set TRUE if we are told to use a fresh connection
by force */
- if(!data->bits.reuse_fresh &&
+ if(!data->set.reuse_fresh &&
ConnectionExists(data, conn, &conn_temp)) {
/*
* We already have a connection for this, we got the former connection
* If we're doing a resumed transfer, we need to setup our stuff
* properly.
*/
- conn->resume_from = data->set_resume_from;
+ conn->resume_from = data->set.set_resume_from;
if (conn->resume_from) {
snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from);
if (conn->bits.rangestringalloc == TRUE)
conn->bits.use_range = TRUE; /* enable range download */
conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
}
- else if (data->set_range) {
+ else if (data->set.set_range) {
/* There is a range, but is not a resume, useful for random ftp access */
- conn->range = strdup(data->set_range);
+ conn->range = strdup(data->set.set_range);
conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
conn->bits.use_range = TRUE; /* enable range download */
}
/*************************************************************
* Resolve the name of the server or proxy
*************************************************************/
- if(!data->bits.httpproxy) {
+ if(!data->change.proxy) {
/* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */
conn->port = conn->remote_port; /* it is the same port */
*************************************************************/
if(conn->bits.proxy_user_passwd) {
char *authorization;
- snprintf(data->buffer, BUFSIZE, "%s:%s",
- data->proxyuser, data->proxypasswd);
- if(Curl_base64_encode(data->buffer, strlen(data->buffer),
+ snprintf(data->state.buffer, BUFSIZE, "%s:%s",
+ data->state.proxyuser, data->state.proxypasswd);
+ if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
&authorization) >= 0) {
if(conn->allocptr.proxyuserpwd)
free(conn->allocptr.proxyuserpwd);
* Send user-agent to HTTP proxies even if the target protocol
* isn't HTTP.
*************************************************************/
- if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
- if(data->useragent) {
+ if((conn->protocol&PROT_HTTP) || data->change.proxy) {
+ if(data->set.useragent) {
if(conn->allocptr.uagent)
free(conn->allocptr.uagent);
conn->allocptr.uagent =
- aprintf("User-Agent: %s\015\012", data->useragent);
+ aprintf("User-Agent: %s\015\012", data->set.useragent);
}
}
* characters (you get mangled text files, and corrupted binary files when
* you download to stdout and redirect it to a file). */
- if ((data->out)->_handle == NULL) {
+ if ((data->set.out)->_handle == NULL) {
_fsetmode(stdout, "b");
}
#endif
return CURLE_OK;
}
-CURLcode Curl_connect(struct UrlData *data,
+CURLcode Curl_connect(struct SessionHandle *data,
struct connectdata **in_connect,
bool allow_port)
{
CURLcode Curl_done(struct connectdata *conn)
{
- struct UrlData *data=conn->data;
+ struct SessionHandle *data=conn->data;
CURLcode result;
/* cleanups done even if the connection is re-used */
Curl_pgrsDone(conn); /* done with the operation */
- /* if data->bits.reuse_forbid is TRUE, it means the libcurl client has
+ /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
forced us to close this no matter what we think.
if conn->bits.close is TRUE, it means that the connection should be
closed in spite of all our efforts to be nice, due to protocol
restrictions in our or the server's end */
- if(data->bits.reuse_forbid ||
+ if(data->set.reuse_forbid ||
((CURLE_OK == result) && conn->bits.close))
result = Curl_disconnect(conn); /* close the connection */
else
* Prototypes for library-wide functions provided by url.c
*/
-CURLcode Curl_open(struct UrlData **curl);
-CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...);
-CURLcode Curl_close(struct UrlData *data); /* the opposite of curl_open() */
-CURLcode Curl_connect(struct UrlData *,
+CURLcode Curl_open(struct SessionHandle **curl);
+CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
+CURLcode Curl_close(struct SessionHandle *data); /* the opposite of curl_open() */
+CURLcode Curl_connect(struct SessionHandle *,
struct connectdata **,
bool allow_port);
CURLcode Curl_do(struct connectdata *);
bool close; /* if set, we close the connection after this request */
bool reuse; /* if set, this is a re-used connection */
bool chunk; /* if set, this is a chunked transfer-encoding */
- bool httpproxy; /* if set, this transfer is done through a http proxy */
- bool user_passwd; /* do we use user+password for this connection? */
+ bool httpproxy; /* if set, this transfer is done through a http proxy */
+ bool user_passwd; /* do we use user+password for this connection? */
bool proxy_user_passwd; /* user+password for the proxy? */
bool use_range;
*/
struct connectdata {
/**** Fields set when inited and not modified again */
- struct UrlData *data; /* link to the root CURL struct */
+ struct SessionHandle *data; /* link to the root CURL struct */
int connectindex; /* what index in the connects index this particular
struct has */
void *generic;
} proto;
+};
+/*
+ * Struct to keep statistical and informational data.
+ */
+struct PureInfo {
+ int httpcode;
+ int httpversion;
+ time_t filetime; /* If requested, this is might get set. It may be 0 if
+ the time was unretrievable */
+ long header_size; /* size of read header(s) in bytes */
+ long request_size; /* the amount of bytes sent in the request(s) */
};
+
struct Progress {
long lastshow; /* time() of the last displayed progress meter or NULL to
force redraw at next call */
double dlspeed;
double ulspeed;
- struct timeval start;
- struct timeval t_startsingle;
- /* various data stored for possible later report */
double t_nslookup;
double t_connect;
double t_pretransfer;
- int httpcode;
- int httpversion;
- time_t filetime; /* If requested, this is might get set. It may be 0 if
- the time was unretrievable */
+ struct timeval start;
+ struct timeval t_startsingle;
#define CURR_TIME 5
double speeder[ CURR_TIME ];
HTTPREQ_LAST /* last in list */
} Curl_HttpReq;
-/* This struct is for boolean settings that define how to behave during
- this session. */
-struct Configbits {
- bool get_filetime;
- bool tunnel_thru_httpproxy;
- bool ftp_append;
- bool ftp_ascii;
- bool ftp_list_only;
- bool ftp_use_port;
- bool hide_progress;
- bool http_fail_on_error;
- bool http_follow_location;
- bool http_include_header;
- bool http_set_referer;
- bool http_auto_referer; /* set "correct" referer when following location: */
- bool httpproxy;
- bool no_body;
- bool set_port;
- bool set_range;
- bool upload;
- bool use_netrc;
- bool verbose;
+/*
+ * Values that are generated, temporary or calculated internally for a
+ * "session handle" must be defined within the 'struct urlstate'. This struct
+ * will be used within the SessionHandle struct. When the 'SessionHandle'
+ * struct is cloned, this data MUST NOT be copied.
+ *
+ * Remember that any "state" information goes globally for the curl handle.
+ * Session-data MUST be put in the connectdata struct and here. */
+#define MAX_CURL_USER_LENGTH 256
+#define MAX_CURL_PASSWORD_LENGTH 256
+
+struct UrlState {
+ /* buffers to store authentication data in, as parsed from input options */
+ char user[MAX_CURL_USER_LENGTH];
+ char passwd[MAX_CURL_PASSWORD_LENGTH];
+ char proxyuser[MAX_CURL_USER_LENGTH];
+ char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
+
+ 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 */
+
+ char *headerbuff; /* allocated buffer to store headers in */
+ int headersize; /* size of the allocation */
+
+ char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */
+
+ double current_speed; /* the ProgressShow() funcion sets this */
+
bool this_is_a_follow; /* this is a followed Location: request */
- bool krb4; /* kerberos4 connection requested */
- bool proxystringalloc; /* the http proxy string is malloc()'ed */
- bool urlstringalloc; /* the URL string is malloc()'ed */
- bool reuse_forbid; /* if this is forbidden to be reused, close
- after use */
- bool reuse_fresh; /* do not re-use an existing connection for this
- transfer */
- bool expect100header; /* TRUE if we added Expect: 100-continue to the
- HTTP header */
+
+ char *auth_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
+ strdup() data.
+ */
};
+
/*
- * As of April 11, 2000 we're now trying to split up the urldata struct in
- * three different parts:
- *
- * (Global)
- * 1 - No matter how many hosts and requests that are being performed, this
- * goes for all of them.
- *
- * (Session)
- * 2 - Host and protocol-specific. No matter if we do several transfers to and
- * from this host, these variables stay the same.
- *
- * (Request)
- * 3 - Request-specific. Variables that are of interest for this particular
- * transfer being made right now. THIS IS WRONG STRUCT FOR THOSE.
- *
- * In Febrary 2001, this is being done stricter. The 'connectdata' struct
- * MUST have all the connection oriented stuff as we may now have several
- * simultaneous connections and connection structs in memory.
- *
- * From now on, the 'UrlData' must only contain data that is set once to go
+ * This 'DynamicStatic' struct defines dynamic states that actually change
+ * values in the 'UserDefined' area, which MUST be taken into consideration
+ * if the UserDefined struct is cloned or similar. You can probably just
+ * copy these, but each one indicate a special action on other data.
+ */
+
+struct DynamicStatic {
+ char *url; /* work URL, copied from UserDefined */
+ bool url_alloc; /* URL string is malloc()'ed */
+ char *proxy; /* work proxy, copied from UserDefined */
+ bool proxy_alloc; /* http proxy string is malloc()'ed */
+ char *referer; /* referer string */
+ bool referer_alloc; /* referer sting is malloc()ed */
+};
+
+/*
+ * This 'UserDefined' struct must only contain data that is set once to go
* for many (perhaps) independent connections. Values that are generated or
- * calculated internally MUST NOT be a part of this struct.
+ * calculated internally for the "session handle" MUST be defined within the
+ * 'struct urlstate' instead. The only exceptions MUST note the changes in
+ * the 'DynamicStatic' struct.
*/
-struct UrlData {
- /*************** Global - specific items ************/
+struct UserDefined {
FILE *err; /* the stderr writes goes here */
char *errorbuffer; /* store failure messages in here */
-
- /*************** Session - specific items ************/
- char *proxy; /* if proxy, set it here */
char *proxyuserpwd; /* Proxy <user:password>, if used */
long proxyport; /* If non-zero, use this port number by default. If the
proxy string features a ":[port]" that one will override
- this. */
-
-
- long header_size; /* size of read header(s) in bytes */
- long request_size; /* the amount of bytes sent in the request(s) */
-
+ this. */
void *out; /* the fetched file goes here */
void *in; /* the uploaded file is read from here */
void *writeheader; /* write the header to this is non-NULL */
-
- char *url; /* what to get */
- char *freethis; /* if non-NULL, an allocated string for the URL */
- long use_port; /* which port to use (when not using default) */
- struct Configbits bits; /* new-style (v7) flag data */
- struct ssl_config_data ssl; /* this is for ssl-stuff */
-
- char *userpwd; /* <user:password>, if used */
- char *set_range; /* range, if used. See README for detailed specification on
- this syntax. */
-
- /* stuff related to HTTP */
-
- long followlocation;
- long maxredirs; /* maximum no. of http(s) redirects to follow */
- char *referer;
+ char *set_url; /* what original URL to work on */
+ char *set_proxy; /* proxy to use */
+ long use_port; /* which port to use (when not using default) */
+ char *userpwd; /* <user:password>, if used */
+ char *set_range; /* range, if used. See README for detailed specification
+ on this syntax. */
+ long followlocation; /* as in HTTP Location: */
+ long maxredirs; /* maximum no. of http(s) redirects to follow */
+ char *set_referer; /* custom string */
bool free_referer; /* set TRUE if 'referer' points to a string we
allocated */
char *useragent; /* User-Agent string */
- char *postfields; /* if POST, set the fields' values here */
+ char *postfields; /* if POST, set the fields' values here */
size_t postfieldsize; /* if POST, this might have a size to use instead of
strlen(), and then the data *may* be binary (contain
zero bytes) */
-
- /* stuff related to FTP */
- char *ftpport; /* port to send with the PORT command */
-
- /* general things */
- char *device; /* Interface to use */
-
- /* function that stores the output:*/
- curl_write_callback fwrite;
-
- /* optional function that stores the header output:*/
- curl_write_callback fwrite_header;
-
- /* function that reads the input:*/
- curl_read_callback fread;
-
- /* function that wants progress information */
- curl_progress_callback fprogress;
+ char *ftpport; /* port to send with the FTP PORT command */
+ char *device; /* network interface to use */
+ curl_write_callback fwrite; /* function that stores the output */
+ curl_write_callback fwrite_header; /* function that stores headers */
+ curl_read_callback fread; /* function that reads the input */
+ curl_progress_callback fprogress; /* function for progress information */
void *progress_client; /* pointer to pass to the progress callback */
-
- /* function to call instead of the internal for password */
- curl_passwd_callback fpasswd;
- void *passwd_client; /* pointer to pass to the passwd callback */
-
- long timeout; /* in seconds, 0 means no timeout */
- long connecttimeout; /* in seconds, 0 means no timeout */
- long infilesize; /* size of file to upload, -1 means unknown */
-
- char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */
-
- double current_speed; /* the ProgressShow() funcion sets this */
-
+ curl_passwd_callback fpasswd; /* call for password */
+ void *passwd_client; /* pass to the passwd callback */
+ long timeout; /* in seconds, 0 means no timeout */
+ long connecttimeout; /* in seconds, 0 means no timeout */
+ long infilesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */
-
- int set_resume_from; /* continue [ftp] transfer from here */
-
- char *cookie; /* HTTP cookie string to send */
-
+ int set_resume_from; /* continue [ftp] transfer from here */
+ char *cookie; /* HTTP cookie string to send */
struct curl_slist *headers; /* linked list of extra headers */
struct HttpPost *httppost; /* linked list of POST data */
-
- char *cert; /* PEM-formatted certificate */
- char *cert_passwd; /* plain text certificate password */
-
- struct CookieInfo *cookies;
- char *cookiejar; /* dump all cookies to this file */
-
- long crlf;
+ char *cert; /* PEM-formatted certificate */
+ char *cert_passwd; /* plain text certificate password */
+ char *cookiejar; /* dump all cookies to this file */
+ bool crlf; /* convert crlf on ftp upload(?) */
struct curl_slist *quote; /* before the transfer */
struct curl_slist *postquote; /* after the transfer */
-
- /* Telnet negotiation options */
struct curl_slist *telnet_options; /* linked list of telnet options */
-
- TimeCond timecondition; /* kind of comparison */
+ TimeCond timecondition; /* kind of time/date comparison */
time_t timevalue; /* what time to compare with */
-
- Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
-
- char *customrequest; /* http/ftp request to use */
-
- char *headerbuff; /* allocated buffer to store headers in */
- int headersize; /* size of the allocation */
-
- struct Progress progress; /* for all the progress meter data */
-
-#define MAX_CURL_USER_LENGTH 128
-#define MAX_CURL_PASSWORD_LENGTH 128
-
+ curl_closepolicy closepolicy; /* connection cache close concept */
+ Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
+ char *customrequest; /* HTTP/FTP request to use */
char *auth_host; /* if set, this is the allocated string to the host name
* to which to send the authorization data to, and no other
* host (which location-following otherwise could lead to)
*/
-
- /* buffers to store authentication data in */
- char user[MAX_CURL_USER_LENGTH];
- char passwd[MAX_CURL_PASSWORD_LENGTH];
- char proxyuser[MAX_CURL_USER_LENGTH];
- char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
-
char *krb4_level; /* what security level */
- struct timeval keeps_speed; /* this should be request-specific */
+ struct ssl_config_data ssl; /* user defined SSL stuff */
- /* '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 */
- curl_closepolicy closepolicy;
+/* 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;
+ bool tunnel_thru_httpproxy;
+ bool ftp_append;
+ bool ftp_ascii;
+ bool ftp_list_only;
+ bool ftp_use_port;
+ bool hide_progress;
+ bool http_fail_on_error;
+ bool http_follow_location;
+ bool http_include_header;
+ bool http_set_referer;
+ bool http_auto_referer; /* set "correct" referer when following location: */
+ bool no_body;
+ bool set_port;
+ bool upload;
+ bool use_netrc;
+ bool verbose;
+ bool krb4; /* kerberos4 connection requested */
+ bool reuse_forbid; /* forbidden to be reused, close after use */
+ bool reuse_fresh; /* do not re-use an existing connection */
+ bool expect100header; /* TRUE if we added Expect: 100-continue */
+};
+/*
+ * In August 2001, this struct was redesigned and is since stricter than
+ * before. The 'connectdata' struct MUST have all the connection oriented
+ * stuff as we may now have several simultaneous connections and connection
+ * structs in memory.
+ *
+ * From now on, the 'SessionHandle' must only contain data that is set once to
+ * go for many (perhaps) independent connections. Values that are generated or
+ * calculated internally for the "session handle" must be defined within the
+ * 'struct urlstate' instead. */
+
+struct SessionHandle {
+ struct UserDefined set; /* values set by the libcurl user */
+ struct DynamicStatic change; /* possibly modified userdefined data */
+
+ struct CookieInfo *cookies; /* the cookies, read from files and servers */
+ struct Progress progress; /* for all the progress meter data */
+ struct UrlState state; /* struct for fields used for state info and
+ other dynamic purposes */
+ struct PureInfo info; /* stats, reports and info data */
};
#define LIBCURL_NAME "libcurl"