diff --git a/lib/ftp.c b/lib/ftp.c index 6fd9fd3ac..bd6826e0c 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -493,7 +493,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn) } else { if((-1 != conn->size) && (conn->size != *ftp->bytecountp) && - (data->maxdownload != *ftp->bytecountp)) { + (conn->maxdownload != *ftp->bytecountp)) { failf(data, "Received only partial file"); return CURLE_PARTIAL_FILE; } @@ -1393,16 +1393,16 @@ again:; else if(from < 0) { /* -Y */ totalsize = -from; - data->maxdownload = -from; + conn->maxdownload = -from; data->resume_from = from; infof(data, "FTP RANGE the last %d bytes\n", totalsize); } else { /* X-Y */ totalsize = to-from; - data->maxdownload = totalsize+1; /* include the last mentioned byte */ + conn->maxdownload = totalsize+1; /* include the last mentioned byte */ data->resume_from = from; - infof(data, "FTP RANGE from %d getting %d bytes\n", from, data->maxdownload); + infof(data, "FTP RANGE from %d getting %d bytes\n", from, conn->maxdownload); } infof(data, "range-download from %d to %d, totally %d bytes\n", from, to, totalsize); diff --git a/lib/http.c b/lib/http.c index 897e0a1fb..3184c7f5f 100644 --- a/lib/http.c +++ b/lib/http.c @@ -282,8 +282,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, "%s" "\r\n", hostname, remote_port, - (data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"", - (data->useragent?data->ptr_uagent:"") + (data->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"", + (data->useragent?conn->allocptr.uagent:"") ); /* wait for the proxy to send us a HTTP/1.0 200 OK header */ @@ -405,9 +405,9 @@ CURLcode Curl_http(struct connectdata *conn) have been used in the proxy connect, but if we have got a header with the user-agent string specified, we erase the previously made string here. */ - if(checkheaders(data, "User-Agent:") && data->ptr_uagent) { - free(data->ptr_uagent); - data->ptr_uagent=NULL; + if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) { + free(conn->allocptr.uagent); + conn->allocptr.uagent=NULL; } if((data->bits.user_passwd) && !checkheaders(data, "Authorization:")) { @@ -421,23 +421,23 @@ CURLcode Curl_http(struct connectdata *conn) sprintf(data->buffer, "%s:%s", data->user, data->passwd); if(Curl_base64_encode(data->buffer, strlen(data->buffer), &authorization) >= 0) { - if(data->ptr_userpwd) - free(data->ptr_userpwd); - data->ptr_userpwd = aprintf( "Authorization: Basic %s\015\012", + if(conn->allocptr.userpwd) + free(conn->allocptr.userpwd); + conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012", authorization); free(authorization); } } } if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) { - if(data->ptr_ref) - free(data->ptr_ref); - data->ptr_ref = aprintf("Referer: %s\015\012", data->referer); + if(conn->allocptr.ref) + free(conn->allocptr.ref); + conn->allocptr.ref = aprintf("Referer: %s\015\012", data->referer); } if(data->cookie && !checkheaders(data, "Cookie:")) { - if(data->ptr_cookie) - free(data->ptr_cookie); - data->ptr_cookie = aprintf("Cookie: %s\015\012", data->cookie); + if(conn->allocptr.cookie) + free(conn->allocptr.cookie); + conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->cookie); } if(data->cookies) { @@ -457,7 +457,7 @@ CURLcode Curl_http(struct connectdata *conn) } if(!checkheaders(data, "Host:") && - !data->ptr_host) { + !conn->allocptr.host) { /* if ptr_host is already set, it is OK since we only re-use connections to the very same host and port */ @@ -465,9 +465,10 @@ CURLcode Curl_http(struct connectdata *conn) (!(conn->protocol&PROT_HTTPS) && (data->remote_port == PORT_HTTP)) ) /* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include the port number in the host string */ - data->ptr_host = aprintf("Host: %s\r\n", host); + conn->allocptr.host = aprintf("Host: %s\r\n", host); else - data->ptr_host = aprintf("Host: %s:%d\r\n", host, data->remote_port); + conn->allocptr.host = aprintf("Host: %s:%d\r\n", host, + data->remote_port); } if(!checkheaders(data, "Pragma:")) @@ -541,7 +542,7 @@ CURLcode Curl_http(struct connectdata *conn) */ if((data->httpreq == HTTPREQ_GET) && !checkheaders(data, "Range:")) { - data->ptr_rangeline = aprintf("Range: bytes=%s\r\n", data->range); + conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->range); } else if((data->httpreq != HTTPREQ_GET) && !checkheaders(data, "Content-Range:")) { @@ -549,14 +550,14 @@ CURLcode Curl_http(struct connectdata *conn) if(data->resume_from) { /* This is because "resume" was selected */ long total_expected_size= data->resume_from + data->infilesize; - data->ptr_rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n", + conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n", data->range, total_expected_size-1, total_expected_size); } else { /* Range was selected and then we just pass the incoming range and append total size */ - data->ptr_rangeline = aprintf("Content-Range: bytes %s/%d\r\n", + conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n", data->range, data->infilesize); } } @@ -572,7 +573,7 @@ CURLcode Curl_http(struct connectdata *conn) /* add the main request stuff */ add_bufferf(req_buffer, "%s " /* GET/HEAD/POST/PUT */ - "%s HTTP/1.0\r\n" /* path */ + "%s HTTP/1.1\r\n" /* path */ "%s" /* proxyuserpwd */ "%s" /* userpwd */ "%s" /* range */ @@ -588,15 +589,15 @@ CURLcode Curl_http(struct connectdata *conn) (data->bits.http_post || data->bits.http_formpost)?"POST": (data->bits.http_put)?"PUT":"GET"), ppath, - (data->bits.proxy_user_passwd && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"", - (data->bits.user_passwd && data->ptr_userpwd)?data->ptr_userpwd:"", - (data->bits.set_range && data->ptr_rangeline)?data->ptr_rangeline:"", - (data->useragent && *data->useragent && data->ptr_uagent)?data->ptr_uagent:"", - (data->ptr_cookie?data->ptr_cookie:""), /* Cookie: */ - (data->ptr_host?data->ptr_host:""), /* Host: host */ + (data->bits.proxy_user_passwd && conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"", + (data->bits.user_passwd && conn->allocptr.userpwd)?conn->allocptr.userpwd:"", + (data->bits.set_range && conn->allocptr.rangeline)?conn->allocptr.rangeline:"", + (data->useragent && *data->useragent && conn->allocptr.uagent)?conn->allocptr.uagent:"", + (conn->allocptr.cookie?conn->allocptr.cookie:""), /* Cookie: */ + (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 && data->ptr_ref)?data->ptr_ref:"" /* Referer: */ + (data->bits.http_set_referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: */ ); if(co) { diff --git a/lib/url.c b/lib/url.c index 71824ad4f..2092b213b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -158,35 +158,6 @@ CURLcode curl_close(CURL *curl) data->bits.rangestringalloc=0; /* free now */ } - if(data->ptr_proxyuserpwd) { - free(data->ptr_proxyuserpwd); - data->ptr_proxyuserpwd=NULL; - } - if(data->ptr_uagent) { - free(data->ptr_uagent); - data->ptr_uagent=NULL; - } - if(data->ptr_userpwd) { - free(data->ptr_userpwd); - data->ptr_userpwd=NULL; - } - if(data->ptr_rangeline) { - free(data->ptr_rangeline); - data->ptr_rangeline=NULL; - } - if(data->ptr_ref) { - free(data->ptr_ref); - data->ptr_ref=NULL; - } - if(data->ptr_cookie) { - free(data->ptr_cookie); - data->ptr_cookie=NULL; - } - if(data->ptr_host) { - free(data->ptr_host); - data->ptr_host=NULL; - } - /* check for allocated [URL] memory to free: */ if(data->freethis) free(data->freethis); @@ -577,13 +548,26 @@ CURLcode curl_disconnect(CURLconnect *c_connect) /* close possibly still open sockets */ if(-1 != conn->secondarysocket) { sclose(conn->secondarysocket); - conn->secondarysocket = -1; } if(-1 != conn->firstsocket) { sclose(conn->firstsocket); - conn->firstsocket=-1; } + if(conn->allocptr.proxyuserpwd) + free(conn->allocptr.proxyuserpwd); + if(conn->allocptr.uagent) + free(conn->allocptr.uagent); + if(conn->allocptr.userpwd) + free(conn->allocptr.userpwd); + if(conn->allocptr.rangeline) + free(conn->allocptr.rangeline); + if(conn->allocptr.ref) + free(conn->allocptr.ref); + if(conn->allocptr.cookie) + free(conn->allocptr.cookie); + if(conn->allocptr.host) + free(conn->allocptr.host); + free(conn); /* free all the connection oriented data */ return CURLE_OK; @@ -1544,6 +1528,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) free(conn->path); /* free the previous path pointer */ conn->path = path; /* use this one */ conn->ppath = path; /* set this too */ + + /* re-use init */ + conn->maxdownload = 0; /* might have been used previously! */ + + infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex); } else { /* @@ -1653,9 +1642,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->proxyuser, data->proxypasswd); if(Curl_base64_encode(data->buffer, strlen(data->buffer), &authorization) >= 0) { - if(data->ptr_proxyuserpwd) - free(data->ptr_proxyuserpwd); - data->ptr_proxyuserpwd = + if(conn->allocptr.proxyuserpwd) + free(conn->allocptr.proxyuserpwd); + conn->allocptr.proxyuserpwd = aprintf("Proxy-authorization: Basic %s\015\012", authorization); free(authorization); } @@ -1667,9 +1656,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) *************************************************************/ if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) { if(data->useragent) { - if(data->ptr_uagent) - free(data->ptr_uagent); - data->ptr_uagent = + if(conn->allocptr.uagent) + free(conn->allocptr.uagent); + conn->allocptr.uagent = aprintf("User-Agent: %s\015\012", data->useragent); } } diff --git a/lib/urldata.h b/lib/urldata.h index d1c770a11..ea25345f6 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -242,6 +242,9 @@ struct connectdata { long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE never smaller than UPLOAD_BUFSIZE */ + long maxdownload; /* in bytes, the maximum amount of data to fetch, 0 + means unlimited */ + struct ssl_connect_data ssl; /* this is for ssl-stuff */ struct ConnectBits bits; /* various state-flags for this connection */ @@ -274,6 +277,17 @@ struct connectdata { the same we read from. -1 disables */ long *writebytecountp; /* return number of bytes written or NULL */ + /** Dynamicly allocated strings, may need to be freed before this **/ + /** struct is killed. **/ + struct dynamically_allocated_data { + char *proxyuserpwd; /* free later if not NULL! */ + char *uagent; /* free later if not NULL! */ + char *userpwd; /* free later if not NULL! */ + char *rangeline; /* free later if not NULL! */ + char *ref; /* free later if not NULL! */ + char *cookie; /* free later if not NULL! */ + char *host; /* free later if not NULL */ + } allocptr; #ifdef KRB4 @@ -411,11 +425,15 @@ typedef enum { * * (Request) * 3 - Request-specific. Variables that are of interest for this particular - * transfer being made right now. + * 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 + * for many (perhaps) independent connections. Values that are generated or + * calculated internally MUST NOT be a part of this struct. */ struct UrlData { @@ -488,9 +506,6 @@ struct UrlData { long timeout; /* in seconds, 0 means no timeout */ long infilesize; /* size of file to upload, -1 means unknown */ - long maxdownload; /* in bytes, the maximum amount of data to fetch, 0 - means unlimited */ - char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */ double current_speed; /* the ProgressShow() funcion sets this */ @@ -546,15 +561,6 @@ struct UrlData { char proxyuser[MAX_CURL_USER_LENGTH]; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; - /**** Dynamicly allocated strings, may need to be freed on return ****/ - char *ptr_proxyuserpwd; /* free later if not NULL! */ - char *ptr_uagent; /* free later if not NULL! */ - char *ptr_userpwd; /* free later if not NULL! */ - char *ptr_rangeline; /* free later if not NULL! */ - char *ptr_ref; /* free later if not NULL! */ - char *ptr_cookie; /* free later if not NULL! */ - char *ptr_host; /* free later if not NULL */ - char *krb4_level; /* what security level */ #ifdef KRB4 FILE *cmdchannel;