From b7a760046545fa9afc3feca68d12dc087fbe625c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Apr 2004 07:53:24 +0000 Subject: [PATCH] Cleaned up hostname/name/gname and path/ppath confusion. Removed the fixed- length limit of the hostname part of the URL. --- CHANGES | 13 +++++- RELEASE-NOTES | 4 +- lib/ftp.c | 8 ++-- lib/http.c | 4 +- lib/ssluse.c | 4 +- lib/transfer.c | 4 +- lib/url.c | 116 +++++++++++++++++++++++-------------------------- lib/urldata.h | 11 ++--- 8 files changed, 85 insertions(+), 79 deletions(-) diff --git a/CHANGES b/CHANGES index aba9ddfd7..c97faea69 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,16 @@ Changelog +Daniel (19 April 2004) +- No more 512 byte limit for host name (inclusing name + password) in libcurl. + An added bonus is that we use less memory for the typical (shorter URL) + case. + +- Cleaned up the sources to better use the terms 'hostname' and 'path' + internally when referring to that data. The buffers used for keep that info + is called 'namebuffer' and 'pathbuffer'. Much easier to read and understand + than the previous mess. + Daniel (15 April 2004) - Modified runtests.pl again to remove all log files in the log/ dir between each test, and then made -p display all non-zero byte files in the log dir. @@ -19,7 +29,8 @@ Daniel (15 April 2004) Previously we had a fixed array for 100 levels, now we save space in each handle by allocating only for a few level by default and then enlarging that in case of need (with no maximum depth). Adjusted test case 142 to verify - that 150 dir levels work fine. + that 150 dir levels work fine. An added bonus is that we use less memory + for the typical (not very deep) case. Daniel (14 April 2004) - Asking for CURL_IPRESOLVE_V6 when ipv6 addresses can't be resolved will diff --git a/RELEASE-NOTES b/RELEASE-NOTES index e8914b2f7..5640135ff 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -7,7 +7,8 @@ Curl and libcurl 7.11.2. A bugfix release. This release includes the following changes: - o removed maximum dir depth limit in the FTP code + o removed maximum user+password+hostname size limit + o removed maximum dir depth limit for FTP o the ares build now requires c-ares 1.2.0 or later o --tcp-nodelay and CURLOPT_TCP_NODELAY were added o curl/curlver.h contains the libcurl version info now @@ -53,6 +54,7 @@ Other curl-related news since the previous public release: http://q-lang.sourceforge.net/ o New German web mirror: http://curl.netmirror.org/ o c-ares 1.2.0 was released: http://daniel.haxx.se/projects/c-ares/ + o New US web mirror: http://curl.signal42.com/ This release would not have looked like this without help, code, reports and advice from friends like these: diff --git a/lib/ftp.c b/lib/ftp.c index cce1d9e9e..088cfaa5e 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -1611,7 +1611,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn, newport = num; /* we should use the same host we already are connected to */ - newhostp = conn->name; + newhostp = conn->hostname; } } else @@ -2320,8 +2320,8 @@ CURLcode Curl_ftp(struct connectdata *conn) struct FTP *ftp; char *slash_pos; /* position of the first '/' char in curpos */ - char *cur_pos=conn->ppath; /* current position in ppath. point at the begin - of next path component */ + char *cur_pos=conn->path; /* current position in ppath. point at the begin + of next path component */ /* the ftp struct is already inited in ftp_connect() */ ftp = conn->proto.ftp; @@ -2343,7 +2343,7 @@ CURLcode Curl_ftp(struct connectdata *conn) /* parse the URL path into separate path components */ while((slash_pos=strchr(cur_pos, '/'))) { /* 1 or 0 to indicate absolute directory */ - bool absolute_dir = (cur_pos - conn->ppath > 0) && (ftp->dirdepth == 0); + bool absolute_dir = (cur_pos - conn->path > 0) && (ftp->dirdepth == 0); /* seek out the next path component */ if (slash_pos-cur_pos) { diff --git a/lib/http.c b/lib/http.c index 3a1f89025..66b5ce228 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1150,8 +1150,8 @@ CURLcode Curl_http(struct connectdata *conn) CURLcode result=CURLE_OK; struct HTTP *http; struct Cookie *co=NULL; /* no cookies from start */ - char *ppath = conn->ppath; /* three previous function arguments */ - char *host = conn->name; + char *ppath = conn->path; + char *host = conn->hostname; const char *te = ""; /* tranfer-encoding */ char *ptr; char *request; diff --git a/lib/ssluse.c b/lib/ssluse.c index d78d78f6d..6a81f24f7 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -544,7 +544,7 @@ static int Get_SSL_Session(struct connectdata *conn, if(!check->sessionid) /* not session ID means blank entry */ continue; - if(curl_strequal(conn->name, check->name) && + if(curl_strequal(conn->hostname, check->name) && (conn->remote_port == check->remote_port) && Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) { /* yes, we have a session ID! */ @@ -662,7 +662,7 @@ static int Store_SSL_Session(struct connectdata *conn, /* now init the session struct wisely */ store->sessionid = ssl_sessionid; store->age = data->state.sessionage; /* set current age */ - store->name = strdup(conn->name); /* clone host name */ + store->name = strdup(conn->hostname); /* clone host name */ store->remote_port = conn->remote_port; /* port number */ Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config); diff --git a/lib/transfer.c b/lib/transfer.c index 977cb72d4..cb24dd30f 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -802,8 +802,8 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* If there is a custom-set Host: name, use it here, or else use real peer host name. */ conn->allocptr.cookiehost? - conn->allocptr.cookiehost:conn->name, - conn->ppath); + conn->allocptr.cookiehost:conn->hostname, + conn->path); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } else if(checkprefix("Last-Modified:", k->p) && diff --git a/lib/url.c b/lib/url.c index de31fd107..078b74c47 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1360,7 +1360,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->proto.generic); Curl_safefree(conn->newurl); - Curl_safefree(conn->path); /* the URL path part */ + Curl_safefree(conn->pathbuffer); /* the URL path buffer */ + Curl_safefree(conn->namebuffer); /* the URL host name buffer */ Curl_SSL_Close(conn); /* close possibly still open sockets */ @@ -1460,7 +1461,7 @@ ConnectionExists(struct SessionHandle *data, continue; if(strequal(needle->protostr, check->protostr) && - strequal(needle->name, check->name) && + strequal(needle->hostname, check->hostname) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same @@ -2096,9 +2097,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(urllen < LEAST_PATH_ALLOC) urllen=LEAST_PATH_ALLOC; - conn->path=(char *)malloc(urllen); - if(NULL == conn->path) + conn->pathbuffer=(char *)malloc(urllen); + if(NULL == conn->pathbuffer) return CURLE_OUT_OF_MEMORY; /* really bad error */ + conn->path = conn->pathbuffer; + + conn->namebuffer=(char *)malloc(urllen); + if(NULL == conn->namebuffer) + return CURLE_OUT_OF_MEMORY; + conn->hostname = conn->namebuffer; /************************************************************* * Parse the URL. @@ -2160,7 +2167,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } else { /* Set default host and default path */ - strcpy(conn->gname, "curl.haxx.se"); + strcpy(conn->namebuffer, "curl.haxx.se"); strcpy(conn->path, "/"); /* We need to search for '/' OR '?' - whichever comes first after host * name but before the path. We need to change that to handle things like @@ -2168,15 +2175,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, * that missing slash at the beginning of the path. */ if (2 > sscanf(data->change.url, - "%64[^\n:]://%512[^\n/?]%[^\n]", - conn->protostr, conn->gname, conn->path)) { + "%64[^\n:]://%[^\n/?]%[^\n]", + conn->protostr, + conn->namebuffer, conn->path)) { /* * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ - if((1 > sscanf(data->change.url, "%512[^\n/?]%[^\n]", - conn->gname, conn->path)) ) { + if((1 > sscanf(data->change.url, "%[^\n/?]%[^\n]", + conn->namebuffer, conn->path)) ) { /* * We couldn't even get this format. */ @@ -2192,21 +2200,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Note: if you add a new protocol, please update the list in * lib/version.c too! */ - if(checkprefix("GOPHER", conn->gname)) + if(checkprefix("GOPHER", conn->namebuffer)) strcpy(conn->protostr, "gopher"); #ifdef USE_SSLEAY - else if(checkprefix("HTTPS", conn->gname)) + else if(checkprefix("HTTPS", conn->namebuffer)) strcpy(conn->protostr, "https"); - else if(checkprefix("FTPS", conn->gname)) + else if(checkprefix("FTPS", conn->namebuffer)) strcpy(conn->protostr, "ftps"); #endif /* USE_SSLEAY */ - else if(checkprefix("FTP", conn->gname)) + else if(checkprefix("FTP", conn->namebuffer)) strcpy(conn->protostr, "ftp"); - else if(checkprefix("TELNET", conn->gname)) + else if(checkprefix("TELNET", conn->namebuffer)) strcpy(conn->protostr, "telnet"); - else if (checkprefix("DICT", conn->gname)) + else if (checkprefix("DICT", conn->namebuffer)) strcpy(conn->protostr, "DICT"); - else if (checkprefix("LDAP", conn->gname)) + else if (checkprefix("LDAP", conn->namebuffer)) strcpy(conn->protostr, "LDAP"); else { strcpy(conn->protostr, "http"); @@ -2231,7 +2239,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* * So if the URL was A://B/C, * conn->protostr is A - * conn->gname is B + * conn->namebuffer is B * conn->path is /C */ @@ -2256,13 +2264,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; } - /************************************************************* - * Set a few convenience pointers - *************************************************************/ - conn->name = conn->gname; - conn->ppath = conn->path; - conn->hostname = conn->name; - /************************************************************* * Detect what (if any) proxy to use *************************************************************/ @@ -2301,15 +2302,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; while(nope) { unsigned int namelen; - char *endptr = strchr(conn->name, ':'); + char *endptr = strchr(conn->hostname, ':'); if(endptr) - namelen=endptr-conn->name; + namelen=endptr-conn->hostname; else - namelen=strlen(conn->name); + namelen=strlen(conn->hostname); if(strlen(nope) <= namelen) { char *checkn= - conn->name + namelen - strlen(nope); + conn->hostname + namelen - strlen(nope); if(checkprefix(nope, checkn)) { /* no proxy for this host! */ break; @@ -2501,10 +2502,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_GOPHER; /* Skip // in path if present */ if (isdigit((int)conn->path[1])) { - conn->ppath = strchr(&conn->path[1], '/'); - if (conn->ppath == NULL) - conn->ppath = conn->path; - } + conn->path = strchr(&conn->path[1], '/'); + if (conn->path == NULL) + conn->path = conn->pathbuffer; + } conn->protocol |= PROT_GOPHER; conn->curl_do = Curl_http; conn->curl_do_more = NULL; @@ -2566,13 +2567,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_disconnect = Curl_ftp_disconnect; } - conn->ppath++; /* don't include the initial slash */ + conn->path++; /* don't include the initial slash */ /* FTP URLs support an extension like ";type=" that * we'll try to get now! */ - type=strstr(conn->ppath, ";type="); + type=strstr(conn->path, ";type="); if(!type) { - type=strstr(conn->gname, ";type="); + type=strstr(conn->namebuffer, ";type="); } if(type) { char command; @@ -2681,24 +2682,23 @@ static CURLcode CreateConnection(struct SessionHandle *data, * To be able to detect port number flawlessly, we must not confuse them * IPv6-specified addresses in the [0::1] style. (RFC2732) * - * The conn->name is currently [user:passwd@]host[:port] where host could - * be a hostname, IPv4 address or IPv6 address. + * The conn->hostname is currently [user:passwd@]host[:port] where host + * could be a hostname, IPv4 address or IPv6 address. *************************************************************/ - if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && + if((1 == sscanf(conn->hostname, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && (']' == endbracket)) { /* this is a RFC2732-style specified IP-address */ conn->bits.ipv6_ip = TRUE; - conn->name++; /* pass the starting bracket */ - conn->hostname++; - tmp = strchr(conn->name, ']'); + conn->hostname++; /* pass the starting bracket */ + tmp = strchr(conn->hostname, ']'); *tmp = 0; /* zero terminate */ tmp++; /* pass the ending bracket */ if(':' != *tmp) tmp = NULL; /* no port number available */ } else - tmp = strrchr(conn->name, ':'); + tmp = strrchr(conn->hostname, ':'); if (tmp) { char *rest; @@ -2805,12 +2805,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* This is a FTP or HTTP URL, we will now try to extract the possible * user+password pair in a string like: * ftp://user:password@ftp.my.site:8021/README */ - char *ptr=strchr(conn->name, '@'); - char *userpass = conn->name; + char *ptr=strchr(conn->hostname, '@'); + char *userpass = conn->hostname; if(ptr != NULL) { /* there's a user+password given here, to the left of the @ */ - conn->name = conn->hostname = ++ptr; + conn->hostname = ++ptr; /* So the hostname is sane. Only bother interpreting the * results if we could care. It could still be wasted @@ -2924,8 +2924,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * existing one. */ struct connectdata *old_conn = conn; - char *path = old_conn->path; /* setup the current path pointer properly */ - char *ppath = old_conn->ppath; /* this is the modified path pointer */ + if(old_conn->proxyhost) free(old_conn->proxyhost); @@ -2943,20 +2942,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* get the newly set value, not the old one */ conn->bits.no_body = old_conn->bits.no_body; - /* If we speak over a proxy, we need to copy the host name too, as it - might be another remote host even when re-using a connection */ - strcpy(conn->gname, old_conn->gname); /* safe strcpy() */ + free(conn->namebuffer); /* free the newly allocated name buffer */ + conn->namebuffer = old_conn->namebuffer; /* use the old one */ + conn->hostname = old_conn->hostname; - /* we need these pointers if we speak over a proxy */ - conn->hostname = conn->gname; - conn->name = &conn->gname[old_conn->name - old_conn->gname]; - - free(conn->path); /* free the previously allocated path pointer */ - - /* 'path' points to the allocated data, 'ppath' may have been advanced - to point somewhere within the 'path' area. */ - conn->path = path; - conn->ppath = ppath; + free(conn->pathbuffer); /* free the newly allocated path pointer */ + conn->pathbuffer = old_conn->pathbuffer; /* use the old one */ + conn->path = old_conn->path; /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ @@ -3093,12 +3085,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = conn->remote_port; /* it is the same port */ /* Resolve target host right on */ - rc = Curl_resolv(conn, conn->name, conn->port, &hostaddr); + rc = Curl_resolv(conn, conn->hostname, conn->port, &hostaddr); if(rc == 1) *async = TRUE; else if(!hostaddr) { - failf(data, "Couldn't resolve host '%s'", conn->name); + failf(data, "Couldn't resolve host '%s'", conn->hostname); result = CURLE_COULDNT_RESOLVE_HOST; /* don't return yet, we need to clean up the timeout first */ } diff --git a/lib/urldata.h b/lib/urldata.h index 1da835126..a4040d15e 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -427,14 +427,15 @@ struct connectdata { struct sockaddr_in serv_addr; #endif char protostr[64]; /* store the protocol string in this buffer */ - char gname[513]; /* store the hostname in this buffer */ - char *name; /* host name pointer to fool around with */ - char *path; /* allocated buffer to store the URL's path part in */ - char *hostname; /* hostname to connect, as parsed from url */ + char *namebuffer; /* allocated buffer to store the hostname in */ + char *hostname; /* hostname to use, as parsed from url. points to + somewhere within the namebuffer[] area */ + char *pathbuffer;/* allocated buffer to store the URL's path part in */ + char *path; /* path to use, points to somewhere within the pathbuffer + area */ long port; /* which port to use locally */ unsigned short remote_port; /* what remote port to connect to, not the proxy port! */ - char *ppath; curl_off_t bytecount; long headerbytecount; /* only count received headers */ long deductheadercount; /* this amount of bytes doesn't count when we check