From ae1912cb0d494b48d514d937826c9fe83ec96c4d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Dec 1999 14:20:26 +0000 Subject: Initial revision --- lib/url.c | 1181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1181 insertions(+) create mode 100644 lib/url.c (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c new file mode 100644 index 000000000..b520898dc --- /dev/null +++ b/lib/url.c @@ -0,0 +1,1181 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Curl. + * + * The Initial Developer of the Original Code is Daniel Stenberg. + * + * Portions created by the Initial Developer are Copyright (C) 1998. + * All Rights Reserved. + * + * ------------------------------------------------------------ + * Main author: + * - Daniel Stenberg + * + * http://curl.haxx.nu + * + * $Source$ + * $Revision$ + * $Date$ + * $Author$ + * $State$ + * $Locker$ + * + * ------------------------------------------------------------ + ****************************************************************************/ + +/* + * SSL code intially written by + * Linas Vepstas and Sampo Kellomaki + */ + +/* -- WIN32 approved -- */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "setup.h" + +#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) +#include +#include +#include +#else +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#include +#include + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifndef HAVE_VPRINTF +#error "We can't compile without vprintf() support!" +#endif +#ifndef HAVE_SELECT +#error "We can't compile without select() support!" +#endif +#ifndef HAVE_SOCKET +#error "We can't compile without socket() support!" +#endif + +#endif + +#include "urldata.h" +#include +#include "netrc.h" + +#include "formdata.h" +#include "getenv.h" +#include "base64.h" +#include "ssluse.h" +#include "hostip.h" +#include "if2ip.h" +#include "upload.h" +#include "download.h" +#include "sendf.h" +#include "speedcheck.h" +#include "getpass.h" +#include "progress.h" +#include "cookie.h" + +/* And now for the protocols */ +#include "ftp.h" +#include "dict.h" +#include "telnet.h" +#include "http.h" +#include "file.h" +#include "ldap.h" + +#define _MPRINTF_REPLACE /* use our functions only */ +#include + +/* -- -- */ + +/*********************************************************************** + * Start with some silly functions to make win32-systems survive + ***********************************************************************/ +#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) +static void cleanup(void) +{ + WSACleanup(); +} + +static int init(void) +{ + WORD wVersionRequested; + WSADATA wsaData; + int err; + wVersionRequested = MAKEWORD(1, 1); + + err = WSAStartup(wVersionRequested, &wsaData); + + if (err != 0) + /* Tell the user that we couldn't find a useable */ + /* winsock.dll. */ + return 1; + + /* Confirm that the Windows Sockets DLL supports 1.1.*/ + /* Note that if the DLL supports versions greater */ + /* than 1.1 in addition to 1.1, it will still return */ + /* 1.1 in wVersion since that is the version we */ + /* requested. */ + + if ( LOBYTE( wsaData.wVersion ) != 1 || + HIBYTE( wsaData.wVersion ) != 1 ) { + /* Tell the user that we couldn't find a useable */ + + /* winsock.dll. */ + WSACleanup(); + return 1; + } + return 0; +} +/* The Windows Sockets DLL is acceptable. Proceed. */ +#else +static int init(void) { return 0; } +static void cleanup(void) {} +#endif + +static UrgError _urlget(struct UrlData *data); + + +void urlfree(struct UrlData *data, bool totally) +{ +#ifdef USE_SSLEAY + if (data->use_ssl) { + if(data->ssl) { + SSL_shutdown(data->ssl); + SSL_set_connect_state(data->ssl); + + SSL_free (data->ssl); + data->ssl = NULL; + } + if(data->ctx) { + SSL_CTX_free (data->ctx); + data->ctx = NULL; + } + data->use_ssl = FALSE; /* get back to ordinary socket usage */ + } +#endif /* USE_SSLEAY */ + + /* close possibly still open sockets */ + if(-1 != data->secondarysocket) { + sclose(data->secondarysocket); + data->secondarysocket = -1; + } + if(-1 != data->firstsocket) { + sclose(data->firstsocket); + data->firstsocket=-1; + } + + + 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; + } + + if(totally) { + /* we let the switch decide whether we're doing a part or total + cleanup */ + + /* check for allocated [URL] memory to free: */ + if(data->freethis) + free(data->freethis); + + if(data->headerbuff) + free(data->headerbuff); + + cookie_cleanup(data->cookies); + + free(data); + + /* winsock crap cleanup */ + cleanup(); + } +} + +typedef int (*func_T)(void); + +UrgError curl_urlget(UrgTag tag, ...) +{ + va_list arg; + func_T param_func = (func_T)0; + long param_long = 0; + void *param_obj = NULL; + UrgError res; + char *cookiefile; + + struct UrlData *data; + + /* this is for the lame win32 socket crap */ + if(init()) + return URG_FAILED_INIT; + + data = (struct UrlData *)malloc(sizeof(struct UrlData)); + if(data) { + + memset(data, 0, sizeof(struct UrlData)); + + /* Let's set some default values: */ + data->out = stdout; /* default output to stdout */ + data->in = stdin; /* default input from stdin */ + data->err = stderr; /* default stderr to stderr */ + data->firstsocket = -1; /* no file descriptor */ + data->secondarysocket = -1; /* no file descriptor */ + + /* use fwrite as default function to store output */ + data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))fwrite; + + /* use fread as default function to read input */ + data->fread = (size_t (*)(char *, size_t, size_t, FILE *))fread; + + data->infilesize = -1; /* we don't know any size */ + + data->current_speed = -1; /* init to negative == impossible */ + + va_start(arg, tag); + + while(tag != URGTAG_DONE) { + /* PORTING NOTE: + Ojbect pointers can't necessarily be casted to function pointers and + therefore we need to know what type it is and read the correct type + at once. This should also correct problems with different sizes of + the types. + */ + + if(tag < URGTYPE_OBJECTPOINT) { + /* This is a LONG type */ + param_long = va_arg(arg, long); + } + else if(tag < URGTYPE_FUNCTIONPOINT) { + /* This is a object pointer type */ + param_obj = va_arg(arg, void *); + } + else + param_func = va_arg(arg, func_T ); + + /* printf("tag: %d\n", tag); */ + + + switch(tag) { +#ifdef MULTIDOC + case URGTAG_MOREDOCS: + data->moredoc = (struct MoreDoc *)param_obj; + break; +#endif + case URGTAG_TIMECONDITION: + data->timecondition = (long)param_long; + break; + + case URGTAG_TIMEVALUE: + data->timevalue = (long)param_long; + break; + + case URGTAG_SSLVERSION: + data->ssl_version = (int)param_long; + break; + + case URGTAG_COOKIEFILE: + cookiefile = (char *)param_obj; + if(cookiefile) { + data->cookies = cookie_init(cookiefile); + } + break; + case URGTAG_WRITEHEADER: + data->writeheader = (FILE *)param_obj; + break; + case URGTAG_COOKIE: + data->cookie = (char *)param_obj; + break; + case URGTAG_ERRORBUFFER: + data->errorbuffer = (char *)param_obj; + break; + case URGTAG_FILE: + data->out = (FILE *)param_obj; + break; + case URGTAG_FTPPORT: + data->ftpport = (char *)param_obj; + break; + case URGTAG_HTTPHEADER: + data->headers = (struct HttpHeader *)param_obj; + break; + case URGTAG_CUSTOMREQUEST: + data->customrequest = (char *)param_obj; + break; + case URGTAG_HTTPPOST: + data->httppost = (struct HttpPost *)param_obj; + break; + case URGTAG_INFILE: + data->in = (FILE *)param_obj; + break; + case URGTAG_INFILESIZE: + data->infilesize = (long)param_long; + break; + case URGTAG_LOW_SPEED_LIMIT: + data->low_speed_limit=(long)param_long; + break; + case URGTAG_LOW_SPEED_TIME: + data->low_speed_time=(long)param_long; + break; + case URGTAG_URL: + data->url = (char *)param_obj; + break; + case URGTAG_PORT: + /* this typecast is used to fool the compiler to NOT warn for a + "cast from pointer to integer of different size" */ + data->port = (unsigned short)((long)param_long); + break; + case URGTAG_POSTFIELDS: + data->postfields = (char *)param_obj; + break; + case URGTAG_PROGRESSMODE: + data->progressmode = (long)param_long; + break; + case URGTAG_REFERER: + data->referer = (char *)param_obj; + break; + case URGTAG_PROXY: + data->proxy = (char *)param_obj; + break; + case URGTAG_FLAGS: + data->conf = (long)param_long; + break; + case URGTAG_TIMEOUT: + data->timeout = (long)param_long; + break; + case URGTAG_USERAGENT: + data->useragent = (char *)param_obj; + break; + case URGTAG_USERPWD: + data->userpwd = (char *)param_obj; + break; + case URGTAG_PROXYUSERPWD: + data->proxyuserpwd = (char *)param_obj; + break; + case URGTAG_RANGE: + data->range = (char *)param_obj; + break; + case URGTAG_RESUME_FROM: + data->resume_from = (long)param_long; + break; + case URGTAG_STDERR: + data->err = (FILE *)param_obj; + break; + case URGTAG_WRITEFUNCTION: + data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))param_func; + break; + case URGTAG_READFUNCTION: + data->fread = (size_t (*)(char *, size_t, size_t, FILE *))param_func; + break; + case URGTAG_SSLCERT: + data->cert = (char *)param_obj; + break; + case URGTAG_SSLCERTPASSWD: + data->cert_passwd = (char *)param_obj; + break; + case URGTAG_CRLF: + data->crlf = (long)param_long; + break; + case URGTAG_QUOTE: + data->quote = (struct curl_slist *)param_obj; + break; + case URGTAG_DONE: /* done with the parsing, fall through */ + continue; + default: + /* unknown tag and its companion, just ignore: */ + break; + } + tag = va_arg(arg, UrgTag); + } + + va_end(arg); + + data-> headerbuff=(char*)malloc(HEADERSIZE); + if(!data->headerbuff) + return URG_FAILED_INIT; + + data-> headersize=HEADERSIZE; + + res = _urlget(data); /* fetch the URL please */ + + while((res == URG_OK) && data->newurl) { + /* Location: redirect */ + char prot[16]; + char path[URL_MAX_LENGTH]; + + if(2 != sscanf(data->newurl, "%15[^:]://%" URL_MAX_LENGTH_TXT + "s", prot, path)) { + /*** + *DANG* this is an RFC 2068 violation. The URL is supposed + to be absolute and this doesn't seem to be that! + At least the Zeus HTTP server seem to do this. + *** + Instead, we have to TRY to append this new path to the old URL + to the right of the host part. Oh crap, this is doomed to cause + problems in the future... + */ + char *protsep; + char *pathsep; + char *newest; + + /* protsep points to the start of the host name */ + protsep=strstr(data->url, "//"); + if(!protsep) + protsep=data->url; + else { + data->port=0; /* we got a full URL and then we should reset the + port number here to re-initiate it later */ + protsep+=2; /* pass the // */ + } + + if('/' != data->newurl[0]) { + /* First we need to find out if there's a ?-letter in the URL, and + cut it and the right-side of that off */ + pathsep = strrchr(protsep, '?'); + if(pathsep) + *pathsep=0; + + /* we have a relative path to append to the last slash if + there's one available */ + pathsep = strrchr(protsep, '/'); + if(pathsep) + *pathsep=0; + } + else { + /* We got a new absolute path for this server, cut off from the + first slash */ + pathsep = strchr(protsep, '/'); + if(pathsep) + *pathsep=0; + } + + newest=(char *)malloc( strlen(data->url) + + 1 + /* possible slash */ + strlen(data->newurl) + 1/* zero byte */); + + if(!newest) + return URG_OUT_OF_MEMORY; + sprintf(newest, "%s%s%s", data->url, ('/' == data->newurl[0])?"":"/", + data->newurl); + free(data->newurl); + data->newurl = newest; + } + + data->url = data->newurl; + data->newurl = NULL; /* don't show! */ + + infof(data, "Follows Location: to new URL: '%s'\n", data->url); + + /* clean up the sockets and SSL stuff from the previous "round" */ + urlfree(data, FALSE); + + res = _urlget(data); + } + if(data->newurl) + free(data->newurl); + + } + else + res = URG_FAILED_INIT; /* failed */ + + /* total cleanup */ + urlfree(data, TRUE); + + return res; +} + + +/* + * Read everything until a newline. + */ + +static int GetLine(int sockfd, char *buf, + struct UrlData *data) +{ + int nread; + int read_rc=1; + char *ptr; + ptr=buf; + + /* get us a full line, terminated with a newline */ + for(nread=0; + (nreaduse_ssl) { + read_rc = SSL_read(data->ssl, ptr, 1); + } + else { +#endif + read_rc = sread(sockfd, ptr, 1); +#ifdef USE_SSLEAY + } +#endif /* USE_SSLEAY */ + if (*ptr == '\n') + break; + } + *ptr=0; /* zero terminate */ + + if(data->conf & CONF_VERBOSE) { + fputs("< ", data->err); + fwrite(buf, 1, nread, data->err); + fputs("\n", data->err); + } + return nread; +} + + + +#ifndef WIN32 +#ifndef RETSIGTYPE +#define RETSIGTYPE void +#endif +RETSIGTYPE alarmfunc(int signal) +{ + /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ + (void)signal; + return; +} +#endif + +/* ====================================================== */ +/* + * urlget + * (result put on stdout) + * + * ::= "://" [ ":" ] "/" + * + * = "HTTP" | "HTTPS" | "GOPHER" | "FTP" + * + * When FTP: + * + * ::= [ ":" "@" ] + */ + +static UrgError _urlget(struct UrlData *data) +{ + struct hostent *hp=NULL; + struct sockaddr_in serv_addr; + char *buf; + char proto[64]; + char gname[256]="default.com"; + char *name; + char path[URL_MAX_LENGTH]="/"; + char *ppath, *tmp; + long bytecount; + struct timeval now; + + UrgError result; + char resumerange[12]=""; + + buf = data->buffer; /* this is our buffer */ + +#if 0 + signal(SIGALRM, alarmfunc); +#endif + + /* Parse */ + /* We need to parse the url, even when using the proxy, because + * we will need the hostname and port in case we are trying + * to SSL connect through the proxy -- and we don't know if we + * will need to use SSL until we parse the url ... + */ + if((1 == sscanf(data->url, "file://%" URL_MAX_LENGTH_TXT "[^\n]", + path))) { + /* we deal with file:/// differently since it + supports no hostname other than "localhost" and "127.0.0.1", + which ist unique among the protocols specified in RFC 1738 */ + if (strstr(path, "localhost/") || strstr(path, "127.0.0.1/")) + strcpy(path, &path[10]); /* ... since coincidentally + both host strings are of + equal length */ + /* otherwise, / is quietly ommitted */ + + + /* that's it, no more fiddling with proxies, redirections, + or SSL for files, go directly to the file reading function */ + result = file(data, path, &bytecount); + if(result) + return result; + + return URG_OK; + } + else if (2 > sscanf(data->url, "%64[^\n:]://%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", + proto, gname, path)) { + + + /* badly formatted, let's try the browser-style _without_ 'http://' */ + if((1 > sscanf(data->url, "%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", gname, + path)) ) { + failf(data, " malformed"); + return URG_URL_MALFORMAT; + } + if(strnequal(gname, "FTP", 3)) { + strcpy(proto, "ftp"); + } + else if(strnequal(gname, "GOPHER", 6)) + strcpy(proto, "gopher"); +#ifdef USE_SSLEAY + else if(strnequal(gname, "HTTPS", 5)) + strcpy(proto, "https"); +#endif /* USE_SSLEAY */ + else if(strnequal(gname, "TELNET", 6)) + strcpy(proto, "telnet"); + else if (strnequal(gname, "DICT", sizeof("DICT")-1)) + strcpy(proto, "DICT"); + else if (strnequal(gname, "LDAP", sizeof("LDAP")-1)) + strcpy(proto, "LDAP"); + else + strcpy(proto, "http"); + + data->conf |= CONF_NOPROT; + } + + + if((data->conf & CONF_USERPWD) && ! (data->conf & CONF_NETRC)) { + if(':' != *data->userpwd) { + if((1 <= sscanf(data->userpwd, "%127[^:]:%127s", + data->user, data->passwd))) { + /* check for password, if no ask for one */ + if( !data->passwd[0] ) + { + strncpy(data->passwd, getpass("password: "), sizeof(data->passwd)); + } + } + } + if(!data->user[0]) { + failf(data, "USER malformat: user name can't be zero length"); + return URG_MALFORMAT_USER; + } + } + + if(data->conf & CONF_PROXYUSERPWD) { + if(':' != *data->proxyuserpwd) { + if((1 <= sscanf(data->proxyuserpwd, "%127[^:]:%127s", + data->proxyuser, data->proxypasswd))) { + /* check for password, if no ask for one */ + if( !data->proxypasswd[0] ) + { + strncpy(data->proxypasswd, getpass("proxy password: "), sizeof(data->proxypasswd)); + } + } + } + if(!data->proxyuser[0]) { + failf(data, " Proxy USER malformat: user name can't be zero length"); + return URG_MALFORMAT_USER; + } + } + + name = gname; + ppath = path; + data->hostname = name; + + + if(!(data->conf & CONF_PROXY)) { + /* If proxy was not specified, we check for default proxy environment + variables, to enable i.e Lynx compliance: + + HTTP_PROXY http://some.server.dom:port/ + HTTPS_PROXY http://some.server.dom:port/ + FTP_PROXY http://some.server.dom:port/ + GOPHER_PROXY http://some.server.dom:port/ + NO_PROXY host.domain.dom (a comma-separated list of hosts which should + not be proxied, or an asterisk to override all proxy variables) + ALL_PROXY seems to exist for the CERN www lib. Probably the first to + check for. + + */ + char *no_proxy=GetEnv("NO_PROXY"); + char *proxy=NULL; + char proxy_env[128]; + + if(!no_proxy || !strequal("*", no_proxy)) { + /* NO_PROXY wasn't specified or it wasn't just an asterisk */ + char *nope; + + nope=no_proxy?strtok(no_proxy, ", "):NULL; + while(nope) { + if(strlen(nope) <= strlen(name)) { + char *checkn= + name + strlen(name) - strlen(nope); + if(strnequal(nope, checkn, strlen(nope))) { + /* no proxy for this host! */ + break; + } + } + nope=strtok(NULL, ", "); + } + if(!nope) { + /* It was not listed as without proxy */ + char *protop = proto; + char *envp = proxy_env; + char *prox; + + /* Now, build _PROXY and check for such a one to use */ + while(*protop) { + *envp++ = toupper(*protop++); + } + /* append _PROXY */ + strcpy(envp, "_PROXY"); +#if 0 + infof(data, "DEBUG: checks the environment variable %s\n", proxy_env); +#endif + /* read the protocol proxy: */ + prox=GetEnv(proxy_env); + + if(prox && *prox) { /* don't count "" strings */ + proxy = prox; /* use this */ + } + else + proxy = GetEnv("ALL_PROXY"); /* default proxy to use */ + + if(proxy && *proxy) { + /* we have a proxy here to set */ + data->proxy = proxy; + data->conf |= CONF_PROXY; + } + } /* if (!nope) - it wasn't specfied non-proxy */ + } /* NO_PROXY wasn't specified or '*' */ + } /* if not using proxy */ + + if((data->conf & (CONF_PROXY|CONF_NOPROT)) == (CONF_PROXY|CONF_NOPROT) ) { + /* 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 = maprintf("%s://%s", proto, data->url); + + if(!reurl) + return URG_OUT_OF_MEMORY; + + data->url = reurl; + if(data->freethis) + free(data->freethis); + data->freethis = reurl; + + data->conf &= ~CONF_NOPROT; /* switch that one off again */ + } + + /* RESUME on a HTTP page is a tricky business. First, let's just check that + 'range' isn't used, then set the range parameter and leave the resume as + it is to inform about this situation for later use. We will then + "attempt" to resume, and if we're talking to a HTTP/1.1 (or later) + server, we will get the document resumed. If we talk to a HTTP/1.0 + server, we just fail since we can't rewind the file writing from within + this function. */ + if(data->resume_from) { + if(!(data->conf & CONF_RANGE)) { + /* if it already was in use, we just skip this */ + sprintf(resumerange, "%d-", data->resume_from); + data->range=resumerange; /* tell ourselves to fetch this range */ + data->conf |= CONF_RANGE; /* switch on range usage */ + } + } + + + if(data->timeout) { + /* We set the timeout on the connection/resolving phase first, separately + from the download/upload part to allow a maximum time on everything */ + myalarm(data->timeout); /* this sends a signal when the timeout fires + off, and that will abort system calls */ + } + + /* + * Hmm, if we are using a proxy, then we can skip the GOPHER and the + * FTP steps, although we cannot skip the HTTPS step (since the proxy + * works differently, depending on whether its SSL or not). + */ + + if (strequal(proto, "HTTP")) { + if(!data->port) + data->port = PORT_HTTP; + data->remote_port = PORT_HTTP; + data->conf |= CONF_HTTP; + } + else if (strequal(proto, "HTTPS")) { +#ifdef USE_SSLEAY + if(!data->port) + data->port = PORT_HTTPS; + data->remote_port = PORT_HTTPS; + data->conf |= CONF_HTTP; + data->conf |= CONF_HTTPS; +#else /* USE_SSLEAY */ + failf(data, "SSL is disabled, https: not supported!"); + return URG_UNSUPPORTED_PROTOCOL; +#endif /* !USE_SSLEAY */ + } + else if (strequal(proto, "GOPHER")) { + if(!data->port) + data->port = PORT_GOPHER; + data->remote_port = PORT_GOPHER; + /* Skip // in path if present */ + if (isdigit((int)path[1])) { + ppath = strchr(&path[1], '/'); + if (ppath == NULL) + ppath = path; + } + data->conf |= CONF_GOPHER; + } + else if(strequal(proto, "FTP")) { + char *type; + if(!data->port) + data->port = PORT_FTP; + data->remote_port = PORT_FTP; + data->conf |= CONF_FTP; + + ppath++; /* don't include the initial slash */ + + /* FTP URLs support an extension like ";type=" that + we'll try to get now! */ + type=strstr(ppath, ";type="); + if(!type) { + type=strstr(gname, ";type="); + } + if(type) { + char command; + *type=0; + command = toupper(type[6]); + switch(command) { + case 'A': /* ASCII mode */ + data->conf |= CONF_FTPASCII; + break; + case 'D': /* directory mode */ + data->conf |= CONF_FTPLISTONLY; + break; + case 'I': /* binary mode */ + default: + /* switch off ASCII */ + data->conf &= ~CONF_FTPASCII; + break; + } + } + } + else if(strequal(proto, "TELNET")) { + /* telnet testing factory */ + data->conf |= CONF_TELNET; + if(!data->port) + data->port = PORT_TELNET; + data->remote_port = PORT_TELNET; + } + else if (strequal(proto, "DICT")) { + data->conf |= CONF_DICT; + if(!data->port) + data->port = PORT_DICT; + data->remote_port = PORT_DICT; + } + else if (strequal(proto, "LDAP")) { + data->conf |= CONF_LDAP; + if(!data->port) + data->port = PORT_LDAP; + data->remote_port = PORT_LDAP; + } + /* file:// is handled above */ + /* else if (strequal(proto, "FILE")) { + data->conf |= CONF_FILE; + + result = file(data, path, &bytecount); + if(result) + return result; + + return URG_OK; + }*/ + else { + failf(data, "Unsupported protocol: %s", proto); + return URG_UNSUPPORTED_PROTOCOL; + } + + if(data->conf & CONF_NETRC) { + if(ParseNetrc(data->hostname, data->user, data->passwd)) { + infof(data, "Couldn't find host %s in the .netrc file, using defaults", + data->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->conf & CONF_HTTP) { + data->conf |= CONF_USERPWD; + } + } + else if(!(data->conf & CONF_USERPWD) && + (data->conf & (CONF_FTP|CONF_HTTP)) ) { + /* This is a FTP or HTTP URL, and we haven't got the user+password in + the extra parameter, 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=NULL; /* assign to remove possible warnings */ + if(':' == *name) { + failf(data, "URL malformat: user can't be zero length"); + return URG_URL_MALFORMAT_USER; + } + if((1 <= sscanf(name, "%127[^:]:%127[^@]", + data->user, data->passwd)) && (ptr=strchr(name, '@'))) { + name = ++ptr; + data->conf |= CONF_USERPWD; + } + else { + strcpy(data->user, CURL_DEFAULT_USER); + strcpy(data->passwd, CURL_DEFAULT_PASSWORD); + } + } + + if(!(data->conf & CONF_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. */ + tmp = strchr(name, ':'); + if (tmp) { + *tmp++ = '\0'; + data->port = atoi(tmp); + } + + /* Connect to target host right on */ + if(!(hp = GetHost(data, name))) { + failf(data, "Couldn't resolv host '%s'", name); + return URG_COULDNT_RESOLVE_HOST; + } + } + else { + char *prox_portno; + char *endofprot; + + /* we use proxy all right, but we wanna know the remote port for SSL + reasons */ + tmp = strchr(name, ':'); + if (tmp) { + *tmp++ = '\0'; /* cut off the name there */ + data->remote_port = atoi(tmp); + } + + /* Daniel Dec 10, 1998: + We do the proxy host string parsing here. We want the host name and the + port name. Accept a protocol:// prefix, even though it should just be + ignored. */ + + /* 1. skip the protocol part if present */ + endofprot=strstr(data->proxy, "://"); + if(endofprot) { + data->proxy = endofprot+3; + } + + /* allow user to specify proxy.server.com:1080 if desired */ + prox_portno = strchr (data->proxy, ':'); + if (prox_portno) { + *prox_portno = 0x0; /* cut off number from host name */ + prox_portno ++; + /* now set the local port number */ + data->port = atoi(prox_portno); + } + + /* connect to proxy */ + if(!(hp = GetHost(data, data->proxy))) { + failf(data, "Couldn't resolv proxy '%s'", data->proxy); + return URG_COULDNT_RESOLVE_PROXY; + } + } + + data->firstsocket = socket(AF_INET, SOCK_STREAM, 0); + + memset((char *) &serv_addr, '\0', sizeof(serv_addr)); + memcpy((char *)&(serv_addr.sin_addr), hp->h_addr, hp->h_length); + serv_addr.sin_family = hp->h_addrtype; + + serv_addr.sin_port = htons(data->port); + + if (connect(data->firstsocket, (struct sockaddr *) &serv_addr, + sizeof(serv_addr)) < 0) { + switch(errno) { +#ifdef ECONNREFUSED + /* this should be made nicer */ + case ECONNREFUSED: + failf(data, "Connection refused"); + break; +#endif +#ifdef EINTR + case EINTR: + failf(data, "Connection timeouted"); + break; +#endif + default: + failf(data, "Can't connect to server: %d", errno); + break; + } + return URG_COULDNT_CONNECT; + } + + if(data->conf & CONF_PROXYUSERPWD) { + char authorization[512]; + sprintf(data->buffer, "%s:%s", data->proxyuser, data->proxypasswd); + base64Encode(data->buffer, authorization); + + data->ptr_proxyuserpwd = maprintf("Proxy-authorization: Basic %s\015\012", + authorization); + } + if(data->conf & (CONF_HTTPS|CONF_HTTP)) { + if(data->useragent) { + data->ptr_uagent = maprintf("User-Agent: %s\015\012", data->useragent); + } + } + + + /* If we are not using a proxy and we want a secure connection, + * perform SSL initialization & connection now. + * If using a proxy with https, then we must tell the proxy to CONNECT + * us to the host we want to talk to. Only after the connect + * has occured, can we start talking SSL + */ + if (data->conf & CONF_HTTPS) { + if (data->conf & CONF_PROXY) { + + /* OK, now send the connect statment */ + sendf(data->firstsocket, data, + "CONNECT %s:%d HTTP/1.0\015\012" + "%s" + "%s" + "\r\n", + data->hostname, data->remote_port, + (data->conf&CONF_PROXYUSERPWD)?data->ptr_proxyuserpwd:"", + (data->useragent?data->ptr_uagent:"") + ); + + /* wait for the proxy to send us a HTTP/1.0 200 OK header */ + /* Daniel rewrote this part Nov 5 1998 to make it more obvious */ + { + int httperror=0; + int subversion=0; + while(GetLine(data->firstsocket, data->buffer, data)) { + if('\r' == data->buffer[0]) + break; /* end of headers */ + if(2 == sscanf(data->buffer, "HTTP/1.%d %d", + &subversion, + &httperror)) { + ; + } + } + if(200 != httperror) { + if(407 == httperror) + /* Added Nov 6 1998 */ + failf(data, "Proxy requires authorization!"); + else + failf(data, "Received error code %d from proxy", httperror); + return URG_READ_ERROR; + } + } + infof (data, "Proxy has replied to CONNECT request\n"); + } + + /* now, perform the SSL initialization for this socket */ + if(UrgSSLConnect (data)) { + return URG_SSL_CONNECT_ERROR; + } + } + + now = tvnow(); /* time this *after* the connect is done */ + bytecount = 0; + + /* Figure out the ip-number and the first host name it shows: */ + { + struct in_addr in; + (void) memcpy(&in.s_addr, *hp->h_addr_list, sizeof (in.s_addr)); + infof(data, "Connected to %s (%s)\n", hp->h_name, inet_ntoa(in)); + } + + if((data->conf&(CONF_FTP|CONF_PROXY)) == CONF_FTP) { + result = ftp(data, &bytecount, data->user, data->passwd, ppath); + if(result) + return result; + } + else if(data->conf & CONF_TELNET) { + result=telnet(data); + if(result) + return result; + } + else if (data->conf & CONF_LDAP) { + result = ldap(data, path, &bytecount); + if (result) + return result; + } + else if (data->conf & CONF_DICT) { + result = dict(data, path, &bytecount); + if(result) + return result; + } + else { + result = http(data, ppath, name, &bytecount); + if(result) + return result; + } + if(bytecount) { + double ittook = tvdiff (tvnow(), now); + infof(data, "%i bytes transfered in %.3lf seconds (%.0lf bytes/sec).\n", + bytecount, ittook, (double)bytecount/(ittook!=0.0?ittook:1)); + } + return URG_OK; +} + -- cgit v1.2.1 From 26e8ccc63151a1c12db709cef4051803afd21189 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 Jan 2000 23:36:14 +0000 Subject: syncing with local edit --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b520898dc..2abdb6343 100644 --- a/lib/url.c +++ b/lib/url.c @@ -413,6 +413,9 @@ UrgError curl_urlget(UrgTag tag, ...) case URGTAG_USERPWD: data->userpwd = (char *)param_obj; break; + case URGTAG_POSTQUOTE: + data->postquote = (struct curl_slist *)param_obj; + break; case URGTAG_PROXYUSERPWD: data->proxyuserpwd = (char *)param_obj; break; -- cgit v1.2.1 From 2be8c7a4e9875a126b7362398237c82b9860173f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 19 Jan 2000 21:57:48 +0000 Subject: - Oskar Liljeblad pointed out and corrected a problem in the Location: following system that made curl following a location: to a different protocol to fail. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2abdb6343..34fc51f4d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -533,6 +533,8 @@ UrgError curl_urlget(UrgTag tag, ...) infof(data, "Follows Location: to new URL: '%s'\n", data->url); + data->port = 0; /* clear the port number so that we don't make any silly + assumptions for the new URL! */ /* clean up the sockets and SSL stuff from the previous "round" */ urlfree(data, FALSE); -- cgit v1.2.1 From fd921c8cd6d308e2ad8f027917ea4a947c6c96b0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Jan 2000 22:20:17 +0000 Subject: removed the port number reset again, it is already being made when the location: URL turns out to be an "absolute" one and that should be the only time it is required. --- lib/url.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 34fc51f4d..de36b2e22 100644 --- a/lib/url.c +++ b/lib/url.c @@ -475,7 +475,6 @@ UrgError curl_urlget(UrgTag tag, ...) /*** *DANG* this is an RFC 2068 violation. The URL is supposed to be absolute and this doesn't seem to be that! - At least the Zeus HTTP server seem to do this. *** Instead, we have to TRY to append this new path to the old URL to the right of the host part. Oh crap, this is doomed to cause @@ -533,8 +532,6 @@ UrgError curl_urlget(UrgTag tag, ...) infof(data, "Follows Location: to new URL: '%s'\n", data->url); - data->port = 0; /* clear the port number so that we don't make any silly - assumptions for the new URL! */ /* clean up the sockets and SSL stuff from the previous "round" */ urlfree(data, FALSE); -- cgit v1.2.1 From bc375152b1626ca7dfa11587732de279a84b2c5f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 1 Feb 2000 23:57:54 +0000 Subject: removed include upload.h --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index de36b2e22..0443f1608 100644 --- a/lib/url.c +++ b/lib/url.c @@ -110,7 +110,6 @@ #include "ssluse.h" #include "hostip.h" #include "if2ip.h" -#include "upload.h" #include "download.h" #include "sendf.h" #include "speedcheck.h" -- cgit v1.2.1 From 582754c0e24c36de3930ca40d99152e811da188b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 14 Feb 2000 23:03:05 +0000 Subject: uses the new progress functions --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0443f1608..39046ea37 100644 --- a/lib/url.c +++ b/lib/url.c @@ -392,7 +392,7 @@ UrgError curl_urlget(UrgTag tag, ...) data->postfields = (char *)param_obj; break; case URGTAG_PROGRESSMODE: - data->progressmode = (long)param_long; + data->progress.mode = (long)param_long; break; case URGTAG_REFERER: data->referer = (char *)param_obj; @@ -456,6 +456,8 @@ UrgError curl_urlget(UrgTag tag, ...) va_end(arg); + pgrsMode(data, data->progress.mode); + data-> headerbuff=(char*)malloc(HEADERSIZE); if(!data->headerbuff) return URG_FAILED_INIT; -- cgit v1.2.1 From 8ed78f6c380509083a2b830801f8353f59f48fef Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 16 Feb 2000 00:01:50 +0000 Subject: Now starts the progress meter timer at once! --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 39046ea37..9458acf3a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -457,6 +457,7 @@ UrgError curl_urlget(UrgTag tag, ...) va_end(arg); pgrsMode(data, data->progress.mode); + pgrsStartNow(data); data-> headerbuff=(char*)malloc(HEADERSIZE); if(!data->headerbuff) -- cgit v1.2.1 From 10f958029a12a8ba7be12332e7e98df7c13f423e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 21 Feb 2000 23:51:09 +0000 Subject: Added writeout stuff --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9458acf3a..9b4977eb5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -430,6 +430,9 @@ UrgError curl_urlget(UrgTag tag, ...) case URGTAG_WRITEFUNCTION: data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))param_func; break; + case URGTAG_WRITEINFO: + data->writeinfo = (char *)param_obj; + break; case URGTAG_READFUNCTION: data->fread = (size_t (*)(char *, size_t, size_t, FILE *))param_func; break; @@ -546,6 +549,12 @@ UrgError curl_urlget(UrgTag tag, ...) else res = URG_FAILED_INIT; /* failed */ + if((URG_OK == res) && data->writeinfo) { + /* Time to output some info to stdout */ + WriteOut(data); + } + + /* total cleanup */ urlfree(data, TRUE); -- cgit v1.2.1 From dfd341efd536244d6b12945ba039044b47626eed Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 1 Mar 2000 22:05:11 +0000 Subject: Added two new time stamp places --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9b4977eb5..3c95a39f3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1052,6 +1052,7 @@ static UrgError _urlget(struct UrlData *data) return URG_COULDNT_RESOLVE_PROXY; } } + pgrsTime(data, TIMER_NAMELOOKUP); data->firstsocket = socket(AF_INET, SOCK_STREAM, 0); @@ -1148,6 +1149,7 @@ static UrgError _urlget(struct UrlData *data) return URG_SSL_CONNECT_ERROR; } } + pgrsTime(data, TIMER_CONNECT); now = tvnow(); /* time this *after* the connect is done */ bytecount = 0; -- cgit v1.2.1 From 2f668aba96f9e8eaa67472839e56e7a96d3614f8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 27 Mar 2000 21:36:05 +0000 Subject: "H. Daphne Luong" pointed out that curl cannot destroy the proxy server data internally as it did, since when doing a location: following it needs the proxy server string several times. --- lib/url.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3c95a39f3..ec72cc644 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1018,6 +1018,18 @@ static UrgError _urlget(struct UrlData *data) char *prox_portno; char *endofprot; + /* We need to make a duplicate of the proxy so that we can modify the + string safely. */ + char *proxydup=strdup(data->proxy); + + /* We use 'proxyptr' to point to the proxy name from now on... */ + char *proxyptr=proxydup; + + if(NULL == proxydup) { + failf(data, "memory shortage"); + return URG_OUT_OF_MEMORY; + } + /* we use proxy all right, but we wanna know the remote port for SSL reasons */ tmp = strchr(name, ':'); @@ -1032,13 +1044,13 @@ static UrgError _urlget(struct UrlData *data) ignored. */ /* 1. skip the protocol part if present */ - endofprot=strstr(data->proxy, "://"); + endofprot=strstr(proxyptr, "://"); if(endofprot) { - data->proxy = endofprot+3; + proxyptr = endofprot+3; } /* allow user to specify proxy.server.com:1080 if desired */ - prox_portno = strchr (data->proxy, ':'); + prox_portno = strchr (proxyptr, ':'); if (prox_portno) { *prox_portno = 0x0; /* cut off number from host name */ prox_portno ++; @@ -1047,10 +1059,12 @@ static UrgError _urlget(struct UrlData *data) } /* connect to proxy */ - if(!(hp = GetHost(data, data->proxy))) { - failf(data, "Couldn't resolv proxy '%s'", data->proxy); + if(!(hp = GetHost(data, proxyptr))) { + failf(data, "Couldn't resolv proxy '%s'", proxyptr); return URG_COULDNT_RESOLVE_PROXY; } + + free(proxydup); /* free the duplicate pointer and not the modified */ } pgrsTime(data, TIMER_NAMELOOKUP); -- cgit v1.2.1 From 005991126181a2967b2d0a5d3a20685837b763f1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 2 Apr 2000 12:08:12 +0000 Subject: James Atwill correctly pointed out that curl didn't follow Location: headers properly when the new URL is an absolute one to a different port than the first URL... --- lib/url.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ec72cc644..e47f0568b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -531,7 +531,11 @@ UrgError curl_urlget(UrgTag tag, ...) free(data->newurl); data->newurl = newest; } - + else { + /* This was an absolute URL, clear the port number! */ + data->port = 0; + } + data->url = data->newurl; data->newurl = NULL; /* don't show! */ @@ -1175,6 +1179,10 @@ static UrgError _urlget(struct UrlData *data) infof(data, "Connected to %s (%s)\n", hp->h_name, inet_ntoa(in)); } +#if 0 /* Kerberos experiements! Beware! Take cover! */ + kerberos_connect(data, name); +#endif + if((data->conf&(CONF_FTP|CONF_PROXY)) == CONF_FTP) { result = ftp(data, &bytecount, data->user, data->passwd, ppath); if(result) -- cgit v1.2.1 From 00ad88408d3e4df9413cf9d9f0f9b2d6ce111687 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 Apr 2000 17:44:24 +0000 Subject: Marco G. Salvagno's OS/2 patch is applied --- lib/url.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e47f0568b..7152511f6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1183,6 +1183,19 @@ static UrgError _urlget(struct UrlData *data) kerberos_connect(data, name); #endif +#ifdef __EMX__ + /* 20000330 mgs + * the check is quite a hack... + * we're calling _fsetmode to fix the problem with fwrite converting newline + * 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) { + fprintf(stderr, "_fsetmode\n"); + _fsetmode(stdout, "b"); + } +#endif + if((data->conf&(CONF_FTP|CONF_PROXY)) == CONF_FTP) { result = ftp(data, &bytecount, data->user, data->passwd, ppath); if(result) -- cgit v1.2.1 From c30a3913b59dc13bf90819450bc7f4242f63767c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 Apr 2000 18:08:34 +0000 Subject: Marco's fix got adjusted --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7152511f6..1b1607fd1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1191,7 +1191,6 @@ static UrgError _urlget(struct UrlData *data) * you download to stdout and redirect it to a file). */ if ((data->out)->_handle == NULL) { - fprintf(stderr, "_fsetmode\n"); _fsetmode(stdout, "b"); } #endif -- cgit v1.2.1 From 75cd7f482d9cebe0169c8a8b82203d2d7cf65a9f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 8 Apr 2000 19:29:58 +0000 Subject: now sends user agent to all requests that go through a http proxy --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1b1607fd1..6211f9470 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1109,7 +1109,7 @@ static UrgError _urlget(struct UrlData *data) data->ptr_proxyuserpwd = maprintf("Proxy-authorization: Basic %s\015\012", authorization); } - if(data->conf & (CONF_HTTPS|CONF_HTTP)) { + if(data->conf & (CONF_HTTPS|CONF_HTTP|CONF_PROXY)) { if(data->useragent) { data->ptr_uagent = maprintf("User-Agent: %s\015\012", data->useragent); } -- cgit v1.2.1 From 0d12792514878d372339929cf993845ce948bd5d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Apr 2000 21:47:28 +0000 Subject: now uses a tiny bit of the new library interface! --- lib/url.c | 358 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 203 insertions(+), 155 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6211f9470..75dd89559 100644 --- a/lib/url.c +++ b/lib/url.c @@ -124,6 +124,7 @@ #include "http.h" #include "file.h" #include "ldap.h" +#include "writeout.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -134,12 +135,12 @@ * Start with some silly functions to make win32-systems survive ***********************************************************************/ #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -static void cleanup(void) +static void win32_cleanup(void) { WSACleanup(); } -static int init(void) +static UrgError win32_init(void) { WORD wVersionRequested; WSADATA wsaData; @@ -151,7 +152,7 @@ static int init(void) if (err != 0) /* Tell the user that we couldn't find a useable */ /* winsock.dll. */ - return 1; + return URG_FAILED_INIT; /* Confirm that the Windows Sockets DLL supports 1.1.*/ /* Note that if the DLL supports versions greater */ @@ -165,16 +166,36 @@ static int init(void) /* winsock.dll. */ WSACleanup(); - return 1; + return URG_FAILED_INIT; } - return 0; + return URG_OK; } /* The Windows Sockets DLL is acceptable. Proceed. */ #else -static int init(void) { return 0; } -static void cleanup(void) {} +static UrgError win32_init(void) { return URG_OK; } +#define win32_cleanup() #endif + +/* + * This is the main global constructor for the lib. Call this before + * _any_ libcurl usage. If this fails, *NO* libcurl functions may be + * used, or havoc may be the result. + */ +UrgError curl_init(void) +{ + return win32_init(); +} + +/* + * This is the main global destructor for the lib. Call this after + * _all_ libcurl usage is done. + */ +void curl_free(void) +{ + win32_cleanup(); +} + static UrgError _urlget(struct UrlData *data); @@ -252,11 +273,170 @@ void urlfree(struct UrlData *data, bool totally) free(data); - /* winsock crap cleanup */ - cleanup(); + /* global cleanup */ + curl_free(); + } +} + +typedef struct UrlData CURL; + +UrgError curl_open(CURL **curl, char *url) +{ + /* We don't yet support specifying the URL at this point */ + + /* Very simple start-up: alloc the struct, init it with zeroes and return */ + CURL *data = (CURL *)malloc(sizeof(CURL)); + if(data) { + memset(data, 0, sizeof(CURL)); + *curl = data; + return URG_OK; + } + + /* this is a very serious error */ + return URG_OUT_OF_MEMORY; +} + +typedef unsigned int CURLoption; + +UrgError curl_setopt(CURL *curl, CURLoption option, ...) +{ + struct UrlData *data = curl; + va_list param; + char *cookiefile; + + va_start(param, option); + + switch(option) { + case URGTAG_TIMECONDITION: + data->timecondition = va_arg(param, long); + break; + + case URGTAG_TIMEVALUE: + data->timevalue = va_arg(param, long); + break; + + case URGTAG_SSLVERSION: + data->ssl_version = va_arg(param, long); + break; + + case URGTAG_COOKIEFILE: + cookiefile = (char *)va_arg(param, void *); + if(cookiefile) { + data->cookies = cookie_init(cookiefile); + } + break; + case URGTAG_WRITEHEADER: + data->writeheader = (FILE *)va_arg(param, FILE *); + break; + case URGTAG_COOKIE: + data->cookie = va_arg(param, char *); + break; + case URGTAG_ERRORBUFFER: + data->errorbuffer = va_arg(param, char *); + break; + case URGTAG_FILE: + data->out = va_arg(param, FILE *); + break; + case URGTAG_FTPPORT: + data->ftpport = va_arg(param, char *); + break; + case URGTAG_HTTPHEADER: + data->headers = va_arg(param, struct HttpHeader *); + break; + case URGTAG_CUSTOMREQUEST: + data->customrequest = va_arg(param, char *); + break; + case URGTAG_HTTPPOST: + data->httppost = va_arg(param, struct HttpPost *); + break; + case URGTAG_INFILE: + data->in = va_arg(param, FILE *); + break; + case URGTAG_INFILESIZE: + data->infilesize = va_arg(param, long); + break; + case URGTAG_LOW_SPEED_LIMIT: + data->low_speed_limit=va_arg(param, long); + break; + case URGTAG_LOW_SPEED_TIME: + data->low_speed_time=va_arg(param, long); + break; + case URGTAG_URL: + data->url = va_arg(param, char *); + break; + case URGTAG_PORT: + /* this typecast is used to fool the compiler to NOT warn for a + "cast from pointer to integer of different size" */ + data->port = (unsigned short)(va_arg(param, long)); + break; + case URGTAG_POSTFIELDS: + data->postfields = va_arg(param, char *); + break; + case URGTAG_PROGRESSMODE: + data->progress.mode = va_arg(param, long); + break; + case URGTAG_REFERER: + data->referer = va_arg(param, char *); + break; + case URGTAG_PROXY: + data->proxy = va_arg(param, char *); + break; + case URGTAG_FLAGS: + data->conf = va_arg(param, long); + break; + case URGTAG_TIMEOUT: + data->timeout = va_arg(param, long); + break; + case URGTAG_USERAGENT: + data->useragent = va_arg(param, char *); + break; + case URGTAG_USERPWD: + data->userpwd = va_arg(param, char *); + break; + case URGTAG_POSTQUOTE: + data->postquote = va_arg(param, struct curl_slist *); + break; + case URGTAG_PROXYUSERPWD: + data->proxyuserpwd = va_arg(param, char *); + break; + case URGTAG_RANGE: + data->range = va_arg(param, char *); + break; + case URGTAG_RESUME_FROM: + data->resume_from = va_arg(param, long); + break; + case URGTAG_STDERR: + data->err = va_arg(param, FILE *); + break; + case URGTAG_WRITEFUNCTION: + data->fwrite = va_arg(param, void *); + break; + case URGTAG_WRITEINFO: + data->writeinfo = va_arg(param, char *); + break; + case URGTAG_READFUNCTION: + data->fread = va_arg(param, void *); + break; + case URGTAG_SSLCERT: + data->cert = va_arg(param, char *); + break; + case URGTAG_SSLCERTPASSWD: + data->cert_passwd = va_arg(param, char *); + break; + case URGTAG_CRLF: + data->crlf = va_arg(param, long); + break; + case URGTAG_QUOTE: + data->quote = va_arg(param, struct curl_slist *); + break; + default: + /* unknown tag and its companion, just ignore: */ + return URG_READ_ERROR; /* correct this */ } + return URG_OK; } + typedef int (*func_T)(void); UrgError curl_urlget(UrgTag tag, ...) @@ -266,23 +446,23 @@ UrgError curl_urlget(UrgTag tag, ...) long param_long = 0; void *param_obj = NULL; UrgError res; - char *cookiefile; struct UrlData *data; /* this is for the lame win32 socket crap */ - if(init()) + if(curl_init()) return URG_FAILED_INIT; - data = (struct UrlData *)malloc(sizeof(struct UrlData)); - if(data) { - - memset(data, 0, sizeof(struct UrlData)); + /* We use curl_open() with undefined URL so far */ + res = curl_open(&data, NULL); + if(res == URG_OK) { + /* data is now filled with good-looking zeroes */ /* Let's set some default values: */ - data->out = stdout; /* default output to stdout */ - data->in = stdin; /* default input from stdin */ - data->err = stderr; /* default stderr to stderr */ + curl_setopt(data, URGTAG_FILE, stdout); /* default output to stdout */ + curl_setopt(data, URGTAG_INFILE, stdin); /* default input from stdin */ + curl_setopt(data, URGTAG_STDERR, stderr); /* default stderr to stderr! */ + data->firstsocket = -1; /* no file descriptor */ data->secondarysocket = -1; /* no file descriptor */ @@ -309,151 +489,19 @@ UrgError curl_urlget(UrgTag tag, ...) if(tag < URGTYPE_OBJECTPOINT) { /* This is a LONG type */ param_long = va_arg(arg, long); + curl_setopt(data, tag, param_long); } else if(tag < URGTYPE_FUNCTIONPOINT) { /* This is a object pointer type */ param_obj = va_arg(arg, void *); + curl_setopt(data, tag, param_obj); } - else + else { param_func = va_arg(arg, func_T ); + curl_setopt(data, tag, param_func); + } /* printf("tag: %d\n", tag); */ - - - switch(tag) { -#ifdef MULTIDOC - case URGTAG_MOREDOCS: - data->moredoc = (struct MoreDoc *)param_obj; - break; -#endif - case URGTAG_TIMECONDITION: - data->timecondition = (long)param_long; - break; - - case URGTAG_TIMEVALUE: - data->timevalue = (long)param_long; - break; - - case URGTAG_SSLVERSION: - data->ssl_version = (int)param_long; - break; - - case URGTAG_COOKIEFILE: - cookiefile = (char *)param_obj; - if(cookiefile) { - data->cookies = cookie_init(cookiefile); - } - break; - case URGTAG_WRITEHEADER: - data->writeheader = (FILE *)param_obj; - break; - case URGTAG_COOKIE: - data->cookie = (char *)param_obj; - break; - case URGTAG_ERRORBUFFER: - data->errorbuffer = (char *)param_obj; - break; - case URGTAG_FILE: - data->out = (FILE *)param_obj; - break; - case URGTAG_FTPPORT: - data->ftpport = (char *)param_obj; - break; - case URGTAG_HTTPHEADER: - data->headers = (struct HttpHeader *)param_obj; - break; - case URGTAG_CUSTOMREQUEST: - data->customrequest = (char *)param_obj; - break; - case URGTAG_HTTPPOST: - data->httppost = (struct HttpPost *)param_obj; - break; - case URGTAG_INFILE: - data->in = (FILE *)param_obj; - break; - case URGTAG_INFILESIZE: - data->infilesize = (long)param_long; - break; - case URGTAG_LOW_SPEED_LIMIT: - data->low_speed_limit=(long)param_long; - break; - case URGTAG_LOW_SPEED_TIME: - data->low_speed_time=(long)param_long; - break; - case URGTAG_URL: - data->url = (char *)param_obj; - break; - case URGTAG_PORT: - /* this typecast is used to fool the compiler to NOT warn for a - "cast from pointer to integer of different size" */ - data->port = (unsigned short)((long)param_long); - break; - case URGTAG_POSTFIELDS: - data->postfields = (char *)param_obj; - break; - case URGTAG_PROGRESSMODE: - data->progress.mode = (long)param_long; - break; - case URGTAG_REFERER: - data->referer = (char *)param_obj; - break; - case URGTAG_PROXY: - data->proxy = (char *)param_obj; - break; - case URGTAG_FLAGS: - data->conf = (long)param_long; - break; - case URGTAG_TIMEOUT: - data->timeout = (long)param_long; - break; - case URGTAG_USERAGENT: - data->useragent = (char *)param_obj; - break; - case URGTAG_USERPWD: - data->userpwd = (char *)param_obj; - break; - case URGTAG_POSTQUOTE: - data->postquote = (struct curl_slist *)param_obj; - break; - case URGTAG_PROXYUSERPWD: - data->proxyuserpwd = (char *)param_obj; - break; - case URGTAG_RANGE: - data->range = (char *)param_obj; - break; - case URGTAG_RESUME_FROM: - data->resume_from = (long)param_long; - break; - case URGTAG_STDERR: - data->err = (FILE *)param_obj; - break; - case URGTAG_WRITEFUNCTION: - data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))param_func; - break; - case URGTAG_WRITEINFO: - data->writeinfo = (char *)param_obj; - break; - case URGTAG_READFUNCTION: - data->fread = (size_t (*)(char *, size_t, size_t, FILE *))param_func; - break; - case URGTAG_SSLCERT: - data->cert = (char *)param_obj; - break; - case URGTAG_SSLCERTPASSWD: - data->cert_passwd = (char *)param_obj; - break; - case URGTAG_CRLF: - data->crlf = (long)param_long; - break; - case URGTAG_QUOTE: - data->quote = (struct curl_slist *)param_obj; - break; - case URGTAG_DONE: /* done with the parsing, fall through */ - continue; - default: - /* unknown tag and its companion, just ignore: */ - break; - } tag = va_arg(arg, UrgTag); } -- cgit v1.2.1 From 96dde76b99897352aa3d0877a0b621a9e605733e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 22 May 2000 14:12:12 +0000 Subject: moved here from the newlib branch --- lib/url.c | 1005 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 483 insertions(+), 522 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 75dd89559..5938c5771 100644 --- a/lib/url.c +++ b/lib/url.c @@ -38,11 +38,6 @@ * ------------------------------------------------------------ ****************************************************************************/ -/* - * SSL code intially written by - * Linas Vepstas and Sampo Kellomaki - */ - /* -- WIN32 approved -- */ #include #include @@ -116,6 +111,8 @@ #include "getpass.h" #include "progress.h" #include "cookie.h" +#include "strequal.h" +#include "writeout.h" /* And now for the protocols */ #include "ftp.h" @@ -124,81 +121,28 @@ #include "http.h" #include "file.h" #include "ldap.h" -#include "writeout.h" + +#include #define _MPRINTF_REPLACE /* use our functions only */ #include /* -- -- */ -/*********************************************************************** - * Start with some silly functions to make win32-systems survive - ***********************************************************************/ -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -static void win32_cleanup(void) -{ - WSACleanup(); -} - -static UrgError win32_init(void) -{ - WORD wVersionRequested; - WSADATA wsaData; - int err; - wVersionRequested = MAKEWORD(1, 1); - - err = WSAStartup(wVersionRequested, &wsaData); - - if (err != 0) - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ - return URG_FAILED_INIT; - - /* Confirm that the Windows Sockets DLL supports 1.1.*/ - /* Note that if the DLL supports versions greater */ - /* than 1.1 in addition to 1.1, it will still return */ - /* 1.1 in wVersion since that is the version we */ - /* requested. */ - - if ( LOBYTE( wsaData.wVersion ) != 1 || - HIBYTE( wsaData.wVersion ) != 1 ) { - /* Tell the user that we couldn't find a useable */ - - /* winsock.dll. */ - WSACleanup(); - return URG_FAILED_INIT; - } - return URG_OK; -} -/* The Windows Sockets DLL is acceptable. Proceed. */ -#else -static UrgError win32_init(void) { return URG_OK; } -#define win32_cleanup() -#endif +CURLcode _urlget(struct UrlData *data); -/* - * This is the main global constructor for the lib. Call this before - * _any_ libcurl usage. If this fails, *NO* libcurl functions may be - * used, or havoc may be the result. - */ -UrgError curl_init(void) +/* does nothing, returns OK */ +CURLcode curl_init(void) { - return win32_init(); + return CURLE_OK; } -/* - * This is the main global destructor for the lib. Call this after - * _all_ libcurl usage is done. - */ +/* does nothing */ void curl_free(void) { - win32_cleanup(); } -static UrgError _urlget(struct UrlData *data); - - void urlfree(struct UrlData *data, bool totally) { #ifdef USE_SSLEAY @@ -278,27 +222,78 @@ void urlfree(struct UrlData *data, bool totally) } } -typedef struct UrlData CURL; +CURLcode curl_close(CURL *curl) +{ + struct UrlData *data=(struct UrlData *)curl; + + void *protocol = data->proto.generic; + + /* total session cleanup */ + urlfree(data, TRUE); + + if(protocol) + free(protocol); + + free(data); + + return CURLE_OK; +} -UrgError curl_open(CURL **curl, char *url) +CURLcode curl_open(CURL **curl, char *url) { /* We don't yet support specifying the URL at this point */ + struct UrlData *data; /* Very simple start-up: alloc the struct, init it with zeroes and return */ - CURL *data = (CURL *)malloc(sizeof(CURL)); + data = (struct UrlData *)malloc(sizeof(struct UrlData)); if(data) { - memset(data, 0, sizeof(CURL)); + memset(data, 0, sizeof(struct UrlData)); + data->handle = STRUCT_OPEN; + data->interface = CURLI_NORMAL; /* normal interface by default */ + + /* We do some initial setup here, all those fields that can't be just 0 */ + + data-> headerbuff=(char*)malloc(HEADERSIZE); + if(!data->headerbuff) { + free(data); /* free the memory again */ + return CURLE_OUT_OF_MEMORY; + } + + data-> headersize=HEADERSIZE; + +#if 0 + /* Let's set some default values: */ + curl_setopt(data, CURLOPT_FILE, stdout); /* default output to stdout */ + curl_setopt(data, CURLOPT_INFILE, stdin); /* default input from stdin */ + curl_setopt(data, CURLOPT_STDERR, stderr); /* default stderr to stderr! */ +#endif + + data->out = stdout; /* default output to stdout */ + data->in = stdin; /* default input from stdin */ + data->err = stderr; /* default stderr to stderr */ + + data->firstsocket = -1; /* no file descriptor */ + data->secondarysocket = -1; /* no file descriptor */ + + /* use fwrite as default function to store output */ + data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))fwrite; + + /* use fread as default function to read input */ + data->fread = (size_t (*)(char *, size_t, size_t, FILE *))fread; + + data->infilesize = -1; /* we don't know any size */ + + data->current_speed = -1; /* init to negative == impossible */ + *curl = data; - return URG_OK; + return CURLE_OK; } /* this is a very serious error */ - return URG_OUT_OF_MEMORY; + return CURLE_OUT_OF_MEMORY; } -typedef unsigned int CURLoption; - -UrgError curl_setopt(CURL *curl, CURLoption option, ...) +CURLcode curl_setopt(CURL *curl, CURLoption option, ...) { struct UrlData *data = curl; va_list param; @@ -307,310 +302,187 @@ UrgError curl_setopt(CURL *curl, CURLoption option, ...) va_start(param, option); switch(option) { - case URGTAG_TIMECONDITION: + case CURLOPT_VERBOSE: + data->bits.verbose = va_arg(param, long); + break; + case CURLOPT_HEADER: + data->bits.http_include_header = va_arg(param, long); + break; + case CURLOPT_NOPROGRESS: + data->bits.hide_progress = va_arg(param, long); + if(data->bits.hide_progress) + data->progress.flags |= PGRS_HIDE; + break; + case CURLOPT_NOBODY: + data->bits.no_body = va_arg(param, long); + break; + case CURLOPT_FAILONERROR: + data->bits.http_fail_on_error = va_arg(param, long); + break; + case CURLOPT_UPLOAD: + data->bits.upload = va_arg(param, long); + break; + case CURLOPT_POST: + data->bits.http_post = va_arg(param, long); + break; + case CURLOPT_FTPLISTONLY: + data->bits.ftp_list_only = va_arg(param, long); + break; + case CURLOPT_FTPAPPEND: + data->bits.ftp_append = va_arg(param, long); + break; + case CURLOPT_NETRC: + data->bits.use_netrc = va_arg(param, long); + break; + case CURLOPT_FOLLOWLOCATION: + data->bits.http_follow_location = va_arg(param, long); + break; + case CURLOPT_FTPASCII: + data->bits.ftp_ascii = va_arg(param, long); + break; + case CURLOPT_PUT: + data->bits.http_put = va_arg(param, long); + break; + case CURLOPT_MUTE: + data->bits.mute = va_arg(param, long); + break; + + case CURLOPT_TIMECONDITION: data->timecondition = va_arg(param, long); break; - case URGTAG_TIMEVALUE: + case CURLOPT_TIMEVALUE: data->timevalue = va_arg(param, long); break; - case URGTAG_SSLVERSION: + case CURLOPT_SSLVERSION: data->ssl_version = va_arg(param, long); break; - case URGTAG_COOKIEFILE: + case CURLOPT_COOKIEFILE: cookiefile = (char *)va_arg(param, void *); if(cookiefile) { data->cookies = cookie_init(cookiefile); } break; - case URGTAG_WRITEHEADER: + case CURLOPT_WRITEHEADER: data->writeheader = (FILE *)va_arg(param, FILE *); break; - case URGTAG_COOKIE: + case CURLOPT_COOKIE: data->cookie = va_arg(param, char *); break; - case URGTAG_ERRORBUFFER: + case CURLOPT_ERRORBUFFER: data->errorbuffer = va_arg(param, char *); break; - case URGTAG_FILE: + case CURLOPT_FILE: data->out = va_arg(param, FILE *); break; - case URGTAG_FTPPORT: + case CURLOPT_FTPPORT: data->ftpport = va_arg(param, char *); + data->bits.ftp_use_port = data->ftpport?1:0; break; - case URGTAG_HTTPHEADER: + case CURLOPT_HTTPHEADER: data->headers = va_arg(param, struct HttpHeader *); break; - case URGTAG_CUSTOMREQUEST: + case CURLOPT_CUSTOMREQUEST: data->customrequest = va_arg(param, char *); break; - case URGTAG_HTTPPOST: + case CURLOPT_HTTPPOST: data->httppost = va_arg(param, struct HttpPost *); + data->bits.http_formpost = data->httppost?1:0; break; - case URGTAG_INFILE: + case CURLOPT_INFILE: data->in = va_arg(param, FILE *); break; - case URGTAG_INFILESIZE: + case CURLOPT_INFILESIZE: data->infilesize = va_arg(param, long); break; - case URGTAG_LOW_SPEED_LIMIT: + case CURLOPT_LOW_SPEED_LIMIT: data->low_speed_limit=va_arg(param, long); break; - case URGTAG_LOW_SPEED_TIME: + case CURLOPT_LOW_SPEED_TIME: data->low_speed_time=va_arg(param, long); break; - case URGTAG_URL: + case CURLOPT_URL: data->url = va_arg(param, char *); break; - case URGTAG_PORT: + case CURLOPT_PORT: /* this typecast is used to fool the compiler to NOT warn for a "cast from pointer to integer of different size" */ data->port = (unsigned short)(va_arg(param, long)); break; - case URGTAG_POSTFIELDS: + case CURLOPT_POSTFIELDS: data->postfields = va_arg(param, char *); break; - case URGTAG_PROGRESSMODE: + case CURLOPT_PROGRESSMODE: data->progress.mode = va_arg(param, long); break; - case URGTAG_REFERER: + case CURLOPT_REFERER: data->referer = va_arg(param, char *); + data->bits.http_set_referer = (data->referer && *data->referer)?1:0; break; - case URGTAG_PROXY: + case CURLOPT_PROXY: data->proxy = va_arg(param, char *); + data->bits.httpproxy = data->proxy?1:0; break; - case URGTAG_FLAGS: - data->conf = va_arg(param, long); +#if 0 + case CURLOPT_FLAGS: + conf_to_internal(data, va_arg(param, long)); break; - case URGTAG_TIMEOUT: +#endif + case CURLOPT_TIMEOUT: data->timeout = va_arg(param, long); break; - case URGTAG_USERAGENT: + case CURLOPT_USERAGENT: data->useragent = va_arg(param, char *); break; - case URGTAG_USERPWD: + case CURLOPT_USERPWD: data->userpwd = va_arg(param, char *); + data->bits.user_passwd = data->userpwd?1:0; break; - case URGTAG_POSTQUOTE: + case CURLOPT_POSTQUOTE: data->postquote = va_arg(param, struct curl_slist *); break; - case URGTAG_PROXYUSERPWD: + case CURLOPT_PROXYUSERPWD: data->proxyuserpwd = va_arg(param, char *); + data->bits.proxy_user_passwd = data->proxyuserpwd?1:0; break; - case URGTAG_RANGE: + case CURLOPT_RANGE: data->range = va_arg(param, char *); + data->bits.set_range = data->range?1:0; break; - case URGTAG_RESUME_FROM: + case CURLOPT_RESUME_FROM: data->resume_from = va_arg(param, long); break; - case URGTAG_STDERR: + case CURLOPT_STDERR: data->err = va_arg(param, FILE *); break; - case URGTAG_WRITEFUNCTION: - data->fwrite = va_arg(param, void *); + case CURLOPT_WRITEFUNCTION: + data->fwrite = va_arg(param, write_callback); break; - case URGTAG_WRITEINFO: + case CURLOPT_WRITEINFO: data->writeinfo = va_arg(param, char *); break; - case URGTAG_READFUNCTION: - data->fread = va_arg(param, void *); + case CURLOPT_READFUNCTION: + data->fread = va_arg(param, read_callback); break; - case URGTAG_SSLCERT: + case CURLOPT_SSLCERT: data->cert = va_arg(param, char *); break; - case URGTAG_SSLCERTPASSWD: + case CURLOPT_SSLCERTPASSWD: data->cert_passwd = va_arg(param, char *); break; - case URGTAG_CRLF: + case CURLOPT_CRLF: data->crlf = va_arg(param, long); break; - case URGTAG_QUOTE: + case CURLOPT_QUOTE: data->quote = va_arg(param, struct curl_slist *); break; default: /* unknown tag and its companion, just ignore: */ - return URG_READ_ERROR; /* correct this */ - } - return URG_OK; -} - - -typedef int (*func_T)(void); - -UrgError curl_urlget(UrgTag tag, ...) -{ - va_list arg; - func_T param_func = (func_T)0; - long param_long = 0; - void *param_obj = NULL; - UrgError res; - - struct UrlData *data; - - /* this is for the lame win32 socket crap */ - if(curl_init()) - return URG_FAILED_INIT; - - /* We use curl_open() with undefined URL so far */ - res = curl_open(&data, NULL); - if(res == URG_OK) { - /* data is now filled with good-looking zeroes */ - - /* Let's set some default values: */ - curl_setopt(data, URGTAG_FILE, stdout); /* default output to stdout */ - curl_setopt(data, URGTAG_INFILE, stdin); /* default input from stdin */ - curl_setopt(data, URGTAG_STDERR, stderr); /* default stderr to stderr! */ - - data->firstsocket = -1; /* no file descriptor */ - data->secondarysocket = -1; /* no file descriptor */ - - /* use fwrite as default function to store output */ - data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))fwrite; - - /* use fread as default function to read input */ - data->fread = (size_t (*)(char *, size_t, size_t, FILE *))fread; - - data->infilesize = -1; /* we don't know any size */ - - data->current_speed = -1; /* init to negative == impossible */ - - va_start(arg, tag); - - while(tag != URGTAG_DONE) { - /* PORTING NOTE: - Ojbect pointers can't necessarily be casted to function pointers and - therefore we need to know what type it is and read the correct type - at once. This should also correct problems with different sizes of - the types. - */ - - if(tag < URGTYPE_OBJECTPOINT) { - /* This is a LONG type */ - param_long = va_arg(arg, long); - curl_setopt(data, tag, param_long); - } - else if(tag < URGTYPE_FUNCTIONPOINT) { - /* This is a object pointer type */ - param_obj = va_arg(arg, void *); - curl_setopt(data, tag, param_obj); - } - else { - param_func = va_arg(arg, func_T ); - curl_setopt(data, tag, param_func); - } - - /* printf("tag: %d\n", tag); */ - tag = va_arg(arg, UrgTag); - } - - va_end(arg); - - pgrsMode(data, data->progress.mode); - pgrsStartNow(data); - - data-> headerbuff=(char*)malloc(HEADERSIZE); - if(!data->headerbuff) - return URG_FAILED_INIT; - - data-> headersize=HEADERSIZE; - - res = _urlget(data); /* fetch the URL please */ - - while((res == URG_OK) && data->newurl) { - /* Location: redirect */ - char prot[16]; - char path[URL_MAX_LENGTH]; - - if(2 != sscanf(data->newurl, "%15[^:]://%" URL_MAX_LENGTH_TXT - "s", prot, path)) { - /*** - *DANG* this is an RFC 2068 violation. The URL is supposed - to be absolute and this doesn't seem to be that! - *** - Instead, we have to TRY to append this new path to the old URL - to the right of the host part. Oh crap, this is doomed to cause - problems in the future... - */ - char *protsep; - char *pathsep; - char *newest; - - /* protsep points to the start of the host name */ - protsep=strstr(data->url, "//"); - if(!protsep) - protsep=data->url; - else { - data->port=0; /* we got a full URL and then we should reset the - port number here to re-initiate it later */ - protsep+=2; /* pass the // */ - } - - if('/' != data->newurl[0]) { - /* First we need to find out if there's a ?-letter in the URL, and - cut it and the right-side of that off */ - pathsep = strrchr(protsep, '?'); - if(pathsep) - *pathsep=0; - - /* we have a relative path to append to the last slash if - there's one available */ - pathsep = strrchr(protsep, '/'); - if(pathsep) - *pathsep=0; - } - else { - /* We got a new absolute path for this server, cut off from the - first slash */ - pathsep = strchr(protsep, '/'); - if(pathsep) - *pathsep=0; - } - - newest=(char *)malloc( strlen(data->url) + - 1 + /* possible slash */ - strlen(data->newurl) + 1/* zero byte */); - - if(!newest) - return URG_OUT_OF_MEMORY; - sprintf(newest, "%s%s%s", data->url, ('/' == data->newurl[0])?"":"/", - data->newurl); - free(data->newurl); - data->newurl = newest; - } - else { - /* This was an absolute URL, clear the port number! */ - data->port = 0; - } - - data->url = data->newurl; - data->newurl = NULL; /* don't show! */ - - infof(data, "Follows Location: to new URL: '%s'\n", data->url); - - /* clean up the sockets and SSL stuff from the previous "round" */ - urlfree(data, FALSE); - - res = _urlget(data); - } - if(data->newurl) - free(data->newurl); - + return CURLE_READ_ERROR; /* correct this */ } - else - res = URG_FAILED_INIT; /* failed */ - - if((URG_OK == res) && data->writeinfo) { - /* Time to output some info to stdout */ - WriteOut(data); - } - - - /* total cleanup */ - urlfree(data, TRUE); - - return res; + return CURLE_OK; } @@ -618,8 +490,7 @@ UrgError curl_urlget(UrgTag tag, ...) * Read everything until a newline. */ -static int GetLine(int sockfd, char *buf, - struct UrlData *data) +int GetLine(int sockfd, char *buf, struct UrlData *data) { int nread; int read_rc=1; @@ -645,7 +516,7 @@ static int GetLine(int sockfd, char *buf, } *ptr=0; /* zero terminate */ - if(data->conf & CONF_VERBOSE) { + if(data->bits.verbose) { fputs("< ", data->err); fwrite(buf, 1, nread, data->err); fputs("\n", data->err); @@ -654,7 +525,6 @@ static int GetLine(int sockfd, char *buf, } - #ifndef WIN32 #ifndef RETSIGTYPE #define RETSIGTYPE void @@ -667,35 +537,114 @@ RETSIGTYPE alarmfunc(int signal) } #endif -/* ====================================================== */ +CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, + size_t *n) +{ + struct connectdata *conn = (struct connectdata *)c_conn; + struct UrlData *data; + size_t bytes_written; + + if(!n || !conn || (conn->handle != STRUCT_CONNECT)) + return CURLE_FAILED_INIT; + data = conn->data; + +#ifdef USE_SSLEAY + if (data->use_ssl) { + bytes_written = SSL_write(data->ssl, buf, amount); + } + else { +#endif + bytes_written = swrite(conn->writesockfd, buf, amount); +#ifdef USE_SSLEAY + } +#endif /* USE_SSLEAY */ + + *n = bytes_written; + return CURLE_OK; +} + +CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize, + size_t *n) +{ + struct connectdata *conn = (struct connectdata *)c_conn; + struct UrlData *data; + size_t nread; + + if(!n || !conn || (conn->handle != STRUCT_CONNECT)) + return CURLE_FAILED_INIT; + data = conn->data; + +#ifdef USE_SSLEAY + if (data->use_ssl) { + nread = SSL_read (data->ssl, buf, buffersize); + } + else { +#endif + nread = sread (conn->sockfd, buf, buffersize); +#ifdef USE_SSLEAY + } +#endif /* USE_SSLEAY */ + *n = nread; + return CURLE_OK; +} + +CURLcode curl_disconnect(CURLconnect *c_connect) +{ + struct connectdata *conn = c_connect; + + struct UrlData *data = conn->data; + + /* clean up the sockets and SSL stuff from the previous "round" */ + urlfree(data, FALSE); + + return CURLE_OK; +} + /* - * urlget - * (result put on stdout) + * NAME curl_connect() * - * ::= "://" [ ":" ] "/" + * DESCRIPTION * - * = "HTTP" | "HTTPS" | "GOPHER" | "FTP" + * Connects to the peer server and performs the initial setup. This function + * writes a connect handle to its second argument that is a unique handle for + * this connect. This allows multiple connects from the same handle returned + * by curl_open(). * - * When FTP: + * EXAMPLE * - * ::= [ ":" "@" ] + * CURLCode result; + * CURL curl; + * CURLconnect connect; + * result = curl_connect(curl, &connect); */ -static UrgError _urlget(struct UrlData *data) +CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) { - struct hostent *hp=NULL; - struct sockaddr_in serv_addr; + char *tmp; char *buf; - char proto[64]; - char gname[256]="default.com"; - char *name; - char path[URL_MAX_LENGTH]="/"; - char *ppath, *tmp; - long bytecount; - struct timeval now; - - UrgError result; + CURLcode result; char resumerange[12]=""; + struct UrlData *data = curl; + struct connectdata *conn; + + if(!data || (data->handle != STRUCT_OPEN)) + return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ + + if(!data->url) + return CURLE_URL_MALFORMAT; + + conn = (struct connectdata *)malloc(sizeof(struct connectdata)); + if(!conn) { + *in_connect = NULL; /* clear the pointer */ + return CURLE_OUT_OF_MEMORY; + } + *in_connect = conn; + + memset(conn, 0, sizeof(struct connectdata)); + conn->handle = STRUCT_CONNECT; + + conn->data = data; /* remember our daddy */ + conn->state = CONN_INIT; buf = data->buffer; /* this is our buffer */ @@ -709,59 +658,60 @@ static UrgError _urlget(struct UrlData *data) * to SSL connect through the proxy -- and we don't know if we * will need to use SSL until we parse the url ... */ - if((1 == sscanf(data->url, "file://%" URL_MAX_LENGTH_TXT "[^\n]", - path))) { + if((2 == sscanf(data->url, "%64[^:]://%" URL_MAX_LENGTH_TXT "[^\n]", + conn->proto, + conn->path)) && strequal(conn->proto, "file")) { /* we deal with file:/// differently since it supports no hostname other than "localhost" and "127.0.0.1", - which ist unique among the protocols specified in RFC 1738 */ - if (strstr(path, "localhost/") || strstr(path, "127.0.0.1/")) - strcpy(path, &path[10]); /* ... since coincidentally - both host strings are of - equal length */ - /* otherwise, / is quietly ommitted */ - - - /* that's it, no more fiddling with proxies, redirections, - or SSL for files, go directly to the file reading function */ - result = file(data, path, &bytecount); - if(result) - return result; - - return URG_OK; + which is unique among the protocols specified in RFC 1738 */ + if (strnequal(conn->path, "localhost/", 10) || + strnequal(conn->path, "127.0.0.1/", 10)) + /* ... since coincidentally both host strings are of equal length + otherwise, / is quietly ommitted */ + strcpy(conn->path, &conn->path[10]); + + strcpy(conn->proto, "file"); } - else if (2 > sscanf(data->url, "%64[^\n:]://%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", - proto, gname, path)) { - + else { + /* Set default host and default path */ + strcpy(conn->gname, "curl.haxx.nu"); + strcpy(conn->path, "/"); + + if (2 > sscanf(data->url, + "%64[^\n:]://%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", + conn->proto, conn->gname, conn->path)) { - /* badly formatted, let's try the browser-style _without_ 'http://' */ - if((1 > sscanf(data->url, "%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", gname, - path)) ) { - failf(data, " malformed"); - return URG_URL_MALFORMAT; - } - if(strnequal(gname, "FTP", 3)) { - strcpy(proto, "ftp"); - } - else if(strnequal(gname, "GOPHER", 6)) - strcpy(proto, "gopher"); + /* badly formatted, let's try the browser-style _without_ 'http://' */ + if((1 > sscanf(data->url, "%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", + conn->gname, conn->path)) ) { + failf(data, " malformed"); + return CURLE_URL_MALFORMAT; + } + if(strnequal(conn->gname, "FTP", 3)) { + strcpy(conn->proto, "ftp"); + } + else if(strnequal(conn->gname, "GOPHER", 6)) + strcpy(conn->proto, "gopher"); #ifdef USE_SSLEAY - else if(strnequal(gname, "HTTPS", 5)) - strcpy(proto, "https"); + else if(strnequal(conn->gname, "HTTPS", 5)) + strcpy(conn->proto, "https"); #endif /* USE_SSLEAY */ - else if(strnequal(gname, "TELNET", 6)) - strcpy(proto, "telnet"); - else if (strnequal(gname, "DICT", sizeof("DICT")-1)) - strcpy(proto, "DICT"); - else if (strnequal(gname, "LDAP", sizeof("LDAP")-1)) - strcpy(proto, "LDAP"); - else - strcpy(proto, "http"); - - data->conf |= CONF_NOPROT; + else if(strnequal(conn->gname, "TELNET", 6)) + strcpy(conn->proto, "telnet"); + else if (strnequal(conn->gname, "DICT", sizeof("DICT")-1)) + strcpy(conn->proto, "DICT"); + else if (strnequal(conn->gname, "LDAP", sizeof("LDAP")-1)) + strcpy(conn->proto, "LDAP"); + else { + strcpy(conn->proto, "http"); + } + + conn->protocol |= PROT_MISSING; /* not given in URL */ + } } - if((data->conf & CONF_USERPWD) && ! (data->conf & CONF_NETRC)) { + if(data->bits.user_passwd && !data->bits.use_netrc) { if(':' != *data->userpwd) { if((1 <= sscanf(data->userpwd, "%127[^:]:%127s", data->user, data->passwd))) { @@ -774,11 +724,11 @@ static UrgError _urlget(struct UrlData *data) } if(!data->user[0]) { failf(data, "USER malformat: user name can't be zero length"); - return URG_MALFORMAT_USER; + return CURLE_MALFORMAT_USER; } } - if(data->conf & CONF_PROXYUSERPWD) { + if(data->bits.proxy_user_passwd) { if(':' != *data->proxyuserpwd) { if((1 <= sscanf(data->proxyuserpwd, "%127[^:]:%127s", data->proxyuser, data->proxypasswd))) { @@ -791,16 +741,16 @@ static UrgError _urlget(struct UrlData *data) } if(!data->proxyuser[0]) { failf(data, " Proxy USER malformat: user name can't be zero length"); - return URG_MALFORMAT_USER; + return CURLE_MALFORMAT_USER; } } - name = gname; - ppath = path; - data->hostname = name; + conn->name = conn->gname; + conn->ppath = conn->path; + data->hostname = conn->name; - if(!(data->conf & CONF_PROXY)) { + if(!data->bits.httpproxy) { /* If proxy was not specified, we check for default proxy environment variables, to enable i.e Lynx compliance: @@ -824,9 +774,9 @@ static UrgError _urlget(struct UrlData *data) nope=no_proxy?strtok(no_proxy, ", "):NULL; while(nope) { - if(strlen(nope) <= strlen(name)) { + if(strlen(nope) <= strlen(conn->name)) { char *checkn= - name + strlen(name) - strlen(nope); + conn->name + strlen(conn->name) - strlen(nope); if(strnequal(nope, checkn, strlen(nope))) { /* no proxy for this host! */ break; @@ -836,7 +786,7 @@ static UrgError _urlget(struct UrlData *data) } if(!nope) { /* It was not listed as without proxy */ - char *protop = proto; + char *protop = conn->proto; char *envp = proxy_env; char *prox; @@ -861,29 +811,29 @@ static UrgError _urlget(struct UrlData *data) if(proxy && *proxy) { /* we have a proxy here to set */ data->proxy = proxy; - data->conf |= CONF_PROXY; + data->bits.httpproxy=1; } } /* if (!nope) - it wasn't specfied non-proxy */ } /* NO_PROXY wasn't specified or '*' */ } /* if not using proxy */ - if((data->conf & (CONF_PROXY|CONF_NOPROT)) == (CONF_PROXY|CONF_NOPROT) ) { + if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) { /* 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 = maprintf("%s://%s", proto, data->url); + reurl = maprintf("%s://%s", conn->proto, data->url); if(!reurl) - return URG_OUT_OF_MEMORY; + return CURLE_OUT_OF_MEMORY; data->url = reurl; if(data->freethis) free(data->freethis); data->freethis = reurl; - data->conf &= ~CONF_NOPROT; /* switch that one off again */ + conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } /* RESUME on a HTTP page is a tricky business. First, let's just check that @@ -894,11 +844,11 @@ static UrgError _urlget(struct UrlData *data) server, we just fail since we can't rewind the file writing from within this function. */ if(data->resume_from) { - if(!(data->conf & CONF_RANGE)) { + if(!data->bits.set_range) { /* if it already was in use, we just skip this */ sprintf(resumerange, "%d-", data->resume_from); data->range=resumerange; /* tell ourselves to fetch this range */ - data->conf |= CONF_RANGE; /* switch on range usage */ + data->bits.set_range = 1; /* switch on range usage */ } } @@ -916,50 +866,69 @@ static UrgError _urlget(struct UrlData *data) * works differently, depending on whether its SSL or not). */ - if (strequal(proto, "HTTP")) { + if (strequal(conn->proto, "HTTP")) { if(!data->port) data->port = PORT_HTTP; data->remote_port = PORT_HTTP; - data->conf |= CONF_HTTP; + conn->protocol |= PROT_HTTP; + conn->curl_do = http; + conn->curl_done = http_done; } - else if (strequal(proto, "HTTPS")) { + else if (strequal(conn->proto, "HTTPS")) { #ifdef USE_SSLEAY if(!data->port) data->port = PORT_HTTPS; data->remote_port = PORT_HTTPS; - data->conf |= CONF_HTTP; - data->conf |= CONF_HTTPS; + conn->protocol |= PROT_HTTP; + conn->protocol |= PROT_HTTPS; + + conn->curl_do = http; + conn->curl_done = http_done; + conn->curl_connect = http_connect; + #else /* USE_SSLEAY */ failf(data, "SSL is disabled, https: not supported!"); - return URG_UNSUPPORTED_PROTOCOL; + return CURLE_UNSUPPORTED_PROTOCOL; #endif /* !USE_SSLEAY */ } - else if (strequal(proto, "GOPHER")) { + else if (strequal(conn->proto, "GOPHER")) { if(!data->port) data->port = PORT_GOPHER; data->remote_port = PORT_GOPHER; /* Skip // in path if present */ - if (isdigit((int)path[1])) { - ppath = strchr(&path[1], '/'); - if (ppath == NULL) - ppath = path; + if (isdigit((int)conn->path[1])) { + conn->ppath = strchr(&conn->path[1], '/'); + if (conn->ppath == NULL) + conn->ppath = conn->path; } - data->conf |= CONF_GOPHER; + conn->protocol |= PROT_GOPHER; + conn->curl_do = http; + conn->curl_done = http_done; } - else if(strequal(proto, "FTP")) { + else if(strequal(conn->proto, "FTP")) { char *type; if(!data->port) data->port = PORT_FTP; data->remote_port = PORT_FTP; - data->conf |= CONF_FTP; + conn->protocol |= PROT_FTP; - ppath++; /* don't include the initial slash */ + if(data->bits.httpproxy) { + conn->curl_do = http; + conn->curl_done = http_done; + } + else { + conn->curl_do = ftp; + conn->curl_done = ftp_done; + conn->curl_connect = ftp_connect; + } + + conn->ppath++; /* don't include the initial slash */ /* FTP URLs support an extension like ";type=" that we'll try to get now! */ - type=strstr(ppath, ";type="); + type=strstr(conn->ppath, ";type="); if(!type) { - type=strstr(gname, ";type="); + type=strstr(conn->gname, ";type="); } if(type) { char command; @@ -967,54 +936,59 @@ static UrgError _urlget(struct UrlData *data) command = toupper(type[6]); switch(command) { case 'A': /* ASCII mode */ - data->conf |= CONF_FTPASCII; + data->bits.ftp_ascii = 1; break; case 'D': /* directory mode */ - data->conf |= CONF_FTPLISTONLY; + data->bits.ftp_list_only = 1; break; case 'I': /* binary mode */ default: /* switch off ASCII */ - data->conf &= ~CONF_FTPASCII; + data->bits.ftp_ascii = 0; break; } } } - else if(strequal(proto, "TELNET")) { + else if(strequal(conn->proto, "TELNET")) { /* telnet testing factory */ - data->conf |= CONF_TELNET; + conn->protocol |= PROT_TELNET; if(!data->port) data->port = PORT_TELNET; data->remote_port = PORT_TELNET; + + conn->curl_do = telnet; + conn->curl_done = telnet_done; + } - else if (strequal(proto, "DICT")) { - data->conf |= CONF_DICT; + else if (strequal(conn->proto, "DICT")) { + conn->protocol |= PROT_DICT; if(!data->port) data->port = PORT_DICT; data->remote_port = PORT_DICT; + conn->curl_do = dict; + conn->curl_done = dict_done; } - else if (strequal(proto, "LDAP")) { - data->conf |= CONF_LDAP; + else if (strequal(conn->proto, "LDAP")) { + conn->protocol |= PROT_LDAP; if(!data->port) data->port = PORT_LDAP; data->remote_port = PORT_LDAP; + conn->curl_do = ldap; + conn->curl_done = ldap_done; } - /* file:// is handled above */ - /* else if (strequal(proto, "FILE")) { - data->conf |= CONF_FILE; + else if (strequal(conn->proto, "FILE")) { + conn->protocol |= PROT_FILE; - result = file(data, path, &bytecount); - if(result) - return result; + conn->curl_do = file; + /* no done() function */ + } - return URG_OK; - }*/ else { - failf(data, "Unsupported protocol: %s", proto); - return URG_UNSUPPORTED_PROTOCOL; + failf(data, "Unsupported protocol: %s", conn->proto); + return CURLE_UNSUPPORTED_PROTOCOL; } - if(data->conf & CONF_NETRC) { + if(data->bits.use_netrc) { if(ParseNetrc(data->hostname, data->user, data->passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", data->hostname); @@ -1025,25 +999,26 @@ static UrgError _urlget(struct UrlData *data) strcpy(data->user, CURL_DEFAULT_USER); if(!data->passwd[0]) strcpy(data->passwd, CURL_DEFAULT_PASSWORD); - if(data->conf & CONF_HTTP) { - data->conf |= CONF_USERPWD; + if(conn->protocol&PROT_HTTP) { + data->bits.user_passwd = 1; /* enable user+password */ } } - else if(!(data->conf & CONF_USERPWD) && - (data->conf & (CONF_FTP|CONF_HTTP)) ) { + else if(!(data->bits.user_passwd) && + (conn->protocol & (PROT_FTP|PROT_HTTP)) ) { /* This is a FTP or HTTP URL, and we haven't got the user+password in the extra parameter, 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=NULL; /* assign to remove possible warnings */ - if(':' == *name) { + if(':' == *conn->name) { failf(data, "URL malformat: user can't be zero length"); - return URG_URL_MALFORMAT_USER; + return CURLE_URL_MALFORMAT_USER; } - if((1 <= sscanf(name, "%127[^:]:%127[^@]", - data->user, data->passwd)) && (ptr=strchr(name, '@'))) { - name = ++ptr; - data->conf |= CONF_USERPWD; + if((1 <= sscanf(conn->name, "%127[^:]:%127[^@]", + data->user, data->passwd)) && + (ptr=strchr(conn->name, '@'))) { + conn->name = ++ptr; + data->bits.user_passwd=1; /* enable user+password */ } else { strcpy(data->user, CURL_DEFAULT_USER); @@ -1051,19 +1026,19 @@ static UrgError _urlget(struct UrlData *data) } } - if(!(data->conf & CONF_PROXY)) { + if(!data->bits.httpproxy) { /* 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. */ - tmp = strchr(name, ':'); + tmp = strchr(conn->name, ':'); if (tmp) { *tmp++ = '\0'; data->port = atoi(tmp); } /* Connect to target host right on */ - if(!(hp = GetHost(data, name))) { - failf(data, "Couldn't resolv host '%s'", name); - return URG_COULDNT_RESOLVE_HOST; + if(!(conn->hp = GetHost(data, conn->name))) { + failf(data, "Couldn't resolv host '%s'", conn->name); + return CURLE_COULDNT_RESOLVE_HOST; } } else { @@ -1079,12 +1054,12 @@ static UrgError _urlget(struct UrlData *data) if(NULL == proxydup) { failf(data, "memory shortage"); - return URG_OUT_OF_MEMORY; + return CURLE_OUT_OF_MEMORY; } /* we use proxy all right, but we wanna know the remote port for SSL reasons */ - tmp = strchr(name, ':'); + tmp = strchr(conn->name, ':'); if (tmp) { *tmp++ = '\0'; /* cut off the name there */ data->remote_port = atoi(tmp); @@ -1111,9 +1086,9 @@ static UrgError _urlget(struct UrlData *data) } /* connect to proxy */ - if(!(hp = GetHost(data, proxyptr))) { + if(!(conn->hp = GetHost(data, proxyptr))) { failf(data, "Couldn't resolv proxy '%s'", proxyptr); - return URG_COULDNT_RESOLVE_PROXY; + return CURLE_COULDNT_RESOLVE_PROXY; } free(proxydup); /* free the duplicate pointer and not the modified */ @@ -1122,14 +1097,16 @@ static UrgError _urlget(struct UrlData *data) data->firstsocket = socket(AF_INET, SOCK_STREAM, 0); - memset((char *) &serv_addr, '\0', sizeof(serv_addr)); - memcpy((char *)&(serv_addr.sin_addr), hp->h_addr, hp->h_length); - serv_addr.sin_family = hp->h_addrtype; - - serv_addr.sin_port = htons(data->port); + memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); + memcpy((char *)&(conn->serv_addr.sin_addr), + conn->hp->h_addr, conn->hp->h_length); + conn->serv_addr.sin_family = conn->hp->h_addrtype; + conn->serv_addr.sin_port = htons(data->port); - if (connect(data->firstsocket, (struct sockaddr *) &serv_addr, - sizeof(serv_addr)) < 0) { + if (connect(data->firstsocket, + (struct sockaddr *) &(conn->serv_addr), + sizeof(conn->serv_addr) + ) < 0) { switch(errno) { #ifdef ECONNREFUSED /* this should be made nicer */ @@ -1146,10 +1123,10 @@ static UrgError _urlget(struct UrlData *data) failf(data, "Can't connect to server: %d", errno); break; } - return URG_COULDNT_CONNECT; + return CURLE_COULDNT_CONNECT; } - if(data->conf & CONF_PROXYUSERPWD) { + if(data->bits.proxy_user_passwd) { char authorization[512]; sprintf(data->buffer, "%s:%s", data->proxyuser, data->proxypasswd); base64Encode(data->buffer, authorization); @@ -1157,74 +1134,27 @@ static UrgError _urlget(struct UrlData *data) data->ptr_proxyuserpwd = maprintf("Proxy-authorization: Basic %s\015\012", authorization); } - if(data->conf & (CONF_HTTPS|CONF_HTTP|CONF_PROXY)) { + if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) { if(data->useragent) { data->ptr_uagent = maprintf("User-Agent: %s\015\012", data->useragent); } } - - /* If we are not using a proxy and we want a secure connection, - * perform SSL initialization & connection now. - * If using a proxy with https, then we must tell the proxy to CONNECT - * us to the host we want to talk to. Only after the connect - * has occured, can we start talking SSL - */ - if (data->conf & CONF_HTTPS) { - if (data->conf & CONF_PROXY) { - - /* OK, now send the connect statment */ - sendf(data->firstsocket, data, - "CONNECT %s:%d HTTP/1.0\015\012" - "%s" - "%s" - "\r\n", - data->hostname, data->remote_port, - (data->conf&CONF_PROXYUSERPWD)?data->ptr_proxyuserpwd:"", - (data->useragent?data->ptr_uagent:"") - ); - - /* wait for the proxy to send us a HTTP/1.0 200 OK header */ - /* Daniel rewrote this part Nov 5 1998 to make it more obvious */ - { - int httperror=0; - int subversion=0; - while(GetLine(data->firstsocket, data->buffer, data)) { - if('\r' == data->buffer[0]) - break; /* end of headers */ - if(2 == sscanf(data->buffer, "HTTP/1.%d %d", - &subversion, - &httperror)) { - ; - } - } - if(200 != httperror) { - if(407 == httperror) - /* Added Nov 6 1998 */ - failf(data, "Proxy requires authorization!"); - else - failf(data, "Received error code %d from proxy", httperror); - return URG_READ_ERROR; - } - } - infof (data, "Proxy has replied to CONNECT request\n"); - } - - /* now, perform the SSL initialization for this socket */ - if(UrgSSLConnect (data)) { - return URG_SSL_CONNECT_ERROR; - } + if(conn->curl_connect) { + /* is there a post-connect() procedure? */ + result = conn->curl_connect(conn); } + pgrsTime(data, TIMER_CONNECT); - now = tvnow(); /* time this *after* the connect is done */ - bytecount = 0; + conn->now = tvnow(); /* time this *after* the connect is done */ + conn->bytecount = 0; /* Figure out the ip-number and the first host name it shows: */ { struct in_addr in; - (void) memcpy(&in.s_addr, *hp->h_addr_list, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s)\n", hp->h_name, inet_ntoa(in)); + (void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr)); + infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in)); } #if 0 /* Kerberos experiements! Beware! Take cover! */ @@ -1243,36 +1173,67 @@ static UrgError _urlget(struct UrlData *data) } #endif - if((data->conf&(CONF_FTP|CONF_PROXY)) == CONF_FTP) { - result = ftp(data, &bytecount, data->user, data->passwd, ppath); - if(result) - return result; + return CURLE_OK; +} + +CURLcode curl_done(CURLconnect *c_connect) +{ + struct connectdata *conn = c_connect; + struct UrlData *data; + CURLcode result; + + if(!conn || (conn->handle!= STRUCT_CONNECT)) { + return CURLE_BAD_FUNCTION_ARGUMENT; } - else if(data->conf & CONF_TELNET) { - result=telnet(data); - if(result) - return result; + if(conn->state != CONN_DO) { + /* This can only be called after a curl_do() */ + return CURLE_BAD_CALLING_ORDER; } - else if (data->conf & CONF_LDAP) { - result = ldap(data, path, &bytecount); - if (result) - return result; + data = conn->data; + + /* this calls the protocol-specific function pointer previously set */ + if(conn->curl_done) + result = conn->curl_done(conn); + else + result = CURLE_OK; + + pgrsDone(data); /* done with the operation */ + + conn->state = CONN_DONE; + + return result; +} + +CURLcode curl_do(CURLconnect *in_conn) +{ + struct connectdata *conn = in_conn; + CURLcode result; + + if(!conn || (conn->handle!= STRUCT_CONNECT)) { + return CURLE_BAD_FUNCTION_ARGUMENT; } - else if (data->conf & CONF_DICT) { - result = dict(data, path, &bytecount); - if(result) - return result; + if(conn->state != CONN_INIT) { + return CURLE_BAD_CALLING_ORDER; } - else { - result = http(data, ppath, name, &bytecount); - if(result) + + if(conn->curl_do) { + /* generic protocol-specific function pointer set in curl_connect() */ + result = conn->curl_do(conn); + if(result) { + conn->state = CONN_ERROR; return result; + } } - if(bytecount) { - double ittook = tvdiff (tvnow(), now); + + conn->state = CONN_DO; /* we have entered this state */ + +#if 0 + if(conn->bytecount) { + double ittook = tvdiff (tvnow(), conn->now); infof(data, "%i bytes transfered in %.3lf seconds (%.0lf bytes/sec).\n", - bytecount, ittook, (double)bytecount/(ittook!=0.0?ittook:1)); + conn->bytecount, ittook, (double)conn->bytecount/(ittook!=0.0?ittook:1)); } - return URG_OK; +#endif + return CURLE_OK; } -- cgit v1.2.1 From c35238e0a3351db3ed20c5a218d42fe18630ffd4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 22 May 2000 17:18:55 +0000 Subject: =?UTF-8?q?J=F6rt=20Hartroth's=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5938c5771..6594afbe6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -249,7 +249,7 @@ CURLcode curl_open(CURL **curl, char *url) if(data) { memset(data, 0, sizeof(struct UrlData)); data->handle = STRUCT_OPEN; - data->interface = CURLI_NORMAL; /* normal interface by default */ + data->interf = CURLI_NORMAL; /* normal interface by default */ /* We do some initial setup here, all those fields that can't be just 0 */ -- cgit v1.2.1 From a0ce95e155de68bd5a088a7a539f45aa7134b00b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 May 2000 22:51:13 +0000 Subject: David LeBlanc's fixes! --- lib/url.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6594afbe6..5dd33a59d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -303,48 +303,48 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) switch(option) { case CURLOPT_VERBOSE: - data->bits.verbose = va_arg(param, long); + data->bits.verbose = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_HEADER: - data->bits.http_include_header = va_arg(param, long); + data->bits.http_include_header = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_NOPROGRESS: - data->bits.hide_progress = va_arg(param, long); + data->bits.hide_progress = va_arg(param, long)?TRUE:FALSE; if(data->bits.hide_progress) data->progress.flags |= PGRS_HIDE; break; case CURLOPT_NOBODY: - data->bits.no_body = va_arg(param, long); + data->bits.no_body = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_FAILONERROR: - data->bits.http_fail_on_error = va_arg(param, long); + data->bits.http_fail_on_error = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_UPLOAD: - data->bits.upload = va_arg(param, long); + data->bits.upload = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_POST: - data->bits.http_post = va_arg(param, long); + data->bits.http_post = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_FTPLISTONLY: - data->bits.ftp_list_only = va_arg(param, long); + data->bits.ftp_list_only = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_FTPAPPEND: - data->bits.ftp_append = va_arg(param, long); + data->bits.ftp_append = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_NETRC: - data->bits.use_netrc = va_arg(param, long); + data->bits.use_netrc = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_FOLLOWLOCATION: - data->bits.http_follow_location = va_arg(param, long); + data->bits.http_follow_location = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_FTPASCII: - data->bits.ftp_ascii = va_arg(param, long); + data->bits.ftp_ascii = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_PUT: - data->bits.http_put = va_arg(param, long); + data->bits.http_put = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_MUTE: - data->bits.mute = va_arg(param, long); + data->bits.mute = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_TIMECONDITION: @@ -627,6 +627,10 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) struct UrlData *data = curl; struct connectdata *conn; + /* I believe the longest possible name in a DNS is set to 255 letters, FQDN + so this should be safe: */ + char hostent_buf[512]; + if(!data || (data->handle != STRUCT_OPEN)) return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ @@ -1036,7 +1040,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } /* Connect to target host right on */ - if(!(conn->hp = GetHost(data, conn->name))) { + if(!(conn->hp = GetHost(data, conn->name, hostent_buf, sizeof(hostent_buf)))) { failf(data, "Couldn't resolv host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; } @@ -1086,7 +1090,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } /* connect to proxy */ - if(!(conn->hp = GetHost(data, proxyptr))) { + if(!(conn->hp = GetHost(data, proxyptr, hostent_buf, sizeof(hostent_buf)))) { failf(data, "Couldn't resolv proxy '%s'", proxyptr); return CURLE_COULDNT_RESOLVE_PROXY; } -- cgit v1.2.1 From 6d522c9c1dae070f73aae1022b09b68f9153959e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 May 2000 23:07:22 +0000 Subject: made getenv() more threadsafe for win32 --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5dd33a59d..8c48d0512 100644 --- a/lib/url.c +++ b/lib/url.c @@ -172,6 +172,12 @@ void urlfree(struct UrlData *data, bool totally) data->firstsocket=-1; } + if(data->bits.proxystringalloc) { + data->bits.proxystringalloc=0; + free(data->proxy); + data->proxy=NULL; + } + if(data->ptr_proxyuserpwd) { free(data->ptr_proxyuserpwd); @@ -815,10 +821,13 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) 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; } } /* if (!nope) - it wasn't specfied non-proxy */ } /* NO_PROXY wasn't specified or '*' */ + if(no_proxy) + free(no_proxy); } /* if not using proxy */ if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) { -- cgit v1.2.1 From 4fd4a6888a468a7c35ef0f7ce804ac9e1518d62d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 8 Jun 2000 15:11:39 +0000 Subject: added progress callback stuff, changed the callback typedefs to be public --- lib/url.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8c48d0512..ac97e23d3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -96,7 +96,6 @@ #endif #include "urldata.h" -#include #include "netrc.h" #include "formdata.h" @@ -388,7 +387,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->bits.ftp_use_port = data->ftpport?1:0; break; case CURLOPT_HTTPHEADER: - data->headers = va_arg(param, struct HttpHeader *); + data->headers = va_arg(param, struct curl_slist *); break; case CURLOPT_CUSTOMREQUEST: data->customrequest = va_arg(param, char *); @@ -449,6 +448,12 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_POSTQUOTE: data->postquote = va_arg(param, struct curl_slist *); break; + case CURLOPT_PROGRESSFUNCTION: + data->fprogress = va_arg(param, curl_progress_callback); + break; + case CURLOPT_PROGRESSDATA: + data->progress_client = va_arg(param, void *); + break; case CURLOPT_PROXYUSERPWD: data->proxyuserpwd = va_arg(param, char *); data->bits.proxy_user_passwd = data->proxyuserpwd?1:0; @@ -464,13 +469,13 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->err = va_arg(param, FILE *); break; case CURLOPT_WRITEFUNCTION: - data->fwrite = va_arg(param, write_callback); + data->fwrite = va_arg(param, curl_write_callback); break; case CURLOPT_WRITEINFO: data->writeinfo = va_arg(param, char *); break; case CURLOPT_READFUNCTION: - data->fread = va_arg(param, read_callback); + data->fread = va_arg(param, curl_read_callback); break; case CURLOPT_SSLCERT: data->cert = va_arg(param, char *); -- cgit v1.2.1 From 2488fff451863db7b18d7a4adf412536c1d864c6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Jun 2000 08:11:45 +0000 Subject: free-twice problem corrected --- lib/url.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ac97e23d3..9b844eda8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -233,14 +233,12 @@ CURLcode curl_close(CURL *curl) void *protocol = data->proto.generic; - /* total session cleanup */ + /* total session cleanup (frees 'data' as well!)*/ urlfree(data, TRUE); if(protocol) free(protocol); - free(data); - return CURLE_OK; } -- cgit v1.2.1 From fb9c5650ceffad60e9e396ee4798d2467139efd4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 16 Jun 2000 13:17:07 +0000 Subject: progress.mode replaced with progress.callback --- lib/url.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9b844eda8..6da761b22 100644 --- a/lib/url.c +++ b/lib/url.c @@ -417,9 +417,6 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_POSTFIELDS: data->postfields = va_arg(param, char *); break; - case CURLOPT_PROGRESSMODE: - data->progress.mode = va_arg(param, long); - break; case CURLOPT_REFERER: data->referer = va_arg(param, char *); data->bits.http_set_referer = (data->referer && *data->referer)?1:0; @@ -448,6 +445,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_PROGRESSFUNCTION: data->fprogress = va_arg(param, curl_progress_callback); + data->progress.callback = TRUE; /* no longer internal */ break; case CURLOPT_PROGRESSDATA: data->progress_client = va_arg(param, void *); -- cgit v1.2.1 From f30ffef477636dc10a72eb30590a84a0218e5935 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Jun 2000 09:28:09 +0000 Subject: autoreferer added, switches off POST on location: following --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6da761b22..62e81d243 100644 --- a/lib/url.c +++ b/lib/url.c @@ -218,6 +218,9 @@ void urlfree(struct UrlData *data, bool totally) if(data->headerbuff) free(data->headerbuff); + if(data->free_referer) + free(data->referer); + cookie_cleanup(data->cookies); free(data); @@ -421,6 +424,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->referer = va_arg(param, char *); data->bits.http_set_referer = (data->referer && *data->referer)?1:0; break; + case CURLOPT_AUTOREFERER: + data->bits.http_auto_referer = va_arg(param, long)?1:0; + break; case CURLOPT_PROXY: data->proxy = va_arg(param, char *); data->bits.httpproxy = data->proxy?1:0; -- cgit v1.2.1 From 1ef3600a0731fef8f59563a1e49981f1b64b9746 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Jun 2000 15:31:26 +0000 Subject: haxx.nu => haxx.se --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 62e81d243..4af97468f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -24,9 +24,9 @@ * * ------------------------------------------------------------ * Main author: - * - Daniel Stenberg + * - Daniel Stenberg * - * http://curl.haxx.nu + * http://curl.haxx.se * * $Source$ * $Revision$ @@ -691,7 +691,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } else { /* Set default host and default path */ - strcpy(conn->gname, "curl.haxx.nu"); + strcpy(conn->gname, "curl.haxx.se"); strcpy(conn->path, "/"); if (2 > sscanf(data->url, -- cgit v1.2.1 From bb3fa8855c80bec0c6c72abf2772c0188dfe86d1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Jul 2000 07:31:35 +0000 Subject: Added CURLOPT_PROXYPORT support Added a missing free() in curl_disconnect() Made (https) connect errors abort better and earlier --- lib/url.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4af97468f..5194da011 100644 --- a/lib/url.c +++ b/lib/url.c @@ -431,11 +431,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->proxy = va_arg(param, char *); data->bits.httpproxy = data->proxy?1:0; break; -#if 0 - case CURLOPT_FLAGS: - conf_to_internal(data, va_arg(param, long)); + case CURLOPT_PROXYPORT: + data->proxyport = va_arg(param, long); break; -#endif case CURLOPT_TIMEOUT: data->timeout = va_arg(param, long); break; @@ -607,6 +605,8 @@ CURLcode curl_disconnect(CURLconnect *c_connect) struct UrlData *data = conn->data; + free(conn); /* free the connection oriented data */ + /* clean up the sockets and SSL stuff from the previous "round" */ urlfree(data, FALSE); @@ -1104,6 +1104,11 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) /* now set the local port number */ data->port = atoi(prox_portno); } + else if(data->proxyport) { + /* None given in the proxy string, then get the default one if it is + given */ + data->port = data->proxyport; + } /* connect to proxy */ if(!(conn->hp = GetHost(data, proxyptr, hostent_buf, sizeof(hostent_buf)))) { @@ -1163,6 +1168,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(conn->curl_connect) { /* is there a post-connect() procedure? */ result = conn->curl_connect(conn); + if(result != CURLE_OK) + return result; /* pass back errors */ } pgrsTime(data, TIMER_CONNECT); -- cgit v1.2.1 From 0cb4814105de3a2da408db23bbc98c3634dca320 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Jul 2000 12:13:57 +0000 Subject: tiny adjustments to set the start-time before the curl_connect() is called to allow the connect function to better deal with timeouts, as was just added to ftp --- lib/url.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5194da011..a8fe1ec77 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1166,13 +1166,16 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } if(conn->curl_connect) { - /* is there a post-connect() procedure? */ + /* is there a connect() procedure? */ + conn->now = tvnow(); /* set this here for timeout purposes in the + connect procedure, it is later set again for the + progress meter purpose */ result = conn->curl_connect(conn); if(result != CURLE_OK) return result; /* pass back errors */ } - pgrsTime(data, TIMER_CONNECT); + pgrsTime(data, TIMER_CONNECT); /* we're connected */ conn->now = tvnow(); /* time this *after* the connect is done */ conn->bytecount = 0; -- cgit v1.2.1 From 293cae68bf7f07bdb53b59b3d3f9f1edec4a91de Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Jul 2000 21:17:45 +0000 Subject: uses the new curl_close function to clean up the http-specific auth_host --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a8fe1ec77..d253fe566 100644 --- a/lib/url.c +++ b/lib/url.c @@ -893,6 +893,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->protocol |= PROT_HTTP; conn->curl_do = http; conn->curl_done = http_done; + conn->curl_close = http_close; } else if (strequal(conn->proto, "HTTPS")) { #ifdef USE_SSLEAY @@ -905,6 +906,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->curl_do = http; conn->curl_done = http_done; conn->curl_connect = http_connect; + conn->curl_close = http_close; #else /* USE_SSLEAY */ failf(data, "SSL is disabled, https: not supported!"); @@ -924,6 +926,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->protocol |= PROT_GOPHER; conn->curl_do = http; conn->curl_done = http_done; + conn->curl_close = http_close; } else if(strequal(conn->proto, "FTP")) { char *type; @@ -935,6 +938,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(data->bits.httpproxy) { conn->curl_do = http; conn->curl_done = http_done; + conn->curl_close = http_close; } else { conn->curl_do = ftp; -- cgit v1.2.1 From 215c75135b687461ed1a5f4f0e9ef0fba1af0d46 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 28 Jul 2000 07:56:06 +0000 Subject: clear the httproxy bit on cleanup if the allocproxy bit was set --- lib/url.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d253fe566..3930da5e2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -172,11 +172,15 @@ void urlfree(struct UrlData *data, bool totally) } if(data->bits.proxystringalloc) { - data->bits.proxystringalloc=0; + data->bits.proxystringalloc=FALSE;; free(data->proxy); data->proxy=NULL; + + /* 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; } - if(data->ptr_proxyuserpwd) { free(data->ptr_proxyuserpwd); -- cgit v1.2.1 From a79b541bd219bf97bfcd56045dfe3cdc0b8e0b67 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Jul 2000 21:31:27 +0000 Subject: made urlfree static, added (void) in front of one of the SSL calls. I did these changes when trying to run lclint on the curl code. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3930da5e2..b8e62838e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -142,12 +142,12 @@ void curl_free(void) { } -void urlfree(struct UrlData *data, bool totally) +void static urlfree(struct UrlData *data, bool totally) { #ifdef USE_SSLEAY if (data->use_ssl) { if(data->ssl) { - SSL_shutdown(data->ssl); + (void)SSL_shutdown(data->ssl); SSL_set_connect_state(data->ssl); SSL_free (data->ssl); -- cgit v1.2.1 From 8fd44dd6486a834a11625fe87ff1010035d7a424 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 8 Aug 2000 13:46:26 +0000 Subject: allow zero length user names for http --- lib/url.c | 78 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 27 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b8e62838e..561ab8202 100644 --- a/lib/url.c +++ b/lib/url.c @@ -733,37 +733,42 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(data->bits.user_passwd && !data->bits.use_netrc) { - if(':' != *data->userpwd) { - if((1 <= sscanf(data->userpwd, "%127[^:]:%127s", - data->user, data->passwd))) { - /* check for password, if no ask for one */ - if( !data->passwd[0] ) - { - strncpy(data->passwd, getpass("password: "), sizeof(data->passwd)); - } + data->user[0] =0; + data->passwd[0]=0; + + if(*data->userpwd != ':') { + /* the name is given, get user+password */ + sscanf(data->userpwd, "%127[^:]:%127[^@]", + data->user, data->passwd); } - } - if(!data->user[0]) { - failf(data, "USER malformat: user name can't be zero length"); - return CURLE_MALFORMAT_USER; + else + /* no name given, get the password only */ + sscanf(data->userpwd+1, "%127[^@]", data->passwd); + + /* check for password, if no ask for one */ + if( !data->passwd[0] ) { + strncpy(data->passwd, getpass("password: "), sizeof(data->passwd)); } } if(data->bits.proxy_user_passwd) { - if(':' != *data->proxyuserpwd) { - if((1 <= sscanf(data->proxyuserpwd, "%127[^:]:%127s", - data->proxyuser, data->proxypasswd))) { - /* check for password, if no ask for one */ - if( !data->proxypasswd[0] ) - { - strncpy(data->proxypasswd, getpass("proxy password: "), sizeof(data->proxypasswd)); - } + data->proxyuser[0] =0; + data->proxypasswd[0]=0; + + if(*data->proxyuserpwd != ':') { + /* the name is given, get user+password */ + sscanf(data->proxyuserpwd, "%127[^:]:%127[^@]", + data->proxyuser, data->proxypasswd); } + else + /* no name given, get the password only */ + sscanf(data->proxyuserpwd+1, "%127[^@]", data->proxypasswd); + + /* check for password, if no ask for one */ + if( !data->proxypasswd[0] ) { + strncpy(data->proxypasswd, getpass("proxy password: "), sizeof(data->proxypasswd)); } - if(!data->proxyuser[0]) { - failf(data, " Proxy USER malformat: user name can't be zero length"); - return CURLE_MALFORMAT_USER; - } + } conn->name = conn->gname; @@ -1038,13 +1043,32 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) user+password pair in a string like: ftp://user:password@ftp.my.site:8021/README */ char *ptr=NULL; /* assign to remove possible warnings */ +#if 0 if(':' == *conn->name) { failf(data, "URL malformat: user can't be zero length"); return CURLE_URL_MALFORMAT_USER; } - if((1 <= sscanf(conn->name, "%127[^:]:%127[^@]", - data->user, data->passwd)) && - (ptr=strchr(conn->name, '@'))) { +#endif + 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; + + if(*conn->name != ':') { + /* the name is given, get user+password */ + sscanf(conn->name, "%127[^:]:%127[^@]", + data->user, data->passwd); + } + else + /* no name given, get the password only */ + sscanf(conn->name+1, "%127[^@]", data->passwd); + + /* check for password, if no ask for one */ + if( !data->passwd[0] ) { + strncpy(data->passwd, getpass("password: "), sizeof(data->passwd)); + } + conn->name = ++ptr; data->bits.user_passwd=1; /* enable user+password */ } -- cgit v1.2.1 From e7ce27a22c6785d70c9bc37eff4b58d3570cca41 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Aug 2000 18:08:50 +0000 Subject: Linux name resolving problem fixed with larger name-buffer --- lib/url.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 561ab8202..dabf6e3c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -644,9 +644,11 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) struct UrlData *data = curl; struct connectdata *conn; - /* I believe the longest possible name in a DNS is set to 255 letters, FQDN - so this should be safe: */ - char hostent_buf[512]; + /* I believe the longest possible name in a DNS is set to 255 letters, FQDN. + Although the buffer required for storing all possible aliases and IP + numbers is according to Stevens' Unix Network Programming 2nd editor, + p. 304: 8192 bytes. Let's go with that! */ + char hostent_buf[8192]; if(!data || (data->handle != STRUCT_OPEN)) return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ -- cgit v1.2.1 From e2a63bee59c8c9031873c73750d4c2fbd1598071 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 17 Aug 2000 15:40:26 +0000 Subject: removed HAVE_VPRINTF dependence --- lib/url.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dabf6e3c0..ad43bc773 100644 --- a/lib/url.c +++ b/lib/url.c @@ -83,9 +83,6 @@ #include #endif -#ifndef HAVE_VPRINTF -#error "We can't compile without vprintf() support!" -#endif #ifndef HAVE_SELECT #error "We can't compile without select() support!" #endif -- cgit v1.2.1 From 1b1f143cd65cb86138e3083790d89f959e3ecc87 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 24 Aug 2000 12:33:16 +0000 Subject: hostname and large file support added --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ad43bc773..e74bb4568 100644 --- a/lib/url.c +++ b/lib/url.c @@ -421,6 +421,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_POSTFIELDS: data->postfields = va_arg(param, char *); break; + case CURLOPT_POSTFIELDSIZE: + data->postfieldsize = va_arg(param, long); + break; case CURLOPT_REFERER: data->referer = va_arg(param, char *); data->bits.http_set_referer = (data->referer && *data->referer)?1:0; -- cgit v1.2.1 From b6e18f2f665f16910c04cb52bdc7b90270ab7c9b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 24 Aug 2000 14:26:33 +0000 Subject: #include "setup.h" moved first of all includes --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e74bb4568..cc123fee4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -39,6 +39,9 @@ ****************************************************************************/ /* -- WIN32 approved -- */ + +#include "setup.h" + #include #include #include @@ -49,7 +52,6 @@ #include -#include "setup.h" #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #include -- cgit v1.2.1 From 0a2f67737418bd2e484fe4da9107f25753fe96fd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Sep 2000 10:41:07 +0000 Subject: file:// fix that prevents name lookup and sets no-upload and no-download --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cc123fee4..4b67717a9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1018,6 +1018,11 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->curl_do = file; /* no done() function */ + + result = Transfer(conn, -1, -1, FALSE, NULL, /* no download */ + -1, NULL); /* no upload */ + + return CURLE_OK; } else { -- cgit v1.2.1 From 86ff2c46b73a2bbcd25edaf6a3c1d62c8a85f29d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Sep 2000 14:05:01 +0000 Subject: introduced 'tunnel through http proxy' for ftp --- lib/url.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4b67717a9..0f2dbfb0a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -437,6 +437,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->proxy = va_arg(param, char *); data->bits.httpproxy = data->proxy?1:0; break; + case CURLOPT_HTTPPROXYTUNNEL: + data->bits.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE; + break; case CURLOPT_PROXYPORT: data->proxyport = va_arg(param, long); break; @@ -619,6 +622,7 @@ CURLcode curl_disconnect(CURLconnect *c_connect) return CURLE_OK; } + /* * NAME curl_connect() * @@ -948,7 +952,10 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) data->remote_port = PORT_FTP; conn->protocol |= PROT_FTP; - if(data->bits.httpproxy) { + if(data->bits.httpproxy && + !data->bits.tunnel_thru_httpproxy) { + /* Unless we have asked to tunnel ftp operations through the proxy, we + switch and use HTTP operations only */ conn->curl_do = http; conn->curl_done = http_done; conn->curl_close = http_close; -- cgit v1.2.1 From c9c7fcf411cdb46bbf1d15191db437f45dffd178 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 18 Sep 2000 21:54:08 +0000 Subject: Stephen Kick's interface fixes --- lib/url.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0f2dbfb0a..1a42dd725 100644 --- a/lib/url.c +++ b/lib/url.c @@ -52,7 +52,6 @@ #include - #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #include #include @@ -498,6 +497,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_QUOTE: data->quote = va_arg(param, struct curl_slist *); break; + case CURLOPT_INTERFACE: + data->device = va_arg(param, char *); + break; default: /* unknown tag and its companion, just ignore: */ return CURLE_READ_ERROR; /* correct this */ @@ -1176,6 +1178,136 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->serv_addr.sin_family = conn->hp->h_addrtype; conn->serv_addr.sin_port = htons(data->port); +/* sck 8/31/2000 add support for specifing device to bind socket to */ +/* #ifdef LINUX */ +/* I am using this, but it may not work everywhere, only tested on RedHat 6.2 */ +#ifdef HAVE_INET_NTOA + +#ifndef INADDR_NONE +#define INADDR_NONE (unsigned long) ~0 +#endif + + if (data->device && (strlen(data->device)<255)) { + struct ifreq ifr; + struct sockaddr_in sa; + struct hostent *h=NULL; + size_t size; + unsigned short porttouse; + char myhost[256] = ""; + unsigned long in; + + if(if2ip(data->device, myhost, sizeof(myhost))) { + h = GetHost(data, myhost, hostent_buf, sizeof(hostent_buf)); + } + else { + if(strlen(data->device)>1) { + h = GetHost(data, data->device, hostent_buf, + sizeof(hostent_buf)); + } + if(h) { + strcpy(myhost,data->device); + } + } + + if(! *myhost) { + /* need to fix this + h=GetHost(data, + getmyhost(*myhost,sizeof(myhost)), + hostent_buf, + sizeof(hostent_buf)); + */ + printf("in here\n"); + } + + infof(data, "We connect from %s\n", myhost); + + if ( (in=inet_addr(myhost)) != INADDR_NONE ) { + + if ( h ) { + memset((char *)&sa, 0, sizeof(sa)); + memcpy((char *)&sa.sin_addr, + h->h_addr, + h->h_length); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = in; + sa.sin_port = 0; /* get any port */ + + if( bind(data->firstsocket, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { + /* we succeeded to bind */ + struct sockaddr_in add; + + size = sizeof(add); + if(getsockname(data->firstsocket, (struct sockaddr *) &add, + (int *)&size)<0) { + failf(data, "getsockname() failed"); + return CURLE_HTTP_PORT_FAILED; + } + } + else { + switch(errno) { + case EBADF: + failf(data, "Invalid descriptor: %d", errno); + break; + case EINVAL: + failf(data, "Invalid request: %d", errno); + break; + case EACCES: + failf(data, "Address is protected, user not superuser: %d", errno); + break; + case ENOTSOCK: + failf(data, + "Argument is a descriptor for a file, not a socket: %d", + errno); + break; + case EFAULT: + failf(data, "Inaccessable memory error: %d", errno); + break; + case ENAMETOOLONG: + failf(data, "Address too long: %d", errno); + break; + case ENOMEM: + failf(data, "Insufficient kernel memory was available: %d", errno); + break; +#if 0 + case EROFS: + failf(data, + "Socket inode would reside on a read-only file system: %d", + errno); + break; + case ENOENT: + failf(data, "File does not exist: %d", errno); + break; + case ENOTDIR: + failf(data, "Component of path prefix is not a directory: %d", + errno); + break; + case ELOOP: + failf(data,"Too many symbolic links encountered: %d",errno); + break; +#endif + default: + failf(data,"errno %d\n"); + } /* end of switch */ + + return CURLE_HTTP_PORT_FAILED; + } /* end of else */ + + } /* end of if h */ + else { + failf(data,"could't find my own IP address (%s)", myhost); + return CURLE_HTTP_PORT_FAILED; + } + + } /* end of inet_addr */ + + else { + failf(data, "could't find my own IP address (%s)", myhost); + return CURLE_HTTP_PORT_FAILED; + } + + } /* end of device selection support */ +#endif /* end of HAVE_INET_NTOA */ + if (connect(data->firstsocket, (struct sockaddr *) &(conn->serv_addr), sizeof(conn->serv_addr) @@ -1186,11 +1318,50 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) case ECONNREFUSED: failf(data, "Connection refused"); break; + case EFAULT: + failf(data, "Invalid socket address: %d",errno); + break; + case EISCONN: + failf(data, "Socket already connected: %d",errno); + break; + case ETIMEDOUT: + failf(data, "Timeout while accepting connection, server busy: %d",errno); + break; + case ENETUNREACH: + failf(data, "Network is unreachable: %d",errno); + break; + case EADDRINUSE: + failf(data, "Local address already in use: %d",errno); + break; + case EINPROGRESS: + failf(data, "Socket is nonblocking and connection can not be completed immediately: %d",errno); + break; + case EALREADY: + failf(data, "Socket is nonblocking and a previous connection attempt not completed: %d",errno); + break; + case EAGAIN: + failf(data, "No more free local ports: %d",errno); + break; + case EACCES: + case EPERM: + failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno); + break; #endif #ifdef EINTR case EINTR: failf(data, "Connection timeouted"); break; +#endif +#if 0 + case EAFNOSUPPORT: + failf(data, "Incorrect address family: %d",errno); + break; + case ENOTSOCK: + failf(data, "File descriptor is not a socket: %d",errno); + break; + case EBADF: + failf(data, "File descriptor is not a valid index in descriptor table: %d",errno); + break; #endif default: failf(data, "Can't connect to server: %d", errno); -- cgit v1.2.1 From ce406a732f3363a6c500d5a49f742ac680727018 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 21 Sep 2000 08:50:05 +0000 Subject: krb4 support new GetHost() usage new base64 encoder usage --- lib/url.c | 60 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1a42dd725..514a648dd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -124,6 +124,10 @@ #define _MPRINTF_REPLACE /* use our functions only */ #include +#ifdef KRB4 +#include "security.h" +#endif + /* -- -- */ @@ -500,6 +504,10 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_INTERFACE: data->device = va_arg(param, char *); break; + case CURLOPT_KRB4LEVEL: + data->krb4_level = va_arg(param, char *); + data->bits.krb4=data->krb4_level?TRUE:FALSE; + break; default: /* unknown tag and its companion, just ignore: */ return CURLE_READ_ERROR; /* correct this */ @@ -576,7 +584,12 @@ CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, } else { #endif - bytes_written = swrite(conn->writesockfd, buf, amount); +#ifdef KRB4 + if(conn->sec_complete) + bytes_written = sec_write(conn, conn->sockfd, buf, amount); + else +#endif + bytes_written = swrite(conn->writesockfd, buf, amount); #ifdef USE_SSLEAY } #endif /* USE_SSLEAY */ @@ -602,7 +615,12 @@ CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize, } else { #endif - nread = sread (conn->sockfd, buf, buffersize); +#ifdef KRB4 + if(conn->sec_complete) + nread = sec_read(conn, conn->sockfd, buf, buffersize); + else +#endif + nread = sread (conn->sockfd, buf, buffersize); #ifdef USE_SSLEAY } #endif /* USE_SSLEAY */ @@ -616,6 +634,9 @@ CURLcode curl_disconnect(CURLconnect *c_connect) struct UrlData *data = conn->data; + if(conn->hostent_buf) /* host name info */ + free(conn->hostent_buf); + free(conn); /* free the connection oriented data */ /* clean up the sockets and SSL stuff from the previous "round" */ @@ -652,12 +673,6 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) struct UrlData *data = curl; struct connectdata *conn; - /* I believe the longest possible name in a DNS is set to 255 letters, FQDN. - Although the buffer required for storing all possible aliases and IP - numbers is according to Stevens' Unix Network Programming 2nd editor, - p. 304: 8192 bytes. Let's go with that! */ - char hostent_buf[8192]; - if(!data || (data->handle != STRUCT_OPEN)) return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ @@ -1106,7 +1121,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } /* Connect to target host right on */ - if(!(conn->hp = GetHost(data, conn->name, hostent_buf, sizeof(hostent_buf)))) { + conn->hp = GetHost(data, conn->name, &conn->hostent_buf); + if(!conn->hp) { failf(data, "Couldn't resolv host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; } @@ -1161,7 +1177,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } /* connect to proxy */ - if(!(conn->hp = GetHost(data, proxyptr, hostent_buf, sizeof(hostent_buf)))) { + conn->hp = GetHost(data, proxyptr, &conn->hostent_buf); + if(!conn->hp) { failf(data, "Couldn't resolv proxy '%s'", proxyptr); return CURLE_COULDNT_RESOLVE_PROXY; } @@ -1191,21 +1208,22 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) struct ifreq ifr; struct sockaddr_in sa; struct hostent *h=NULL; + char *hostdataptr; size_t size; unsigned short porttouse; char myhost[256] = ""; unsigned long in; if(if2ip(data->device, myhost, sizeof(myhost))) { - h = GetHost(data, myhost, hostent_buf, sizeof(hostent_buf)); + h = GetHost(data, myhost, &hostdataptr); } else { if(strlen(data->device)>1) { - h = GetHost(data, data->device, hostent_buf, - sizeof(hostent_buf)); + h = GetHost(data, data->device, &hostdataptr); } if(h) { - strcpy(myhost,data->device); + /* we know data->device is shorter than the myhost array */ + strcpy(myhost, data->device); } } @@ -1297,7 +1315,6 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) failf(data,"could't find my own IP address (%s)", myhost); return CURLE_HTTP_PORT_FAILED; } - } /* end of inet_addr */ else { @@ -1305,6 +1322,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) return CURLE_HTTP_PORT_FAILED; } + free(hostdataptr); /* allocated by GetHost() */ + } /* end of device selection support */ #endif /* end of HAVE_INET_NTOA */ @@ -1371,12 +1390,13 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } if(data->bits.proxy_user_passwd) { - char authorization[512]; + char *authorization; sprintf(data->buffer, "%s:%s", data->proxyuser, data->proxypasswd); - base64Encode(data->buffer, authorization); - - data->ptr_proxyuserpwd = maprintf("Proxy-authorization: Basic %s\015\012", - authorization); + if(base64Encode(data->buffer, 0, &authorization) >= 0) { + data->ptr_proxyuserpwd = + maprintf("Proxy-authorization: Basic %s\015\012", authorization); + free(authorization); + } } if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) { if(data->useragent) { -- cgit v1.2.1 From d03db1cd11b44adddbd1989c26ec81d235f32f07 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Sep 2000 22:16:36 +0000 Subject: corrected curl_write() for kerberos --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 514a648dd..f3231436a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -586,7 +586,7 @@ CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, #endif #ifdef KRB4 if(conn->sec_complete) - bytes_written = sec_write(conn, conn->sockfd, buf, amount); + bytes_written = sec_write(conn, conn->writesockfd, buf, amount); else #endif bytes_written = swrite(conn->writesockfd, buf, amount); -- cgit v1.2.1 From 13962adcb55a676b0b47925680b2e17b3e4815f0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Sep 2000 10:26:44 +0000 Subject: 7.3 commit --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f3231436a..4ddafc182 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1392,7 +1392,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(data->bits.proxy_user_passwd) { char *authorization; sprintf(data->buffer, "%s:%s", data->proxyuser, data->proxypasswd); - if(base64Encode(data->buffer, 0, &authorization) >= 0) { + if(base64_encode(data->buffer, strlen(data->buffer), + &authorization) >= 0) { data->ptr_proxyuserpwd = maprintf("Proxy-authorization: Basic %s\015\012", authorization); free(authorization); -- cgit v1.2.1 From eee5c71affa2b158b707d5c46eeef25edcce2a67 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Oct 2000 11:03:55 +0000 Subject: inits the upload_bufsize at connect time --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4ddafc182..a0c90e7b3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -692,6 +692,9 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->data = data; /* remember our daddy */ conn->state = CONN_INIT; + conn->upload_bufsize = UPLOAD_BUFSIZE; /* the smallest upload buffer size + we use */ + buf = data->buffer; /* this is our buffer */ #if 0 -- cgit v1.2.1 From 2cdd150723ecb17b58fcd440f05b69c7235b1967 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Oct 2000 22:04:04 +0000 Subject: removed writeinfo stuff --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a0c90e7b3..582d03da0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -483,9 +483,11 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_WRITEFUNCTION: data->fwrite = va_arg(param, curl_write_callback); break; +#if 0 case CURLOPT_WRITEINFO: data->writeinfo = va_arg(param, char *); break; +#endif case CURLOPT_READFUNCTION: data->fread = va_arg(param, curl_read_callback); break; -- cgit v1.2.1 From 03a56b3e56f8200c479f3786b54dc458b148f667 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 6 Oct 2000 06:28:39 +0000 Subject: HTTP resume fix, now the range pointer may be allocated --- lib/url.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 582d03da0..3865d201e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -183,6 +183,11 @@ void static urlfree(struct UrlData *data, bool totally) switch off that knowledge again... */ data->bits.httpproxy=FALSE; } + + if(data->bits.rangestringalloc) { + free(data->range); + data->range=NULL; + } if(data->ptr_proxyuserpwd) { free(data->ptr_proxyuserpwd); @@ -906,7 +911,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(!data->bits.set_range) { /* if it already was in use, we just skip this */ sprintf(resumerange, "%d-", data->resume_from); - data->range=resumerange; /* tell ourselves to fetch this range */ + data->range=strdup(resumerange); /* tell ourselves to fetch this range */ + data->bits.rangestringalloc = TRUE; /* mark as allocated */ data->bits.set_range = 1; /* switch on range usage */ } } -- cgit v1.2.1 From c58dc8f82fc65e7279ad2e6ad306202fc17c9af8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 6 Oct 2000 11:03:20 +0000 Subject: the --interface code doesn't work on win32 and is #ifndef WIN32 now --- lib/url.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3865d201e..640b8597a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -109,7 +109,6 @@ #include "progress.h" #include "cookie.h" #include "strequal.h" -#include "writeout.h" /* And now for the protocols */ #include "ftp.h" @@ -1206,9 +1205,14 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->serv_addr.sin_family = conn->hp->h_addrtype; conn->serv_addr.sin_port = htons(data->port); -/* sck 8/31/2000 add support for specifing device to bind socket to */ -/* #ifdef LINUX */ -/* I am using this, but it may not work everywhere, only tested on RedHat 6.2 */ +#ifndef WIN32 + /* We don't generally like checking for OS-versions, we should make this + HAVE_XXXX based, although at the moment I don't have a decent test for + this! */ + + /* sck 8/31/2000 add support for specifing device to bind socket to */ + /* I am using this, but it may not work everywhere, only tested on + RedHat 6.2 */ #ifdef HAVE_INET_NTOA #ifndef INADDR_NONE @@ -1337,6 +1341,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) } /* end of device selection support */ #endif /* end of HAVE_INET_NTOA */ +#endif /* end of not WIN32 */ if (connect(data->firstsocket, (struct sockaddr *) &(conn->serv_addr), -- cgit v1.2.1 From 0f8facb49b45a711fa7832c68260a5b45b362922 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Oct 2000 11:12:34 +0000 Subject: added memory debugging include file --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 640b8597a..822f14e12 100644 --- a/lib/url.c +++ b/lib/url.c @@ -126,6 +126,10 @@ #ifdef KRB4 #include "security.h" #endif +/* The last #include file should be: */ +#ifdef MALLOCDEBUG +#include "memdebug.h" +#endif /* -- -- */ -- cgit v1.2.1 From 7717212912e4fa05761809b215467c39036843bb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Oct 2000 10:58:37 +0000 Subject: free the URL string if that was allocated --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 822f14e12..2cdb0c06e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -235,6 +235,10 @@ void static urlfree(struct UrlData *data, bool totally) if(data->free_referer) free(data->referer); + if(data->bits.urlstringalloc) + /* the URL is allocated, free it! */ + free(data->url); + cookie_cleanup(data->cookies); free(data); -- cgit v1.2.1 From 751d503f54596d6d86f969683fec2fe296d9d1f0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 12 Oct 2000 08:22:16 +0000 Subject: sprintf() => snprintf() --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2cdb0c06e..c6f2606f7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -917,7 +917,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(data->resume_from) { if(!data->bits.set_range) { /* if it already was in use, we just skip this */ - sprintf(resumerange, "%d-", data->resume_from); + snprintf(resumerange, sizeof(resumerange), "%d-", data->resume_from); data->range=strdup(resumerange); /* tell ourselves to fetch this range */ data->bits.rangestringalloc = TRUE; /* mark as allocated */ data->bits.set_range = 1; /* switch on range usage */ @@ -1415,7 +1415,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(data->bits.proxy_user_passwd) { char *authorization; - sprintf(data->buffer, "%s:%s", data->proxyuser, data->proxypasswd); + snprintf(data->buffer, BUFSIZE, "%s:%s", + data->proxyuser, data->proxypasswd); if(base64_encode(data->buffer, strlen(data->buffer), &authorization) >= 0) { data->ptr_proxyuserpwd = -- cgit v1.2.1 From c44b10de41ffca204acf11f36093c24521119239 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 20 Oct 2000 13:48:38 +0000 Subject: remote_port used in Host: headers only when non-default --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c6f2606f7..753222124 100644 --- a/lib/url.c +++ b/lib/url.c @@ -961,7 +961,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) conn->curl_close = http_close; #else /* USE_SSLEAY */ - failf(data, "SSL is disabled, https: not supported!"); + failf(data, "libcurl was built with SSL disabled, https: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; #endif /* !USE_SSLEAY */ } @@ -1137,7 +1137,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) *tmp++ = '\0'; data->port = atoi(tmp); } - + data->remote_port = data->port; /* it is the same port */ + /* Connect to target host right on */ conn->hp = GetHost(data, conn->name, &conn->hostent_buf); if(!conn->hp) { -- cgit v1.2.1 From 02037971ed5a97ad78c062e753b53c7a1542bcc5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 26 Oct 2000 10:32:04 +0000 Subject: =?UTF-8?q?renamed=20getpass()=20to=20my=5Fgetpass()=20and=20it=20?= =?UTF-8?q?is=20now=20thread-safe=20and=20should=20disable=20passwd-echoin?= =?UTF-8?q?g=20on=20win32=20(supplied=20by=20Bj=F6rn=20Stenberg)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 753222124..32faa3423 100644 --- a/lib/url.c +++ b/lib/url.c @@ -780,16 +780,16 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(*data->userpwd != ':') { /* the name is given, get user+password */ - sscanf(data->userpwd, "%127[^:]:%127[^@]", + sscanf(data->userpwd, "%127[^:]:%127[^\n]", data->user, data->passwd); } else /* no name given, get the password only */ - sscanf(data->userpwd+1, "%127[^@]", data->passwd); + sscanf(data->userpwd+1, "%127[^\n]", data->passwd); /* check for password, if no ask for one */ if( !data->passwd[0] ) { - strncpy(data->passwd, getpass("password: "), sizeof(data->passwd)); + my_getpass("password:", data->passwd, sizeof(data->passwd)); } } @@ -799,16 +799,18 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(*data->proxyuserpwd != ':') { /* the name is given, get user+password */ - sscanf(data->proxyuserpwd, "%127[^:]:%127[^@]", + sscanf(data->proxyuserpwd, "%127[^:]:%127[^\n]", data->proxyuser, data->proxypasswd); } else /* no name given, get the password only */ - sscanf(data->proxyuserpwd+1, "%127[^@]", data->proxypasswd); + sscanf(data->proxyuserpwd+1, "%127[^\n]", data->proxypasswd); /* check for password, if no ask for one */ if( !data->proxypasswd[0] ) { - strncpy(data->proxypasswd, getpass("proxy password: "), sizeof(data->proxypasswd)); + my_getpass("proxy password:", + data->proxypasswd, + sizeof(data->proxypasswd)); } } @@ -1117,7 +1119,7 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) /* check for password, if no ask for one */ if( !data->passwd[0] ) { - strncpy(data->passwd, getpass("password: "), sizeof(data->passwd)); + my_getpass("password:",data->passwd,sizeof(data->passwd)); } conn->name = ++ptr; -- cgit v1.2.1 From 9d0d8280e984ca265bb61f075020d85e9a5b9ad8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 26 Oct 2000 21:57:12 +0000 Subject: Georg Horn provided a fix for the timeout signal stuff. Finally the timeout switch should work under most unixes (requires sigaction()) --- lib/url.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 32faa3423..c941e99e3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -686,6 +686,9 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) char resumerange[12]=""; struct UrlData *data = curl; struct connectdata *conn; +#ifdef HAVE_SIGACTION + struct sigaction sigact; +#endif if(!data || (data->handle != STRUCT_OPEN)) return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ @@ -711,8 +714,11 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) buf = data->buffer; /* this is our buffer */ -#if 0 - signal(SIGALRM, alarmfunc); +#ifdef HAVE_SIGACTION + sigaction(SIGALRM, NULL, &sigact); + sigact.sa_handler = alarmfunc; + sigact.sa_flags &= ~SA_RESTART; + sigaction(SIGALRM, &sigact, NULL); #endif /* Parse */ @@ -1393,11 +1399,9 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno); break; #endif -#ifdef EINTR case EINTR: failf(data, "Connection timeouted"); break; -#endif #if 0 case EAFNOSUPPORT: failf(data, "Incorrect address family: %d",errno); -- cgit v1.2.1 From 0cff27906300a046e3569d7b32887d681fc8ea62 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 30 Oct 2000 11:53:40 +0000 Subject: new urldata ssl layout and T. Bharath brought the new SSL cert verify function --- lib/url.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c941e99e3..76b8f4e8d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -150,19 +150,19 @@ void curl_free(void) void static urlfree(struct UrlData *data, bool totally) { #ifdef USE_SSLEAY - if (data->use_ssl) { - if(data->ssl) { - (void)SSL_shutdown(data->ssl); - SSL_set_connect_state(data->ssl); + if (data->ssl.use) { + if(data->ssl.handle) { + (void)SSL_shutdown(data->ssl.handle); + SSL_set_connect_state(data->ssl.handle); - SSL_free (data->ssl); - data->ssl = NULL; + SSL_free (data->ssl.handle); + data->ssl.handle = NULL; } - if(data->ctx) { - SSL_CTX_free (data->ctx); - data->ctx = NULL; + if(data->ssl.ctx) { + SSL_CTX_free (data->ssl.ctx); + data->ssl.ctx = NULL; } - data->use_ssl = FALSE; /* get back to ordinary socket usage */ + data->ssl.use = FALSE; /* get back to ordinary socket usage */ } #endif /* USE_SSLEAY */ @@ -380,7 +380,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_SSLVERSION: - data->ssl_version = va_arg(param, long); + data->ssl.version = va_arg(param, long); break; case CURLOPT_COOKIEFILE: @@ -522,6 +522,13 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->krb4_level = va_arg(param, char *); data->bits.krb4=data->krb4_level?TRUE:FALSE; break; + case CURLOPT_SSL_VERIFYPEER: + data->ssl.verifypeer = va_arg(param, long); + break; + case CURLOPT_CAINFO: + data->ssl.CAfile = va_arg(param, char *); + data->ssl.CApath = NULL; /*This does not work on windows.*/ + break; default: /* unknown tag and its companion, just ignore: */ return CURLE_READ_ERROR; /* correct this */ @@ -546,8 +553,8 @@ int GetLine(int sockfd, char *buf, struct UrlData *data) (nreaduse_ssl) { - read_rc = SSL_read(data->ssl, ptr, 1); + if (data->ssl.use) { + read_rc = SSL_read(data->ssl.handle, ptr, 1); } else { #endif @@ -593,8 +600,8 @@ CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, data = conn->data; #ifdef USE_SSLEAY - if (data->use_ssl) { - bytes_written = SSL_write(data->ssl, buf, amount); + if (data->ssl.use) { + bytes_written = SSL_write(data->ssl.handle, buf, amount); } else { #endif @@ -624,8 +631,8 @@ CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize, data = conn->data; #ifdef USE_SSLEAY - if (data->use_ssl) { - nread = SSL_read (data->ssl, buf, buffersize); + if (data->ssl.use) { + nread = SSL_read (data->ssl.handle, buf, buffersize); } else { #endif -- cgit v1.2.1 From 852b664e450b15bff3b9d05e6fefcee78b86335e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 1 Nov 2000 08:19:10 +0000 Subject: added signal in case sigaction is missing --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 76b8f4e8d..492192ed0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -726,6 +726,12 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) sigact.sa_handler = alarmfunc; sigact.sa_flags &= ~SA_RESTART; sigaction(SIGALRM, &sigact, NULL); +#else + /* no sigaction(), revert to the much lamer signal() */ +#ifdef HAVE_SIGNAL + signal(SIGALRM, alarmfunc); +#endif + #endif /* Parse */ -- cgit v1.2.1 From b6bb734215a40238ada3a02c9fcddcf5bf934c2c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Nov 2000 08:12:30 +0000 Subject: Emmanuel Tychon found a problem when specifying user-name only in a URL (and the password entered interactively). This fix also includes proper URL-decoding of the user name and password if specified in the URL. --- lib/url.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 492192ed0..590348029 100644 --- a/lib/url.c +++ b/lib/url.c @@ -109,6 +109,7 @@ #include "progress.h" #include "cookie.h" #include "strequal.h" +#include "escape.h" /* And now for the protocols */ #include "ftp.h" @@ -1129,17 +1130,35 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(*conn->name != ':') { /* the name is given, get user+password */ - sscanf(conn->name, "%127[^:]:%127[^@]", + sscanf(conn->name, "%127[^:@]:%127[^@]", data->user, data->passwd); } else /* no name given, get the password only */ sscanf(conn->name+1, "%127[^@]", data->passwd); + if(data->user[0]) { + char *newname=curl_unescape(data->user, 0); + if(strlen(newname) < sizeof(data->user)) { + strcpy(data->user, newname); + } + /* if the new name is longer than accepted, then just use + the unconverted name, it'll be wrong but what the heck */ + free(newname); + } + /* check for password, if no ask for one */ if( !data->passwd[0] ) { my_getpass("password:",data->passwd,sizeof(data->passwd)); } + 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); + } + free(newpasswd); + } conn->name = ++ptr; data->bits.user_passwd=1; /* enable user+password */ -- cgit v1.2.1 From 9f4f16b55d7df262774aee227933347e0ae3846e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Nov 2000 22:53:50 +0000 Subject: new getpass proto and function pointer usage --- lib/url.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 590348029..d1613ebd6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -306,6 +306,9 @@ CURLcode curl_open(CURL **curl, char *url) /* use fread as default function to read input */ data->fread = (size_t (*)(char *, size_t, size_t, FILE *))fread; + /* set the default passwd function */ + data->fpasswd = my_getpass; + data->infilesize = -1; /* we don't know any size */ data->current_speed = -1; /* init to negative == impossible */ @@ -479,6 +482,12 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_PROGRESSDATA: data->progress_client = va_arg(param, void *); break; + case CURLOPT_PASSWDFUNCTION: + data->fpasswd = va_arg(param, curl_passwd_callback); + break; + case CURLOPT_PASSWDDATA: + data->passwd_client = va_arg(param, void *); + break; case CURLOPT_PROXYUSERPWD: data->proxyuserpwd = va_arg(param, char *); data->bits.proxy_user_passwd = data->proxyuserpwd?1:0; @@ -809,7 +818,10 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) /* check for password, if no ask for one */ if( !data->passwd[0] ) { - my_getpass("password:", data->passwd, sizeof(data->passwd)); + if(!data->fpasswd || + data->fpasswd(data->passwd_client, + "password:", data->passwd, sizeof(data->passwd))) + return CURLE_BAD_PASSWORD_ENTERED; } } @@ -828,9 +840,12 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) /* check for password, if no ask for one */ if( !data->proxypasswd[0] ) { - my_getpass("proxy password:", - data->proxypasswd, - sizeof(data->proxypasswd)); + if(!data->fpasswd || + data->fpasswd( data->passwd_client, + "proxy password:", + data->proxypasswd, + sizeof(data->proxypasswd))) + return CURLE_BAD_PASSWORD_ENTERED; } } @@ -1149,7 +1164,10 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) /* check for password, if no ask for one */ if( !data->passwd[0] ) { - my_getpass("password:",data->passwd,sizeof(data->passwd)); + if(!data->fpasswd || + data->fpasswd(data->passwd_client, + "password:",data->passwd,sizeof(data->passwd))) + return CURLE_BAD_PASSWORD_ENTERED; } else { /* we have a password found in the URL, decode it! */ -- cgit v1.2.1 From 56548f9a13b9438ca2be3760f486f5441f679057 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Nov 2000 23:18:50 +0000 Subject: getpass_r() is the new getpass name for thread-safe getpass! --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d1613ebd6..f3212901a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -264,6 +264,12 @@ CURLcode curl_close(CURL *curl) return CURLE_OK; } +int my_getpass(void *clientp, char *prompt, char* buffer, int buflen ) +{ + return getpass_r(prompt, buffer, buflen); +} + + CURLcode curl_open(CURL **curl, char *url) { /* We don't yet support specifying the URL at this point */ -- cgit v1.2.1 From 7b5c551835d3ac00f12a06b804f54a91eb97e367 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Nov 2000 09:19:09 +0000 Subject: adjusted to the changed getpass_r() --- lib/url.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f3212901a..9e32eaff4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -266,7 +266,12 @@ CURLcode curl_close(CURL *curl) int my_getpass(void *clientp, char *prompt, char* buffer, int buflen ) { - return getpass_r(prompt, buffer, buflen); + char *retbuf; + retbuf = getpass_r(prompt, buffer, buflen); + if(NULL == retbuf) + return 1; + else + return 0; /* success */ } -- cgit v1.2.1 From 2297bc4791e1cb5c6ed034b4d4a1355c1e4e1b0c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Nov 2000 09:48:21 +0000 Subject: changed the 'port' field to long to better work with the va_arg() system --- lib/url.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9e32eaff4..eea7808ea 100644 --- a/lib/url.c +++ b/lib/url.c @@ -446,9 +446,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->url = va_arg(param, char *); break; case CURLOPT_PORT: - /* this typecast is used to fool the compiler to NOT warn for a - "cast from pointer to integer of different size" */ - data->port = (unsigned short)(va_arg(param, long)); + data->port = va_arg(param, long); break; case CURLOPT_POSTFIELDS: data->postfields = va_arg(param, char *); -- cgit v1.2.1 From 868488b518706a7eba8e380eeb51d71066a73df8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Nov 2000 14:03:58 +0000 Subject: memory leak cleanup campaign --- lib/url.c | 65 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index eea7808ea..057e163a6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -685,26 +685,7 @@ CURLcode curl_disconnect(CURLconnect *c_connect) return CURLE_OK; } - -/* - * NAME curl_connect() - * - * DESCRIPTION - * - * Connects to the peer server and performs the initial setup. This function - * writes a connect handle to its second argument that is a unique handle for - * this connect. This allows multiple connects from the same handle returned - * by curl_open(). - * - * EXAMPLE - * - * CURLCode result; - * CURL curl; - * CURLconnect connect; - * result = curl_connect(curl, &connect); - */ - -CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) +static CURLcode _connect(CURL *curl, CURLconnect **in_connect) { char *tmp; char *buf; @@ -1537,6 +1518,50 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) return CURLE_OK; } +CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) +{ + CURLcode code; + struct connectdata *conn; + + /* call the stuff that needs to be called */ + code = _connect(curl, in_connect); + + if(CURLE_OK != code) { + /* We're not allowed to return failure with memory left allocated + in the connectdata struct, free those here */ + conn = (struct connectdata *)*in_connect; + if(conn) { + if(conn->hostent_buf) + free(conn->hostent_buf); + free(conn); + *in_connect=NULL; + } + } + return code; +} + + +/* + * NAME curl_connect() + * + * DESCRIPTION + * + * Connects to the peer server and performs the initial setup. This function + * writes a connect handle to its second argument that is a unique handle for + * this connect. This allows multiple connects from the same handle returned + * by curl_open(). + * + * EXAMPLE + * + * CURLCode result; + * CURL curl; + * CURLconnect connect; + * result = curl_connect(curl, &connect); + */ + + + + CURLcode curl_done(CURLconnect *c_connect) { struct connectdata *conn = c_connect; -- cgit v1.2.1 From bda9fde4d84f595482b8f45b2f5db3d9a18d4689 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 18 Nov 2000 16:31:27 +0000 Subject: spell correction resolv => resolve in two error messages --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 057e163a6..faaa99692 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1190,7 +1190,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) /* Connect to target host right on */ conn->hp = GetHost(data, conn->name, &conn->hostent_buf); if(!conn->hp) { - failf(data, "Couldn't resolv host '%s'", conn->name); + failf(data, "Couldn't resolve host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; } } @@ -1246,7 +1246,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) /* connect to proxy */ conn->hp = GetHost(data, proxyptr, &conn->hostent_buf); if(!conn->hp) { - failf(data, "Couldn't resolv proxy '%s'", proxyptr); + failf(data, "Couldn't resolve proxy '%s'", proxyptr); return CURLE_COULDNT_RESOLVE_PROXY; } -- cgit v1.2.1 From 91c879461ef308ba24404c3e7e84870f83844001 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 20 Nov 2000 07:35:21 +0000 Subject: Alexander Kourakos's lowercase environment variable fix --- lib/url.c | 63 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index faaa99692..4e9d1bd2c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -849,20 +849,29 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) /* If proxy was not specified, we check for default proxy environment variables, to enable i.e Lynx compliance: - HTTP_PROXY http://some.server.dom:port/ - HTTPS_PROXY http://some.server.dom:port/ - FTP_PROXY http://some.server.dom:port/ - GOPHER_PROXY http://some.server.dom:port/ - NO_PROXY host.domain.dom (a comma-separated list of hosts which should - not be proxied, or an asterisk to override all proxy variables) - ALL_PROXY seems to exist for the CERN www lib. Probably the first to - check for. - + http_proxy=http://some.server.dom:port/ + https_proxy=http://some.server.dom:port/ + ftp_proxy=http://some.server.dom:port/ + gopher_proxy=http://some.server.dom:port/ + no_proxy=domain1.dom,host.domain2.dom + (a comma-separated list of hosts which should + not be proxied, or an asterisk to override + all proxy variables) + all_proxy=http://some.server.dom:port/ + (seems to exist for the CERN www lib. Probably + the first to check for.) + + For compatibility, the all-uppercase versions of these variables are + checked if the lowercase versions don't exist. */ - char *no_proxy=GetEnv("NO_PROXY"); + char *no_proxy=NULL; char *proxy=NULL; char proxy_env[128]; + no_proxy=GetEnv("no_proxy"); + if(!no_proxy) + no_proxy=GetEnv("NO_PROXY"); + if(!no_proxy || !strequal("*", no_proxy)) { /* NO_PROXY wasn't specified or it wasn't just an asterisk */ char *nope; @@ -885,23 +894,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) char *envp = proxy_env; char *prox; - /* Now, build _PROXY and check for such a one to use */ - while(*protop) { - *envp++ = toupper(*protop++); - } - /* append _PROXY */ - strcpy(envp, "_PROXY"); -#if 0 - infof(data, "DEBUG: checks the environment variable %s\n", proxy_env); -#endif + /* Now, build _proxy and check for such a one to use */ + while(*protop) + *envp++ = tolower(*protop++); + + /* append _proxy */ + strcpy(envp, "_proxy"); + /* read the protocol proxy: */ prox=GetEnv(proxy_env); + if(!prox) { + /* There was no lowercase variable, try the uppercase version: */ + for(envp = proxy_env; *envp; envp++) + *envp = toupper(*envp); + prox=GetEnv(proxy_env); + } + if(prox && *prox) { /* don't count "" strings */ proxy = prox; /* use this */ - } - else - proxy = GetEnv("ALL_PROXY"); /* default proxy to use */ + } + else { + proxy = GetEnv("all_proxy"); /* default proxy to use */ + if(!proxy) + proxy=GetEnv("ALL_PROXY"); + } if(proxy && *proxy) { /* we have a proxy here to set */ @@ -909,7 +926,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->bits.proxystringalloc=1; /* this needs to be freed later */ data->bits.httpproxy=1; } - } /* if (!nope) - it wasn't specfied non-proxy */ + } /* if (!nope) - it wasn't specified non-proxy */ } /* NO_PROXY wasn't specified or '*' */ if(no_proxy) free(no_proxy); -- cgit v1.2.1 From 42280e95bf159c4db89e3d9ea3d2e77f32cf800f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 20 Nov 2000 08:53:21 +0000 Subject: removed URL size restrictions --- lib/url.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4e9d1bd2c..f212bb5d0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -677,6 +677,9 @@ CURLcode curl_disconnect(CURLconnect *c_connect) if(conn->hostent_buf) /* host name info */ free(conn->hostent_buf); + if(conn->path) /* the URL path part */ + free(conn->path); + free(conn); /* free the connection oriented data */ /* clean up the sockets and SSL stuff from the previous "round" */ @@ -696,6 +699,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #ifdef HAVE_SIGACTION struct sigaction sigact; #endif + int urllen; if(!data || (data->handle != STRUCT_OPEN)) return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ @@ -734,13 +738,25 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #endif + /* We need to allocate memory to store the path in. We get the size of the + full URL to be sure, and we need to make it at least 256 bytes since + other parts of the code will rely on this fact */ +#define LEAST_PATH_ALLOC 256 + urllen=strlen(data->url); + if(urllen < LEAST_PATH_ALLOC) + urllen=LEAST_PATH_ALLOC; + + conn->path=(char *)malloc(urllen); + if(NULL == conn->path) + return CURLE_OUT_OF_MEMORY; /* really bad error */ + /* Parse */ /* We need to parse the url, even when using the proxy, because * we will need the hostname and port in case we are trying * to SSL connect through the proxy -- and we don't know if we * will need to use SSL until we parse the url ... */ - if((2 == sscanf(data->url, "%64[^:]://%" URL_MAX_LENGTH_TXT "[^\n]", + if((2 == sscanf(data->url, "%64[^:]://%[^\n]", conn->proto, conn->path)) && strequal(conn->proto, "file")) { /* we deal with file:/// differently since it @@ -760,11 +776,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) strcpy(conn->path, "/"); if (2 > sscanf(data->url, - "%64[^\n:]://%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", + "%64[^\n:]://%256[^\n/]%[^\n]", conn->proto, conn->gname, conn->path)) { /* badly formatted, let's try the browser-style _without_ 'http://' */ - if((1 > sscanf(data->url, "%256[^\n/]%" URL_MAX_LENGTH_TXT "[^\n]", + if((1 > sscanf(data->url, "%256[^\n/]%[^\n]", conn->gname, conn->path)) ) { failf(data, " malformed"); return CURLE_URL_MALFORMAT; @@ -1548,6 +1564,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) in the connectdata struct, free those here */ conn = (struct connectdata *)*in_connect; if(conn) { + if(conn->path) + free(conn->path); if(conn->hostent_buf) free(conn->hostent_buf); free(conn); -- cgit v1.2.1 From 3e5ba33e2dcf2fe5959ee63e46944d2b2e2f1aa5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Nov 2000 09:31:55 +0000 Subject: removed two unused variables and added an extra set of parentheses, done to remove pedantic compiler warnings --- lib/url.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f212bb5d0..d4db4428e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1160,7 +1160,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_URL_MALFORMAT_USER; } #endif - if(ptr=strchr(conn->name, '@')) { + if((ptr=strchr(conn->name, '@'))) { /* there's a user+password given here, to the left of the @ */ data->user[0] =0; @@ -1310,12 +1310,10 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #endif if (data->device && (strlen(data->device)<255)) { - struct ifreq ifr; struct sockaddr_in sa; struct hostent *h=NULL; char *hostdataptr; size_t size; - unsigned short porttouse; char myhost[256] = ""; unsigned long in; -- cgit v1.2.1 From 2a5e68ea895136168dd6d0d753299e9b04fd85a1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Nov 2000 15:36:38 +0000 Subject: added some defensive code around the GetHost()'s third argument result --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d4db4428e..a88d1a214 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1312,7 +1312,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) if (data->device && (strlen(data->device)<255)) { struct sockaddr_in sa; struct hostent *h=NULL; - char *hostdataptr; + char *hostdataptr=NULL; size_t size; char myhost[256] = ""; unsigned long in; @@ -1425,7 +1425,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_HTTP_PORT_FAILED; } - free(hostdataptr); /* allocated by GetHost() */ + if(hostdataptr) + free(hostdataptr); /* allocated by GetHost() */ } /* end of device selection support */ #endif /* end of HAVE_INET_NTOA */ -- cgit v1.2.1 From c93816652081a39f2e8eabce9bdb0d32aa82a455 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Nov 2000 19:06:55 +0000 Subject: set rangestringalloc to 0 after the string has been freed to prevent it from being freed twice (a NULL free the second time) --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a88d1a214..878aee1f6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -191,6 +191,7 @@ void static urlfree(struct UrlData *data, bool totally) if(data->bits.rangestringalloc) { free(data->range); data->range=NULL; + data->bits.rangestringalloc=0; /* free now */ } if(data->ptr_proxyuserpwd) { @@ -693,7 +694,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) char *tmp; char *buf; CURLcode result; - char resumerange[12]=""; + char resumerange[40]=""; struct UrlData *data = curl; struct connectdata *conn; #ifdef HAVE_SIGACTION -- cgit v1.2.1 From b5739b3a97318ee52b5069b305e43ea972621b0c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 22 Nov 2000 13:50:17 +0000 Subject: document time fixes --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 878aee1f6..9522034f0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -365,6 +365,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_POST: data->bits.http_post = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_FILETIME: + data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE; + break; case CURLOPT_FTPLISTONLY: data->bits.ftp_list_only = va_arg(param, long)?TRUE:FALSE; break; -- cgit v1.2.1 From b8f7d94ef15b93c98cda472a32227d84a3ac5f72 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 28 Nov 2000 09:05:47 +0000 Subject: James Griffiths' max-redirs fix --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9522034f0..2d88aa495 100644 --- a/lib/url.c +++ b/lib/url.c @@ -478,6 +478,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_TIMEOUT: data->timeout = va_arg(param, long); break; + case CURLOPT_MAXREDIRS: + data->maxredirs = va_arg(param, long); + break; case CURLOPT_USERAGENT: data->useragent = va_arg(param, char *); break; -- cgit v1.2.1 From 9980568f42a8954e74171f25d416ba39131ee2c9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Nov 2000 08:16:27 +0000 Subject: removed '#if 0' sections --- lib/url.c | 57 --------------------------------------------------------- 1 file changed, 57 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2d88aa495..006644f41 100644 --- a/lib/url.c +++ b/lib/url.c @@ -298,13 +298,6 @@ CURLcode curl_open(CURL **curl, char *url) data-> headersize=HEADERSIZE; -#if 0 - /* Let's set some default values: */ - curl_setopt(data, CURLOPT_FILE, stdout); /* default output to stdout */ - curl_setopt(data, CURLOPT_INFILE, stdin); /* default input from stdin */ - curl_setopt(data, CURLOPT_STDERR, stderr); /* default stderr to stderr! */ -#endif - data->out = stdout; /* default output to stdout */ data->in = stdin; /* default input from stdin */ data->err = stderr; /* default stderr to stderr */ @@ -521,11 +514,6 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_WRITEFUNCTION: data->fwrite = va_arg(param, curl_write_callback); break; -#if 0 - case CURLOPT_WRITEINFO: - data->writeinfo = va_arg(param, char *); - break; -#endif case CURLOPT_READFUNCTION: data->fread = va_arg(param, curl_read_callback); break; @@ -1161,12 +1149,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) user+password pair in a string like: ftp://user:password@ftp.my.site:8021/README */ char *ptr=NULL; /* assign to remove possible warnings */ -#if 0 - if(':' == *conn->name) { - failf(data, "URL malformat: user can't be zero length"); - return CURLE_URL_MALFORMAT_USER; - } -#endif if((ptr=strchr(conn->name, '@'))) { /* there's a user+password given here, to the left of the @ */ @@ -1396,23 +1378,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) case ENOMEM: failf(data, "Insufficient kernel memory was available: %d", errno); break; -#if 0 - case EROFS: - failf(data, - "Socket inode would reside on a read-only file system: %d", - errno); - break; - case ENOENT: - failf(data, "File does not exist: %d", errno); - break; - case ENOTDIR: - failf(data, "Component of path prefix is not a directory: %d", - errno); - break; - case ELOOP: - failf(data,"Too many symbolic links encountered: %d",errno); - break; -#endif default: failf(data,"errno %d\n"); } /* end of switch */ @@ -1481,17 +1446,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) case EINTR: failf(data, "Connection timeouted"); break; -#if 0 - case EAFNOSUPPORT: - failf(data, "Incorrect address family: %d",errno); - break; - case ENOTSOCK: - failf(data, "File descriptor is not a socket: %d",errno); - break; - case EBADF: - failf(data, "File descriptor is not a valid index in descriptor table: %d",errno); - break; -#endif default: failf(data, "Can't connect to server: %d", errno); break; @@ -1538,10 +1492,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in)); } -#if 0 /* Kerberos experiements! Beware! Take cover! */ - kerberos_connect(data, name); -#endif - #ifdef __EMX__ /* 20000330 mgs * the check is quite a hack... @@ -1654,13 +1604,6 @@ CURLcode curl_do(CURLconnect *in_conn) conn->state = CONN_DO; /* we have entered this state */ -#if 0 - if(conn->bytecount) { - double ittook = tvdiff (tvnow(), conn->now); - infof(data, "%i bytes transfered in %.3lf seconds (%.0lf bytes/sec).\n", - conn->bytecount, ittook, (double)conn->bytecount/(ittook!=0.0?ittook:1)); - } -#endif return CURLE_OK; } -- cgit v1.2.1 From 69abefc936bd00d7e991acab71f811b9750bf8ba Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 7 Dec 2000 09:09:26 +0000 Subject: Added SA_RESTART since (some) HPUX doesn't have that define and it doesn't need it --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 006644f41..b2e47b7ed 100644 --- a/lib/url.c +++ b/lib/url.c @@ -723,7 +723,10 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #ifdef HAVE_SIGACTION sigaction(SIGALRM, NULL, &sigact); sigact.sa_handler = alarmfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ sigact.sa_flags &= ~SA_RESTART; +#endif sigaction(SIGALRM, &sigact, NULL); #else /* no sigaction(), revert to the much lamer signal() */ -- cgit v1.2.1 From 24dee483e9e925c2ab79dd582f70c9a55ab9ba4d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Jan 2001 09:29:33 +0000 Subject: dual-license fix --- lib/url.c | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b2e47b7ed..b6a2848b1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,38 +5,21 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * The contents of this file are subject to the Mozilla Public License - * Version 1.0 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ + * Copyright (C) 2000, Daniel Stenberg, , et al. * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - * License for the specific language governing rights and limitations - * under the License. + * In order to be useful for every potential user, curl and libcurl are + * dual-licensed under the MPL and the MIT/X-derivate licenses. * - * The Original Code is Curl. + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the MPL or the MIT/X-derivate + * licenses. You may pick one of these licenses. * - * The Initial Developer of the Original Code is Daniel Stenberg. + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. * - * Portions created by the Initial Developer are Copyright (C) 1998. - * All Rights Reserved. - * - * ------------------------------------------------------------ - * Main author: - * - Daniel Stenberg - * - * http://curl.haxx.se - * - * $Source$ - * $Revision$ - * $Date$ - * $Author$ - * $State$ - * $Locker$ - * - * ------------------------------------------------------------ - ****************************************************************************/ + * $Id$ + *****************************************************************************/ /* -- WIN32 approved -- */ -- cgit v1.2.1 From 4031104404c6ceed5e57134125dcdb6cac51c564 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Jan 2001 10:11:41 +0000 Subject: Internal symbols that aren't static are now prefixed with 'Curl_' --- lib/url.c | 146 +++++++++++++++++++++++--------------------------------------- 1 file changed, 55 insertions(+), 91 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b6a2848b1..3bd3c6ce2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -87,7 +87,6 @@ #include "if2ip.h" #include "download.h" #include "sendf.h" -#include "speedcheck.h" #include "getpass.h" #include "progress.h" #include "cookie.h" @@ -224,7 +223,7 @@ void static urlfree(struct UrlData *data, bool totally) /* the URL is allocated, free it! */ free(data->url); - cookie_cleanup(data->cookies); + Curl_cookie_cleanup(data->cookies); free(data); @@ -248,6 +247,7 @@ CURLcode curl_close(CURL *curl) return CURLE_OK; } +static int my_getpass(void *clientp, char *prompt, char* buffer, int buflen ) { char *retbuf; @@ -381,7 +381,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_COOKIEFILE: cookiefile = (char *)va_arg(param, void *); if(cookiefile) { - data->cookies = cookie_init(cookiefile); + data->cookies = Curl_cookie_init(cookiefile); } break; case CURLOPT_WRITEHEADER: @@ -533,50 +533,11 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) return CURLE_OK; } - -/* - * Read everything until a newline. - */ - -int GetLine(int sockfd, char *buf, struct UrlData *data) -{ - int nread; - int read_rc=1; - char *ptr; - ptr=buf; - - /* get us a full line, terminated with a newline */ - for(nread=0; - (nreadssl.use) { - read_rc = SSL_read(data->ssl.handle, ptr, 1); - } - else { -#endif - read_rc = sread(sockfd, ptr, 1); -#ifdef USE_SSLEAY - } -#endif /* USE_SSLEAY */ - if (*ptr == '\n') - break; - } - *ptr=0; /* zero terminate */ - - if(data->bits.verbose) { - fputs("< ", data->err); - fwrite(buf, 1, nread, data->err); - fputs("\n", data->err); - } - return nread; -} - - #ifndef WIN32 #ifndef RETSIGTYPE #define RETSIGTYPE void #endif +static RETSIGTYPE alarmfunc(int signal) { /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ @@ -865,9 +826,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) char *proxy=NULL; char proxy_env[128]; - no_proxy=GetEnv("no_proxy"); + no_proxy=curl_getenv("no_proxy"); if(!no_proxy) - no_proxy=GetEnv("NO_PROXY"); + no_proxy=curl_getenv("NO_PROXY"); if(!no_proxy || !strequal("*", no_proxy)) { /* NO_PROXY wasn't specified or it wasn't just an asterisk */ @@ -899,22 +860,22 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) strcpy(envp, "_proxy"); /* read the protocol proxy: */ - prox=GetEnv(proxy_env); + prox=curl_getenv(proxy_env); if(!prox) { /* There was no lowercase variable, try the uppercase version: */ for(envp = proxy_env; *envp; envp++) *envp = toupper(*envp); - prox=GetEnv(proxy_env); + prox=curl_getenv(proxy_env); } if(prox && *prox) { /* don't count "" strings */ proxy = prox; /* use this */ } else { - proxy = GetEnv("all_proxy"); /* default proxy to use */ + proxy = curl_getenv("all_proxy"); /* default proxy to use */ if(!proxy) - proxy=GetEnv("ALL_PROXY"); + proxy=curl_getenv("ALL_PROXY"); } if(proxy && *proxy) { @@ -935,7 +896,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) */ char *reurl; - reurl = maprintf("%s://%s", conn->proto, data->url); + reurl = aprintf("%s://%s", conn->proto, data->url); if(!reurl) return CURLE_OUT_OF_MEMORY; @@ -984,9 +945,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->port = PORT_HTTP; data->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; - conn->curl_do = http; - conn->curl_done = http_done; - conn->curl_close = http_close; + conn->curl_do = Curl_http; + conn->curl_done = Curl_http_done; + conn->curl_close = Curl_http_close; } else if (strequal(conn->proto, "HTTPS")) { #ifdef USE_SSLEAY @@ -996,10 +957,10 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->protocol |= PROT_HTTP; conn->protocol |= PROT_HTTPS; - conn->curl_do = http; - conn->curl_done = http_done; - conn->curl_connect = http_connect; - conn->curl_close = http_close; + conn->curl_do = Curl_http; + conn->curl_done = Curl_http_done; + conn->curl_connect = Curl_http_connect; + conn->curl_close = Curl_http_close; #else /* USE_SSLEAY */ failf(data, "libcurl was built with SSL disabled, https: not supported!"); @@ -1017,9 +978,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->ppath = conn->path; } conn->protocol |= PROT_GOPHER; - conn->curl_do = http; - conn->curl_done = http_done; - conn->curl_close = http_close; + conn->curl_do = Curl_http; + conn->curl_done = Curl_http_done; + conn->curl_close = Curl_http_close; } else if(strequal(conn->proto, "FTP")) { char *type; @@ -1032,14 +993,14 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) !data->bits.tunnel_thru_httpproxy) { /* Unless we have asked to tunnel ftp operations through the proxy, we switch and use HTTP operations only */ - conn->curl_do = http; - conn->curl_done = http_done; - conn->curl_close = http_close; + conn->curl_do = Curl_http; + conn->curl_done = Curl_http_done; + conn->curl_close = Curl_http_close; } else { - conn->curl_do = ftp; - conn->curl_done = ftp_done; - conn->curl_connect = ftp_connect; + conn->curl_do = Curl_ftp; + conn->curl_done = Curl_ftp_done; + conn->curl_connect = Curl_ftp_connect; } conn->ppath++; /* don't include the initial slash */ @@ -1076,8 +1037,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->port = PORT_TELNET; data->remote_port = PORT_TELNET; - conn->curl_do = telnet; - conn->curl_done = telnet_done; + conn->curl_do = Curl_telnet; + conn->curl_done = Curl_telnet_done; } else if (strequal(conn->proto, "DICT")) { @@ -1085,16 +1046,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) if(!data->port) data->port = PORT_DICT; data->remote_port = PORT_DICT; - conn->curl_do = dict; - conn->curl_done = dict_done; + conn->curl_do = Curl_dict; + conn->curl_done = Curl_dict_done; } else if (strequal(conn->proto, "LDAP")) { conn->protocol |= PROT_LDAP; if(!data->port) data->port = PORT_LDAP; data->remote_port = PORT_LDAP; - conn->curl_do = ldap; - conn->curl_done = ldap_done; + conn->curl_do = Curl_ldap; + conn->curl_done = Curl_ldap_done; } else if (strequal(conn->proto, "FILE")) { conn->protocol |= PROT_FILE; @@ -1114,7 +1075,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } if(data->bits.use_netrc) { - if(ParseNetrc(data->hostname, data->user, data->passwd)) { + if(Curl_parsenetrc(data->hostname, data->user, data->passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", data->hostname); } @@ -1196,7 +1157,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->remote_port = data->port; /* it is the same port */ /* Connect to target host right on */ - conn->hp = GetHost(data, conn->name, &conn->hostent_buf); + conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); if(!conn->hp) { failf(data, "Couldn't resolve host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; @@ -1252,7 +1213,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } /* connect to proxy */ - conn->hp = GetHost(data, proxyptr, &conn->hostent_buf); + conn->hp = Curl_gethost(data, proxyptr, &conn->hostent_buf); if(!conn->hp) { failf(data, "Couldn't resolve proxy '%s'", proxyptr); return CURLE_COULDNT_RESOLVE_PROXY; @@ -1260,7 +1221,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) free(proxydup); /* free the duplicate pointer and not the modified */ } - pgrsTime(data, TIMER_NAMELOOKUP); + Curl_pgrsTime(data, TIMER_NAMELOOKUP); data->firstsocket = socket(AF_INET, SOCK_STREAM, 0); @@ -1292,12 +1253,12 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) char myhost[256] = ""; unsigned long in; - if(if2ip(data->device, myhost, sizeof(myhost))) { - h = GetHost(data, myhost, &hostdataptr); + if(Curl_if2ip(data->device, myhost, sizeof(myhost))) { + h = Curl_gethost(data, myhost, &hostdataptr); } else { if(strlen(data->device)>1) { - h = GetHost(data, data->device, &hostdataptr); + h = Curl_gethost(data, data->device, &hostdataptr); } if(h) { /* we know data->device is shorter than the myhost array */ @@ -1307,7 +1268,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) if(! *myhost) { /* need to fix this - h=GetHost(data, + h=Curl_gethost(data, getmyhost(*myhost,sizeof(myhost)), hostent_buf, sizeof(hostent_buf)); @@ -1384,7 +1345,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } if(hostdataptr) - free(hostdataptr); /* allocated by GetHost() */ + free(hostdataptr); /* allocated by Curl_gethost() */ } /* end of device selection support */ #endif /* end of HAVE_INET_NTOA */ @@ -1443,32 +1404,35 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) char *authorization; snprintf(data->buffer, BUFSIZE, "%s:%s", data->proxyuser, data->proxypasswd); - if(base64_encode(data->buffer, strlen(data->buffer), - &authorization) >= 0) { + if(Curl_base64_encode(data->buffer, strlen(data->buffer), + &authorization) >= 0) { data->ptr_proxyuserpwd = - maprintf("Proxy-authorization: Basic %s\015\012", authorization); + aprintf("Proxy-authorization: Basic %s\015\012", authorization); free(authorization); } } if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) { if(data->useragent) { - data->ptr_uagent = maprintf("User-Agent: %s\015\012", data->useragent); + data->ptr_uagent = + aprintf("User-Agent: %s\015\012", data->useragent); } } if(conn->curl_connect) { /* is there a connect() procedure? */ - conn->now = tvnow(); /* set this here for timeout purposes in the - connect procedure, it is later set again for the - progress meter purpose */ + + /* set start time here for timeout purposes in the + connect procedure, it is later set again for the + progress meter purpose */ + conn->now = Curl_tvnow(); result = conn->curl_connect(conn); if(result != CURLE_OK) return result; /* pass back errors */ } - pgrsTime(data, TIMER_CONNECT); /* we're connected */ + Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */ - conn->now = tvnow(); /* time this *after* the connect is done */ + conn->now = Curl_tvnow(); /* time this *after* the connect is done */ conn->bytecount = 0; /* Figure out the ip-number and the first host name it shows: */ @@ -1560,7 +1524,7 @@ CURLcode curl_done(CURLconnect *c_connect) else result = CURLE_OK; - pgrsDone(data); /* done with the operation */ + Curl_pgrsDone(data); /* done with the operation */ conn->state = CONN_DONE; -- cgit v1.2.1 From ae0a6835bdd6c54e56ce16b7a2727ada3adcccaf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 17 Jan 2001 13:23:01 +0000 Subject: Transfer is now Curl_Tranfer() and transfer.h is used instead of highlevel.h and download.h --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3bd3c6ce2..ab50613a3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -85,7 +85,7 @@ #include "ssluse.h" #include "hostip.h" #include "if2ip.h" -#include "download.h" +#include "transfer.h" #include "sendf.h" #include "getpass.h" #include "progress.h" @@ -1063,7 +1063,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->curl_do = file; /* no done() function */ - result = Transfer(conn, -1, -1, FALSE, NULL, /* no download */ + result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ -1, NULL); /* no upload */ return CURLE_OK; -- cgit v1.2.1 From 7872cc131aab3db9ca694264fc4ebb1308b26368 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 23 Jan 2001 10:21:30 +0000 Subject: Enabled support for IPv6-style IP-addresses if ENABLE_IPV6 is set. If it isn't, curl will return an error when such an address is used. --- lib/url.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ab50613a3..4c990d28c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -635,6 +635,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) char resumerange[40]=""; struct UrlData *data = curl; struct connectdata *conn; + char endbracket; #ifdef HAVE_SIGACTION struct sigaction sigact; #endif @@ -1146,15 +1147,40 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } } + /* No matter if we use a proxy or not, we have to figure out the remote + port number of various reasons. + + To be able to detect port number flawlessly, we must not confuse them + IPv6-specified addresses in the [0::1] style. + */ + if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:]%c", &endbracket)) && + (']' == endbracket)) { + /* this is a IPv6-style specified IP-address */ +#ifndef ENABLE_IPV6 + failf(data, "You haven't enabled IPv6 support"); + return CURLE_URL_MALFORMAT; +#else + tmp = strchr(conn->name, ']'); + + tmp++; /* pass the ending bracket */ + if(':' != *tmp) + tmp = NULL; /* no port number available */ +#endif + } + else { + /* traditional IPv4-style port-extracting */ + tmp = strchr(conn->name, ':'); + } + + if (tmp) { + *tmp++ = '\0'; /* cut off the name there */ + data->remote_port = atoi(tmp); + } + if(!data->bits.httpproxy) { /* 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. */ - tmp = strchr(conn->name, ':'); - if (tmp) { - *tmp++ = '\0'; - data->port = atoi(tmp); - } - data->remote_port = data->port; /* it is the same port */ + data->port = data->remote_port; /* it is the same port */ /* Connect to target host right on */ conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); @@ -1179,14 +1205,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_OUT_OF_MEMORY; } - /* we use proxy all right, but we wanna know the remote port for SSL - reasons */ - tmp = strchr(conn->name, ':'); - if (tmp) { - *tmp++ = '\0'; /* cut off the name there */ - data->remote_port = atoi(tmp); - } - /* Daniel Dec 10, 1998: We do the proxy host string parsing here. We want the host name and the port name. Accept a protocol:// prefix, even though it should just be -- cgit v1.2.1 From 8a75120568c0eccdbfb7412b5053875491f1af61 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Jan 2001 12:32:34 +0000 Subject: added comments all over --- lib/url.c | 198 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 134 insertions(+), 64 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4c990d28c..06f18afff 100644 --- a/lib/url.c +++ b/lib/url.c @@ -641,12 +641,19 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #endif int urllen; + /************************************************************* + * Check input data + *************************************************************/ + if(!data || (data->handle != STRUCT_OPEN)) return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ if(!data->url) return CURLE_URL_MALFORMAT; + /************************************************************* + * Allocate and initiate a connection struct + *************************************************************/ conn = (struct connectdata *)malloc(sizeof(struct connectdata)); if(!conn) { *in_connect = NULL; /* clear the pointer */ @@ -665,6 +672,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) buf = data->buffer; /* this is our buffer */ + /************************************************************* + * Set signal handler + *************************************************************/ #ifdef HAVE_SIGACTION sigaction(SIGALRM, NULL, &sigact); sigact.sa_handler = alarmfunc; @@ -681,9 +691,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #endif - /* We need to allocate memory to store the path in. We get the size of the - full URL to be sure, and we need to make it at least 256 bytes since - other parts of the code will rely on this fact */ + /*********************************************************** + * We need to allocate memory to store the path in. We get the size of the + * full URL to be sure, and we need to make it at least 256 bytes since + * other parts of the code will rely on this fact + ***********************************************************/ #define LEAST_PATH_ALLOC 256 urllen=strlen(data->url); if(urllen < LEAST_PATH_ALLOC) @@ -693,25 +705,30 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) if(NULL == conn->path) return CURLE_OUT_OF_MEMORY; /* really bad error */ - /* Parse */ - /* We need to parse the url, even when using the proxy, because - * we will need the hostname and port in case we are trying - * to SSL connect through the proxy -- and we don't know if we - * will need to use SSL until we parse the url ... - */ + /************************************************************* + * Parse the URL. + * + * We need to parse the url even when using the proxy, because we will need + * the hostname and port in case we are trying to SSL connect through the + * 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]", conn->proto, conn->path)) && strequal(conn->proto, "file")) { - /* we deal with file:/// differently since it - supports no hostname other than "localhost" and "127.0.0.1", - which is unique among the protocols specified in RFC 1738 */ + /* + * we deal with file:/// differently since it supports no + * hostname other than "localhost" and "127.0.0.1", which is unique among + * the URL protocols specified in RFC 1738 + */ + if (strnequal(conn->path, "localhost/", 10) || strnequal(conn->path, "127.0.0.1/", 10)) - /* ... since coincidentally both host strings are of equal length - otherwise, / is quietly ommitted */ + /* If there's another host name than the one we support, / is + * quietly ommitted */ strcpy(conn->path, &conn->path[10]); - strcpy(conn->proto, "file"); + strcpy(conn->proto, "file"); /* store protocol string lowercase */ } else { /* Set default host and default path */ @@ -722,12 +739,24 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) "%64[^\n:]://%256[^\n/]%[^\n]", conn->proto, conn->gname, conn->path)) { - /* badly formatted, let's try the browser-style _without_ 'http://' */ + /* + * The URL was badly formatted, let's try the browser-style _without_ + * protocol specified like 'http://'. + */ if((1 > sscanf(data->url, "%256[^\n/]%[^\n]", conn->gname, conn->path)) ) { + /* + * We couldn't even get this format. + */ failf(data, " malformed"); return CURLE_URL_MALFORMAT; } + + /* + * Since there was no protocol part specified, we guess what protocol it + * is based on the first letters of the server name. + */ + if(strnequal(conn->gname, "FTP", 3)) { strcpy(conn->proto, "ftp"); } @@ -751,6 +780,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } } + /************************************************************* + * Take care of user and password authentication stuff + *************************************************************/ if(data->bits.user_passwd && !data->bits.use_netrc) { data->user[0] =0; @@ -774,6 +806,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } } + /************************************************************* + * Take care of proxy authentication stuff + *************************************************************/ if(data->bits.proxy_user_passwd) { data->proxyuser[0] =0; data->proxypasswd[0]=0; @@ -799,30 +834,36 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } + /************************************************************* + * Set a few convenience pointers + *************************************************************/ conn->name = conn->gname; conn->ppath = conn->path; data->hostname = conn->name; + /************************************************************* + * Detect what (if any) proxy to use + *************************************************************/ if(!data->bits.httpproxy) { /* If proxy was not specified, we check for default proxy environment - variables, to enable i.e Lynx compliance: - - http_proxy=http://some.server.dom:port/ - https_proxy=http://some.server.dom:port/ - ftp_proxy=http://some.server.dom:port/ - gopher_proxy=http://some.server.dom:port/ - no_proxy=domain1.dom,host.domain2.dom - (a comma-separated list of hosts which should - not be proxied, or an asterisk to override - all proxy variables) - all_proxy=http://some.server.dom:port/ - (seems to exist for the CERN www lib. Probably - the first to check for.) - - For compatibility, the all-uppercase versions of these variables are - checked if the lowercase versions don't exist. - */ + * variables, to enable i.e Lynx compliance: + * + * http_proxy=http://some.server.dom:port/ + * https_proxy=http://some.server.dom:port/ + * ftp_proxy=http://some.server.dom:port/ + * gopher_proxy=http://some.server.dom:port/ + * no_proxy=domain1.dom,host.domain2.dom + * (a comma-separated list of hosts which should + * not be proxied, or an asterisk to override + * all proxy variables) + * all_proxy=http://some.server.dom:port/ + * (seems to exist for the CERN www lib. Probably + * the first to check for.) + * + * For compatibility, the all-uppercase versions of these variables are + * checked if the lowercase versions don't exist. + */ char *no_proxy=NULL; char *proxy=NULL; char proxy_env[128]; @@ -891,6 +932,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) free(no_proxy); } /* if not using proxy */ + /************************************************************* + * No protocol but proxy usage needs attention + *************************************************************/ if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) { /* 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! @@ -910,13 +954,15 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } - /* RESUME on a HTTP page is a tricky business. First, let's just check that - 'range' isn't used, then set the range parameter and leave the resume as - it is to inform about this situation for later use. We will then - "attempt" to resume, and if we're talking to a HTTP/1.1 (or later) - server, we will get the document resumed. If we talk to a HTTP/1.0 - server, we just fail since we can't rewind the file writing from within - this function. */ + /************************************************************ + * RESUME on a HTTP page is a tricky business. First, let's just check that + * 'range' isn't used, then set the range parameter and leave the resume as + * it is to inform about this situation for later use. We will then + * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later) + * server, we will get the document resumed. If we talk to a HTTP/1.0 + * server, we just fail since we can't rewind the file writing from within + * this function. + ***********************************************************/ if(data->resume_from) { if(!data->bits.set_range) { /* if it already was in use, we just skip this */ @@ -927,19 +973,19 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } } - + /************************************************************* + * Set timeout if that is being used + *************************************************************/ if(data->timeout) { /* We set the timeout on the connection/resolving phase first, separately - from the download/upload part to allow a maximum time on everything */ + * from the download/upload part to allow a maximum time on everything */ myalarm(data->timeout); /* this sends a signal when the timeout fires off, and that will abort system calls */ } - /* - * Hmm, if we are using a proxy, then we can skip the GOPHER and the - * FTP steps, although we cannot skip the HTTPS step (since the proxy - * works differently, depending on whether its SSL or not). - */ + /************************************************************* + * Setup internals depending on protocol + *************************************************************/ if (strequal(conn->proto, "HTTP")) { if(!data->port) @@ -1007,7 +1053,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->ppath++; /* don't include the initial slash */ /* FTP URLs support an extension like ";type=" that - we'll try to get now! */ + * we'll try to get now! */ type=strstr(conn->ppath, ";type="); if(!type) { type=strstr(conn->gname, ";type="); @@ -1069,12 +1115,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_OK; } - else { + /* We fell through all checks and thus we don't support the specified + protocol */ failf(data, "Unsupported protocol: %s", conn->proto); return CURLE_UNSUPPORTED_PROTOCOL; } + /************************************************************* + * .netrc scanning coming up + *************************************************************/ if(data->bits.use_netrc) { if(Curl_parsenetrc(data->hostname, data->user, data->passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", @@ -1093,9 +1143,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) else if(!(data->bits.user_passwd) && (conn->protocol & (PROT_FTP|PROT_HTTP)) ) { /* This is a FTP or HTTP URL, and we haven't got the user+password in - the extra parameter, we will now try to extract the possible - user+password pair in a string like: - ftp://user:password@ftp.my.site:8021/README */ + * the extra parameter, 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=NULL; /* assign to remove possible warnings */ if((ptr=strchr(conn->name, '@'))) { /* there's a user+password given here, to the left of the @ */ @@ -1147,12 +1197,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } } - /* No matter if we use a proxy or not, we have to figure out the remote - port number of various reasons. - - To be able to detect port number flawlessly, we must not confuse them - IPv6-specified addresses in the [0::1] style. - */ + /************************************************************* + * Figure out the remote port number + * + * No matter if we use a proxy or not, we have to figure out the remote + * port number of various reasons. + * + * To be able to detect port number flawlessly, we must not confuse them + * IPv6-specified addresses in the [0::1] style. + *************************************************************/ + if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:]%c", &endbracket)) && (']' == endbracket)) { /* this is a IPv6-style specified IP-address */ @@ -1177,6 +1231,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->remote_port = atoi(tmp); } + /************************************************************* + * Resolve the name of the server or proxy + *************************************************************/ if(!data->bits.httpproxy) { /* 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. */ @@ -1254,15 +1311,15 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) HAVE_XXXX based, although at the moment I don't have a decent test for this! */ - /* sck 8/31/2000 add support for specifing device to bind socket to */ - /* I am using this, but it may not work everywhere, only tested on - RedHat 6.2 */ #ifdef HAVE_INET_NTOA #ifndef INADDR_NONE #define INADDR_NONE (unsigned long) ~0 #endif + /************************************************************* + * Select device to bind socket to + *************************************************************/ if (data->device && (strlen(data->device)<255)) { struct sockaddr_in sa; struct hostent *h=NULL; @@ -1369,6 +1426,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #endif /* end of HAVE_INET_NTOA */ #endif /* end of not WIN32 */ + /************************************************************* + * Connect to server/proxy + *************************************************************/ if (connect(data->firstsocket, (struct sockaddr *) &(conn->serv_addr), sizeof(conn->serv_addr) @@ -1418,6 +1478,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_COULDNT_CONNECT; } + /************************************************************* + * Proxy authentication + *************************************************************/ if(data->bits.proxy_user_passwd) { char *authorization; snprintf(data->buffer, BUFSIZE, "%s:%s", @@ -1429,6 +1492,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) free(authorization); } } + + /************************************************************* + * 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) { data->ptr_uagent = @@ -1440,9 +1508,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) /* is there a connect() procedure? */ /* set start time here for timeout purposes in the - connect procedure, it is later set again for the - progress meter purpose */ + * connect procedure, it is later set again for the + * progress meter purpose */ conn->now = Curl_tvnow(); + + /* Call the protocol-specific connect function */ result = conn->curl_connect(conn); if(result != CURLE_OK) return result; /* pass back errors */ @@ -1453,7 +1523,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->now = Curl_tvnow(); /* time this *after* the connect is done */ conn->bytecount = 0; - /* Figure out the ip-number and the first host name it shows: */ + /* Figure out the ip-number and display the first host name it shows: */ { struct in_addr in; (void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr)); -- cgit v1.2.1 From 29bcba9a9075265cefd967a1dfdbac50a6958245 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Jan 2001 14:44:05 +0000 Subject: Ingo Ralf Blum's cygwin fixes --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 06f18afff..dc825cce7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -533,7 +533,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) return CURLE_OK; } -#ifndef WIN32 +#if !defined(WIN32)||defined(__CYGWIN32__) #ifndef RETSIGTYPE #define RETSIGTYPE void #endif @@ -1306,7 +1306,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->serv_addr.sin_family = conn->hp->h_addrtype; conn->serv_addr.sin_port = htons(data->port); -#ifndef WIN32 +#if !defined(WIN32)||defined(__CYGWIN32__) /* We don't generally like checking for OS-versions, we should make this HAVE_XXXX based, although at the moment I don't have a decent test for this! */ -- cgit v1.2.1 From 30eab8ca515b36985346953cf7988144ccdfb8f9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 25 Jan 2001 12:23:57 +0000 Subject: moved curl_read() and curl_write() to sendf.c --- lib/url.c | 61 ------------------------------------------------------------- 1 file changed, 61 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dc825cce7..30cc64ffc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -546,67 +546,6 @@ RETSIGTYPE alarmfunc(int signal) } #endif -CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount, - size_t *n) -{ - struct connectdata *conn = (struct connectdata *)c_conn; - struct UrlData *data; - size_t bytes_written; - - if(!n || !conn || (conn->handle != STRUCT_CONNECT)) - return CURLE_FAILED_INIT; - data = conn->data; - -#ifdef USE_SSLEAY - if (data->ssl.use) { - bytes_written = SSL_write(data->ssl.handle, buf, amount); - } - else { -#endif -#ifdef KRB4 - if(conn->sec_complete) - bytes_written = sec_write(conn, conn->writesockfd, buf, amount); - else -#endif - bytes_written = swrite(conn->writesockfd, buf, amount); -#ifdef USE_SSLEAY - } -#endif /* USE_SSLEAY */ - - *n = bytes_written; - return CURLE_OK; -} - -CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize, - size_t *n) -{ - struct connectdata *conn = (struct connectdata *)c_conn; - struct UrlData *data; - size_t nread; - - if(!n || !conn || (conn->handle != STRUCT_CONNECT)) - return CURLE_FAILED_INIT; - data = conn->data; - -#ifdef USE_SSLEAY - if (data->ssl.use) { - nread = SSL_read (data->ssl.handle, buf, buffersize); - } - else { -#endif -#ifdef KRB4 - if(conn->sec_complete) - nread = sec_read(conn, conn->sockfd, buf, buffersize); - else -#endif - nread = sread (conn->sockfd, buf, buffersize); -#ifdef USE_SSLEAY - } -#endif /* USE_SSLEAY */ - *n = nread; - return CURLE_OK; -} - CURLcode curl_disconnect(CURLconnect *c_connect) { struct connectdata *conn = c_connect; -- cgit v1.2.1 From fcb347d1249df552ef37faf47e2a15dbed5e7ce5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 26 Jan 2001 15:52:01 +0000 Subject: Added a httpreq field in the main struct so that there's one field to check for what HTTP request that is being used. The old bit-style fields are still in there as well. --- lib/url.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 30cc64ffc..7a69ff691 100644 --- a/lib/url.c +++ b/lib/url.c @@ -301,6 +301,8 @@ CURLcode curl_open(CURL **curl, char *url) data->current_speed = -1; /* init to negative == impossible */ + data->httpreq = HTTPREQ_GET; /* Default HTTP request */ + *curl = data; return CURLE_OK; } @@ -340,6 +342,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_POST: data->bits.http_post = va_arg(param, long)?TRUE:FALSE; + data->httpreq = HTTPREQ_POST; break; case CURLOPT_FILETIME: data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE; @@ -361,19 +364,17 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_PUT: data->bits.http_put = va_arg(param, long)?TRUE:FALSE; + data->httpreq = HTTPREQ_PUT; break; case CURLOPT_MUTE: data->bits.mute = va_arg(param, long)?TRUE:FALSE; break; - case CURLOPT_TIMECONDITION: data->timecondition = va_arg(param, long); break; - case CURLOPT_TIMEVALUE: data->timevalue = va_arg(param, long); break; - case CURLOPT_SSLVERSION: data->ssl.version = va_arg(param, long); break; @@ -405,10 +406,12 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_CUSTOMREQUEST: data->customrequest = va_arg(param, char *); + data->httpreq = HTTPREQ_CUSTOM; break; case CURLOPT_HTTPPOST: data->httppost = va_arg(param, struct HttpPost *); data->bits.http_formpost = data->httppost?1:0; + data->httpreq = HTTPREQ_POST_FORM; break; case CURLOPT_INFILE: data->in = va_arg(param, FILE *); -- cgit v1.2.1 From 62fec1d28d6fb3b9f747f4bc0134ea31e4c18797 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 27 Jan 2001 17:58:15 +0000 Subject: data->httpreq was not set properly --- lib/url.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7a69ff691..58965123a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -342,7 +342,8 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_POST: data->bits.http_post = va_arg(param, long)?TRUE:FALSE; - data->httpreq = HTTPREQ_POST; + if(data->bits.http_post) + data->httpreq = HTTPREQ_POST; break; case CURLOPT_FILETIME: data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE; @@ -364,7 +365,8 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_PUT: data->bits.http_put = va_arg(param, long)?TRUE:FALSE; - data->httpreq = HTTPREQ_PUT; + if(data->bits.http_put) + data->httpreq = HTTPREQ_PUT; break; case CURLOPT_MUTE: data->bits.mute = va_arg(param, long)?TRUE:FALSE; @@ -406,12 +408,14 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_CUSTOMREQUEST: data->customrequest = va_arg(param, char *); - data->httpreq = HTTPREQ_CUSTOM; + if(data->customrequest) + data->httpreq = HTTPREQ_CUSTOM; break; case CURLOPT_HTTPPOST: data->httppost = va_arg(param, struct HttpPost *); data->bits.http_formpost = data->httppost?1:0; - data->httpreq = HTTPREQ_POST_FORM; + if(data->bits.http_formpost) + data->httpreq = HTTPREQ_POST_FORM; break; case CURLOPT_INFILE: data->in = va_arg(param, FILE *); -- cgit v1.2.1 From 4cc76d157673c46434a5d3f59b2e61b85ca9e756 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 Jan 2001 07:23:11 +0000 Subject: upload sets HTTP request to PUT for "HTTP upload" --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 58965123a..e37f24163 100644 --- a/lib/url.c +++ b/lib/url.c @@ -339,6 +339,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_UPLOAD: data->bits.upload = va_arg(param, long)?TRUE:FALSE; + if(data->bits.upload) + /* If this is HTTP, PUT is what's needed to "upload" */ + data->httpreq = HTTPREQ_PUT; break; case CURLOPT_POST: data->bits.http_post = va_arg(param, long)?TRUE:FALSE; -- cgit v1.2.1 From f6e2bfd464a7ffd7ec24194da2a9a1e285387560 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Feb 2001 23:04:44 +0000 Subject: Jun-ichiro itojun Hagino's IPv6 adjustments --- lib/url.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e37f24163..98d41acb7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -562,8 +562,13 @@ CURLcode curl_disconnect(CURLconnect *c_connect) struct UrlData *data = conn->data; +#ifdef ENABLE_IPV6 + if(conn->res) /* host name info */ + freeaddrinfo(conn->res); +#else if(conn->hostent_buf) /* host name info */ free(conn->hostent_buf); +#endif if(conn->path) /* the URL path part */ free(conn->path); @@ -589,6 +594,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) struct sigaction sigact; #endif int urllen; +#ifdef ENABLE_IPV6 + struct addrinfo *ai; +#endif /************************************************************* * Check input data @@ -1189,13 +1197,23 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->port = data->remote_port; /* it is the same port */ /* Connect to target host right on */ +#ifdef ENABLE_IPV6 + conn->res = Curl_getaddrinfo(data, conn->name, data->port); + if(!conn->res) +#else conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); - if(!conn->hp) { + if(!conn->hp) +#endif + { failf(data, "Couldn't resolve host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; } } else { +#ifdef ENABLE_IPV6 + failf(data, "proxy yet to be supported"); + return CURLE_OUT_OF_MEMORY; +#else char *prox_portno; char *endofprot; @@ -1244,9 +1262,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } free(proxydup); /* free the duplicate pointer and not the modified */ +#endif } Curl_pgrsTime(data, TIMER_NAMELOOKUP); +#ifndef ENABLE_IPV6 data->firstsocket = socket(AF_INET, SOCK_STREAM, 0); memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); @@ -1254,6 +1274,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->hp->h_addr, conn->hp->h_length); conn->serv_addr.sin_family = conn->hp->h_addrtype; conn->serv_addr.sin_port = htons(data->port); +#endif #if !defined(WIN32)||defined(__CYGWIN32__) /* We don't generally like checking for OS-versions, we should make this @@ -1266,6 +1287,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #define INADDR_NONE (unsigned long) ~0 #endif +#ifndef ENABLE_IPV6 /************************************************************* * Select device to bind socket to *************************************************************/ @@ -1374,10 +1396,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } /* end of device selection support */ #endif /* end of HAVE_INET_NTOA */ #endif /* end of not WIN32 */ +#endif /*ENABLE_IPV6*/ /************************************************************* * Connect to server/proxy *************************************************************/ +#ifdef ENABLE_IPV6 + data->firstsocket = -1; + for (ai = conn->res; ai; ai = ai->ai_next) { + data->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (data->firstsocket < 0) + continue; + + if (connect(data->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { + close(data->firstsocket); + data->firstsocket = -1; + continue; + } + + break; + } + if (data->firstsocket < 0) { + failf(data, strerror(errno)); + return CURLE_COULDNT_CONNECT; + } +#else if (connect(data->firstsocket, (struct sockaddr *) &(conn->serv_addr), sizeof(conn->serv_addr) @@ -1426,6 +1469,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } return CURLE_COULDNT_CONNECT; } +#endif /************************************************************* * Proxy authentication @@ -1473,11 +1517,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->bytecount = 0; /* Figure out the ip-number and display the first host name it shows: */ +#ifdef ENABLE_IPV6 + { + char hbuf[NI_MAXHOST]; +#ifdef NI_WITHSCOPEID + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; +#else + const int niflags = NI_NUMERICHOST; +#endif + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, + niflags)) { + snprintf(hbuf, sizeof(hbuf), "?"); + } + if (ai->ai_canonname) { + infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf); + } else { + infof(data, "Connected to %s\n", hbuf); + } + } +#else { struct in_addr in; (void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr)); infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in)); } +#endif #ifdef __EMX__ /* 20000330 mgs @@ -1509,8 +1573,13 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(conn) { if(conn->path) free(conn->path); +#ifdef ENABLE_IPV6 + if(conn->res) + freeaddrinfo(conn->res); +#else if(conn->hostent_buf) free(conn->hostent_buf); +#endif free(conn); *in_connect=NULL; } -- cgit v1.2.1 From 58d70db92e2a43387697eeb2d15f1574521c9d41 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Feb 2001 08:36:23 +0000 Subject: no longer #includes "getenv.h" --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 98d41acb7..74a69050a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -80,7 +80,6 @@ #include "netrc.h" #include "formdata.h" -#include "getenv.h" #include "base64.h" #include "ssluse.h" #include "hostip.h" -- cgit v1.2.1 From b12e334d83c0ad2a342eeb14c1cecf314915830f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 8 Feb 2001 13:53:13 +0000 Subject: if netrc is parsed and our host was found in there, set data->bits.user_passwd unconditioanlly! --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 74a69050a..83aa6e3b2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1086,15 +1086,15 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) infof(data, "Couldn't find host %s in the .netrc file, using defaults", data->hostname); } + else + data->bits.user_passwd = 1; /* enable user+password */ + /* 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(conn->protocol&PROT_HTTP) { - data->bits.user_passwd = 1; /* enable user+password */ - } } else if(!(data->bits.user_passwd) && (conn->protocol & (PROT_FTP|PROT_HTTP)) ) { -- cgit v1.2.1 From c107303ade3a18aced62fdf241d1a0e4c4618667 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Feb 2001 08:22:19 +0000 Subject: very minor indentation fix --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 83aa6e3b2..2348ac2d6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -748,7 +748,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) /* the name is given, get user+password */ sscanf(data->userpwd, "%127[^:]:%127[^\n]", data->user, data->passwd); - } + } else /* no name given, get the password only */ sscanf(data->userpwd+1, "%127[^\n]", data->passwd); -- cgit v1.2.1 From a140e5311d4cc2dd72a172443643839723b30bde Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Feb 2001 13:34:16 +0000 Subject: moved the protocol-specific free to allow easier multiple transfers --- lib/url.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2348ac2d6..7fe2fc1e9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -561,6 +561,10 @@ CURLcode curl_disconnect(CURLconnect *c_connect) struct UrlData *data = conn->data; + if(data->proto.generic) + free(data->proto.generic); + data->proto.generic=NULL; /* it is gone */ + #ifdef ENABLE_IPV6 if(conn->res) /* host name info */ freeaddrinfo(conn->res); @@ -1644,7 +1648,13 @@ CURLcode curl_do(CURLconnect *in_conn) if(!conn || (conn->handle!= STRUCT_CONNECT)) { return CURLE_BAD_FUNCTION_ARGUMENT; } - if(conn->state != CONN_INIT) { + switch(conn->state) { + case CONN_INIT: + case CONN_DONE: + /* these two states are OK */ + break; + default: + /* anything else is bad */ return CURLE_BAD_CALLING_ORDER; } -- cgit v1.2.1 From ce95d2020f8b4f98644a685aec2ded8eca52c2f1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Feb 2001 21:57:04 +0000 Subject: better english timeouted => timed out, as suggested by Larry Fahnoe --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7fe2fc1e9..0c5767913 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1464,7 +1464,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) break; #endif case EINTR: - failf(data, "Connection timeouted"); + failf(data, "Connection timed out"); break; default: failf(data, "Can't connect to server: %d", errno); -- cgit v1.2.1 From f7a890937244d936f5224a4d1666d9a08d9c1f42 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 19 Feb 2001 09:29:19 +0000 Subject: Made CURLOPT_POST no longer necessary when CURLOPT_POSTFIELDS is used --- lib/url.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0c5767913..d4b33e828 100644 --- a/lib/url.c +++ b/lib/url.c @@ -342,11 +342,6 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) /* If this is HTTP, PUT is what's needed to "upload" */ data->httpreq = HTTPREQ_PUT; break; - case CURLOPT_POST: - data->bits.http_post = va_arg(param, long)?TRUE:FALSE; - if(data->bits.http_post) - data->httpreq = HTTPREQ_POST; - break; case CURLOPT_FILETIME: data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE; break; @@ -437,8 +432,17 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) case CURLOPT_PORT: data->port = va_arg(param, long); break; + case CURLOPT_POST: + /* Does this option serve a purpose anymore? */ + data->bits.http_post = va_arg(param, long)?TRUE:FALSE; + if(data->bits.http_post) + data->httpreq = HTTPREQ_POST; + break; case CURLOPT_POSTFIELDS: data->postfields = va_arg(param, char *); + data->bits.http_post = data->postfields?TRUE:FALSE; + if(data->bits.http_post) + data->httpreq = HTTPREQ_POST; break; case CURLOPT_POSTFIELDSIZE: data->postfieldsize = va_arg(param, long); -- cgit v1.2.1 From a1d6ad26100bc493c7b04f1301b1634b7f5aa8b4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Feb 2001 17:35:51 +0000 Subject: multiple connection support initial commit --- lib/url.c | 877 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 526 insertions(+), 351 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d4b33e828..0dbf4ed16 100644 --- a/lib/url.c +++ b/lib/url.c @@ -113,11 +113,15 @@ #include "memdebug.h" #endif -/* -- -- */ +/* Local static prototypes */ +static int ConnectionKillOne(struct UrlData *data); +static bool ConnectionExists(struct UrlData *data, + struct connectdata *needle, + struct connectdata **usethis); +static unsigned int ConnectionStore(struct UrlData *data, + struct connectdata *conn); -CURLcode _urlget(struct UrlData *data); - /* does nothing, returns OK */ CURLcode curl_init(void) { @@ -129,34 +133,12 @@ void curl_free(void) { } -void static urlfree(struct UrlData *data, bool totally) +CURLcode curl_close(CURL *curl) { -#ifdef USE_SSLEAY - if (data->ssl.use) { - if(data->ssl.handle) { - (void)SSL_shutdown(data->ssl.handle); - SSL_set_connect_state(data->ssl.handle); - - SSL_free (data->ssl.handle); - data->ssl.handle = NULL; - } - if(data->ssl.ctx) { - SSL_CTX_free (data->ssl.ctx); - data->ssl.ctx = NULL; - } - data->ssl.use = FALSE; /* get back to ordinary socket usage */ - } -#endif /* USE_SSLEAY */ - - /* close possibly still open sockets */ - if(-1 != data->secondarysocket) { - sclose(data->secondarysocket); - data->secondarysocket = -1; - } - if(-1 != data->firstsocket) { - sclose(data->firstsocket); - data->firstsocket=-1; - } + struct UrlData *data=(struct UrlData *)curl; + + /* Loop through all open connections and kill them one by one */ + while(-1 != ConnectionKillOne(data)); if(data->bits.proxystringalloc) { data->bits.proxystringalloc=FALSE;; @@ -168,7 +150,8 @@ void static urlfree(struct UrlData *data, bool totally) switch off that knowledge again... */ data->bits.httpproxy=FALSE; } - + + if(data->bits.rangestringalloc) { free(data->range); data->range=NULL; @@ -204,44 +187,29 @@ void static urlfree(struct UrlData *data, bool totally) data->ptr_host=NULL; } - if(totally) { - /* we let the switch decide whether we're doing a part or total - cleanup */ - - /* check for allocated [URL] memory to free: */ - if(data->freethis) - free(data->freethis); - - if(data->headerbuff) - free(data->headerbuff); + /* check for allocated [URL] memory to free: */ + if(data->freethis) + free(data->freethis); - if(data->free_referer) - free(data->referer); + if(data->headerbuff) + free(data->headerbuff); - if(data->bits.urlstringalloc) - /* the URL is allocated, free it! */ - free(data->url); + if(data->free_referer) + free(data->referer); - Curl_cookie_cleanup(data->cookies); + if(data->bits.urlstringalloc) + /* the URL is allocated, free it! */ + free(data->url); - free(data); + Curl_cookie_cleanup(data->cookies); - /* global cleanup */ - curl_free(); - } -} + /* free the connection cache */ + free(data->connects); -CURLcode curl_close(CURL *curl) -{ - struct UrlData *data=(struct UrlData *)curl; - - void *protocol = data->proto.generic; + free(data); - /* total session cleanup (frees 'data' as well!)*/ - urlfree(data, TRUE); - - if(protocol) - free(protocol); + /* global cleanup */ + curl_free(); return CURLE_OK; } @@ -284,9 +252,6 @@ CURLcode curl_open(CURL **curl, char *url) data->in = stdin; /* default input from stdin */ data->err = stderr; /* default stderr to stderr */ - data->firstsocket = -1; /* no file descriptor */ - data->secondarysocket = -1; /* no file descriptor */ - /* use fwrite as default function to store output */ data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))fwrite; @@ -302,6 +267,18 @@ CURLcode curl_open(CURL **curl, char *url) data->httpreq = HTTPREQ_GET; /* Default HTTP request */ + /* 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); + + if(!data->connects) { + free(data); + return CURLE_OUT_OF_MEMORY; + } + + memset(data->connects, 0, sizeof(struct connectdata *)*data->numconnects); + *curl = data; return CURLE_OK; } @@ -539,6 +516,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->ssl.CAfile = va_arg(param, char *); data->ssl.CApath = NULL; /*This does not work on windows.*/ break; + case CURLOPT_TELNETOPTIONS: + data->telnet_options = va_arg(param, struct curl_slist *); + break; default: /* unknown tag and its companion, just ignore: */ return CURLE_READ_ERROR; /* correct this */ @@ -563,11 +543,8 @@ CURLcode curl_disconnect(CURLconnect *c_connect) { struct connectdata *conn = c_connect; - struct UrlData *data = conn->data; - - if(data->proto.generic) - free(data->proto.generic); - data->proto.generic=NULL; /* it is gone */ + if(conn->proto.generic) + free(conn->proto.generic); #ifdef ENABLE_IPV6 if(conn->res) /* host name info */ @@ -580,80 +557,407 @@ CURLcode curl_disconnect(CURLconnect *c_connect) if(conn->path) /* the URL path part */ free(conn->path); - free(conn); /* free the connection oriented data */ +#ifdef USE_SSLEAY + if (conn->ssl.use) { + if(conn->ssl.handle) { + (void)SSL_shutdown(conn->ssl.handle); + SSL_set_connect_state(conn->ssl.handle); - /* clean up the sockets and SSL stuff from the previous "round" */ - urlfree(data, FALSE); + SSL_free (conn->ssl.handle); + conn->ssl.handle = NULL; + } + if(conn->ssl.ctx) { + SSL_CTX_free (conn->ssl.ctx); + conn->ssl.ctx = NULL; + } + conn->ssl.use = FALSE; /* get back to ordinary socket usage */ + } +#endif /* USE_SSLEAY */ + + /* 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; + } + + free(conn); /* free all the connection oriented data */ return CURLE_OK; } -static CURLcode _connect(CURL *curl, CURLconnect **in_connect) +/* + * Given one filled in connection struct, this function should detect if there + * already is one that have all the significant details exactly the same and + * thus should be used instead. + */ +static bool +ConnectionExists(struct UrlData *data, + struct connectdata *needle, + struct connectdata **usethis) { - char *tmp; - char *buf; - CURLcode result; - char resumerange[40]=""; - struct UrlData *data = curl; + size_t i; + struct connectdata *check; + + for(i=0; i< data->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]; + if(!check) + /* NULL pointer means not filled-in entry */ + continue; + if(strequal(needle->protostr, check->protostr) && + strequal(needle->name, check->name) && + (needle->port == check->port) ) { + *usethis = check; + return TRUE; /* yes, we found one to use! */ + } + } + return FALSE; /* no matching connecting exists */ +} + +/* + * This function frees/closes a connection in the connection cache. This + * should take the previously set policy into account when deciding which + * of the connections to kill. + */ +static int +ConnectionKillOne(struct UrlData *data) +{ + size_t i; struct connectdata *conn; - char endbracket; -#ifdef HAVE_SIGACTION - struct sigaction sigact; + int highscore=-1; + int connindex=-1; + int score; + CURLcode result; + + for(i=0; i< data->numconnects; i++) { + conn = data->connects[i]; + + if(!conn) + continue; + + /* + * By using the set policy, we score each connection. + */ + switch(data->closepolicy) { + default: + score = 1; /* not implemented yet */ + break; + } + + if(score > highscore) { + highscore = score; + connindex = i; + } + } + if(connindex >= 0) { + + /* the winner gets the honour of being disconnected */ + result = curl_disconnect(data->connects[connindex]); + + /* clean the array entry */ + data->connects[connindex] = NULL; + } + + return connindex; /* return the available index or -1 */ +} + +/* + * The given input connection struct pointer is to be stored. If the "cache" + * is already full, we must clean out the most suitable using the previously + * set policy. + * + * The given connection should be unique. That must've been checked prior to + * this call. + */ +static unsigned int +ConnectionStore(struct UrlData *data, + struct connectdata *conn) +{ + size_t i; + for(i=0; i< data->numconnects; i++) { + if(!data->connects[i]) + break; + } + if(i == data->numconnects) + /* there was no room available, kill one */ + i = ConnectionKillOne(data); + + data->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, + struct connectdata *conn) +{ + +#ifndef ENABLE_IPV6 + conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); + + memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); + memcpy((char *)&(conn->serv_addr.sin_addr), + conn->hp->h_addr, conn->hp->h_length); + conn->serv_addr.sin_family = conn->hp->h_addrtype; + conn->serv_addr.sin_port = htons(data->port); #endif - int urllen; -#ifdef ENABLE_IPV6 - struct addrinfo *ai; + +#if !defined(WIN32)||defined(__CYGWIN32__) + /* We don't generally like checking for OS-versions, we should make this + HAVE_XXXX based, although at the moment I don't have a decent test for + this! */ + +#ifdef HAVE_INET_NTOA + +#ifndef INADDR_NONE +#define INADDR_NONE (unsigned long) ~0 #endif +#ifndef ENABLE_IPV6 /************************************************************* - * Check input data + * Select device to bind socket to *************************************************************/ + if (data->device && (strlen(data->device)<255)) { + struct sockaddr_in sa; + struct hostent *h=NULL; + char *hostdataptr=NULL; + size_t size; + char myhost[256] = ""; + unsigned long in; - if(!data || (data->handle != STRUCT_OPEN)) - return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ + if(Curl_if2ip(data->device, myhost, sizeof(myhost))) { + h = Curl_gethost(data, myhost, &hostdataptr); + } + else { + if(strlen(data->device)>1) { + h = Curl_gethost(data, data->device, &hostdataptr); + } + if(h) { + /* we know data->device is shorter than the myhost array */ + strcpy(myhost, data->device); + } + } - if(!data->url) - return CURLE_URL_MALFORMAT; + if(! *myhost) { + /* need to fix this + h=Curl_gethost(data, + getmyhost(*myhost,sizeof(myhost)), + hostent_buf, + sizeof(hostent_buf)); + */ + printf("in here\n"); + } - /************************************************************* - * Allocate and initiate a connection struct - *************************************************************/ - conn = (struct connectdata *)malloc(sizeof(struct connectdata)); - if(!conn) { - *in_connect = NULL; /* clear the pointer */ - return CURLE_OUT_OF_MEMORY; - } - *in_connect = conn; + infof(data, "We connect from %s\n", myhost); - memset(conn, 0, sizeof(struct connectdata)); - conn->handle = STRUCT_CONNECT; + if ( (in=inet_addr(myhost)) != INADDR_NONE ) { + + if ( h ) { + memset((char *)&sa, 0, sizeof(sa)); + memcpy((char *)&sa.sin_addr, + h->h_addr, + h->h_length); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = in; + sa.sin_port = 0; /* get any port */ + + if( bind(conn->firstsocket, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { + /* we succeeded to bind */ + struct sockaddr_in add; + + size = sizeof(add); + if(getsockname(conn->firstsocket, (struct sockaddr *) &add, + (int *)&size)<0) { + failf(data, "getsockname() failed"); + return CURLE_HTTP_PORT_FAILED; + } + } + else { + switch(errno) { + case EBADF: + failf(data, "Invalid descriptor: %d", errno); + break; + case EINVAL: + failf(data, "Invalid request: %d", errno); + break; + case EACCES: + failf(data, "Address is protected, user not superuser: %d", errno); + break; + case ENOTSOCK: + failf(data, + "Argument is a descriptor for a file, not a socket: %d", + errno); + break; + case EFAULT: + failf(data, "Inaccessable memory error: %d", errno); + break; + case ENAMETOOLONG: + failf(data, "Address too long: %d", errno); + break; + case ENOMEM: + failf(data, "Insufficient kernel memory was available: %d", errno); + break; + default: + failf(data,"errno %d\n"); + } /* end of switch */ + + return CURLE_HTTP_PORT_FAILED; + } /* end of else */ + + } /* end of if h */ + else { + failf(data,"could't find my own IP address (%s)", myhost); + return CURLE_HTTP_PORT_FAILED; + } + } /* end of inet_addr */ - conn->data = data; /* remember our daddy */ - conn->state = CONN_INIT; + else { + failf(data, "could't find my own IP address (%s)", myhost); + return CURLE_HTTP_PORT_FAILED; + } - conn->upload_bufsize = UPLOAD_BUFSIZE; /* the smallest upload buffer size - we use */ + if(hostdataptr) + free(hostdataptr); /* allocated by Curl_gethost() */ - buf = data->buffer; /* this is our buffer */ + } /* end of device selection support */ +#endif /* end of HAVE_INET_NTOA */ +#endif /* end of not WIN32 */ +#endif /*ENABLE_IPV6*/ /************************************************************* - * Set signal handler + * Connect to server/proxy *************************************************************/ +#ifdef ENABLE_IPV6 + data->firstsocket = -1; + for (ai = conn->res; ai; ai = ai->ai_next) { + data->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (data->firstsocket < 0) + continue; + + if (connect(data->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { + close(data->firstsocket); + data->firstsocket = -1; + continue; + } + + break; + } + if (data->firstsocket < 0) { + failf(data, strerror(errno)); + return CURLE_COULDNT_CONNECT; + } +#else + if (connect(conn->firstsocket, + (struct sockaddr *) &(conn->serv_addr), + sizeof(conn->serv_addr) + ) < 0) { + switch(errno) { +#ifdef ECONNREFUSED + /* this should be made nicer */ + case ECONNREFUSED: + failf(data, "Connection refused"); + break; + case EFAULT: + failf(data, "Invalid socket address: %d",errno); + break; + case EISCONN: + failf(data, "Socket already connected: %d",errno); + break; + case ETIMEDOUT: + failf(data, "Timeout while accepting connection, server busy: %d",errno); + break; + case ENETUNREACH: + failf(data, "Network is unreachable: %d",errno); + break; + case EADDRINUSE: + failf(data, "Local address already in use: %d",errno); + break; + case EINPROGRESS: + failf(data, "Socket is nonblocking and connection can not be completed immediately: %d",errno); + break; + case EALREADY: + failf(data, "Socket is nonblocking and a previous connection attempt not completed: %d",errno); + break; + case EAGAIN: + failf(data, "No more free local ports: %d",errno); + break; + case EACCES: + case EPERM: + failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno); + break; +#endif + case EINTR: + failf(data, "Connection timed out"); + break; + default: + failf(data, "Can't connect to server: %d", errno); + break; + } + return CURLE_COULDNT_CONNECT; + } +#endif + + return CURLE_OK; +} + + +static CURLcode _connect(CURL *curl, CURLconnect **in_connect) +{ + char *tmp; + char *buf; + CURLcode result; + char resumerange[40]=""; + struct UrlData *data = curl; + struct connectdata *conn; + struct connectdata *conn_temp; + char endbracket; #ifdef HAVE_SIGACTION - sigaction(SIGALRM, NULL, &sigact); - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; + struct sigaction sigact; #endif - sigaction(SIGALRM, &sigact, NULL); -#else - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - signal(SIGALRM, alarmfunc); + int urllen; +#ifdef ENABLE_IPV6 + struct addrinfo *ai; #endif -#endif + /************************************************************* + * Check input data + *************************************************************/ + + if(!data || (data->handle != STRUCT_OPEN)) + return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ + + if(!data->url) + return CURLE_URL_MALFORMAT; + + /* First, split up the current URL in parts so that we can use the + parts for checking against the already present connections. In order + to not have to modify everything at once, we allocate a temporary + connection data struct and fill in for comparison purposes. */ + + conn = (struct connectdata *)malloc(sizeof(struct connectdata)); + if(!conn) { + *in_connect = NULL; /* clear the pointer */ + return CURLE_OUT_OF_MEMORY; + } + /* we have to init the struct */ + memset(conn, 0, sizeof(struct connectdata)); + + /* and we setup a few fields in case we end up actually using this struct */ + conn->handle = STRUCT_CONNECT; /* this is a connection handle */ + conn->data = data; /* remember our daddy */ + conn->state = CONN_INIT; /* init state */ + conn->upload_bufsize = UPLOAD_BUFSIZE; /* default upload buffer size */ + conn->firstsocket = -1; /* no file descriptor */ + conn->secondarysocket = -1; /* no file descriptor */ + conn->connectindex = -1; /* no index */ /*********************************************************** * We need to allocate memory to store the path in. We get the size of the @@ -678,8 +982,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) * url ... ************************************************************/ if((2 == sscanf(data->url, "%64[^:]://%[^\n]", - conn->proto, - conn->path)) && strequal(conn->proto, "file")) { + conn->protostr, + conn->path)) && strequal(conn->protostr, "file")) { /* * we deal with file:/// differently since it supports no * hostname other than "localhost" and "127.0.0.1", which is unique among @@ -692,7 +996,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) * quietly ommitted */ strcpy(conn->path, &conn->path[10]); - strcpy(conn->proto, "file"); /* store protocol string lowercase */ + strcpy(conn->protostr, "file"); /* store protocol string lowercase */ } else { /* Set default host and default path */ @@ -701,7 +1005,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) if (2 > sscanf(data->url, "%64[^\n:]://%256[^\n/]%[^\n]", - conn->proto, conn->gname, conn->path)) { + conn->protostr, conn->gname, conn->path)) { /* * The URL was badly formatted, let's try the browser-style _without_ @@ -722,28 +1026,49 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) */ if(strnequal(conn->gname, "FTP", 3)) { - strcpy(conn->proto, "ftp"); + strcpy(conn->protostr, "ftp"); } else if(strnequal(conn->gname, "GOPHER", 6)) - strcpy(conn->proto, "gopher"); + strcpy(conn->protostr, "gopher"); #ifdef USE_SSLEAY else if(strnequal(conn->gname, "HTTPS", 5)) - strcpy(conn->proto, "https"); + strcpy(conn->protostr, "https"); #endif /* USE_SSLEAY */ else if(strnequal(conn->gname, "TELNET", 6)) - strcpy(conn->proto, "telnet"); + strcpy(conn->protostr, "telnet"); else if (strnequal(conn->gname, "DICT", sizeof("DICT")-1)) - strcpy(conn->proto, "DICT"); + strcpy(conn->protostr, "DICT"); else if (strnequal(conn->gname, "LDAP", sizeof("LDAP")-1)) - strcpy(conn->proto, "LDAP"); + strcpy(conn->protostr, "LDAP"); else { - strcpy(conn->proto, "http"); + strcpy(conn->protostr, "http"); } conn->protocol |= PROT_MISSING; /* not given in URL */ } } + buf = data->buffer; /* this is our buffer */ + + /************************************************************* + * Set signal handler + *************************************************************/ +#ifdef HAVE_SIGACTION + sigaction(SIGALRM, NULL, &sigact); + sigact.sa_handler = alarmfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; +#endif + sigaction(SIGALRM, &sigact, NULL); +#else + /* no sigaction(), revert to the much lamer signal() */ +#ifdef HAVE_SIGNAL + signal(SIGALRM, alarmfunc); +#endif + +#endif + /************************************************************* * Take care of user and password authentication stuff *************************************************************/ @@ -803,7 +1128,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) *************************************************************/ conn->name = conn->gname; conn->ppath = conn->path; - data->hostname = conn->name; + conn->hostname = conn->name; /************************************************************* @@ -854,7 +1179,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } if(!nope) { /* It was not listed as without proxy */ - char *protop = conn->proto; + char *protop = conn->protostr; char *envp = proxy_env; char *prox; @@ -905,7 +1230,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) */ char *reurl; - reurl = aprintf("%s://%s", conn->proto, data->url); + reurl = aprintf("%s://%s", conn->protostr, data->url); if(!reurl) return CURLE_OUT_OF_MEMORY; @@ -951,7 +1276,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) * Setup internals depending on protocol *************************************************************/ - if (strequal(conn->proto, "HTTP")) { + if (strequal(conn->protostr, "HTTP")) { if(!data->port) data->port = PORT_HTTP; data->remote_port = PORT_HTTP; @@ -960,7 +1285,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->curl_done = Curl_http_done; conn->curl_close = Curl_http_close; } - else if (strequal(conn->proto, "HTTPS")) { + else if (strequal(conn->protostr, "HTTPS")) { #ifdef USE_SSLEAY if(!data->port) data->port = PORT_HTTPS; @@ -978,7 +1303,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_UNSUPPORTED_PROTOCOL; #endif /* !USE_SSLEAY */ } - else if (strequal(conn->proto, "GOPHER")) { + else if (strequal(conn->protostr, "GOPHER")) { if(!data->port) data->port = PORT_GOPHER; data->remote_port = PORT_GOPHER; @@ -993,7 +1318,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->curl_done = Curl_http_done; conn->curl_close = Curl_http_close; } - else if(strequal(conn->proto, "FTP")) { + else if(strequal(conn->protostr, "FTP")) { char *type; if(!data->port) data->port = PORT_FTP; @@ -1041,7 +1366,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } } } - else if(strequal(conn->proto, "TELNET")) { + else if(strequal(conn->protostr, "TELNET")) { /* telnet testing factory */ conn->protocol |= PROT_TELNET; if(!data->port) @@ -1052,7 +1377,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->curl_done = Curl_telnet_done; } - else if (strequal(conn->proto, "DICT")) { + else if (strequal(conn->protostr, "DICT")) { conn->protocol |= PROT_DICT; if(!data->port) data->port = PORT_DICT; @@ -1060,7 +1385,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->curl_do = Curl_dict; conn->curl_done = Curl_dict_done; } - else if (strequal(conn->proto, "LDAP")) { + else if (strequal(conn->protostr, "LDAP")) { conn->protocol |= PROT_LDAP; if(!data->port) data->port = PORT_LDAP; @@ -1068,7 +1393,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->curl_do = Curl_ldap; conn->curl_done = Curl_ldap_done; } - else if (strequal(conn->proto, "FILE")) { + else if (strequal(conn->protostr, "FILE")) { conn->protocol |= PROT_FILE; conn->curl_do = file; @@ -1082,7 +1407,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) else { /* We fell through all checks and thus we don't support the specified protocol */ - failf(data, "Unsupported protocol: %s", conn->proto); + failf(data, "Unsupported protocol: %s", conn->protostr); return CURLE_UNSUPPORTED_PROTOCOL; } @@ -1090,9 +1415,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) * .netrc scanning coming up *************************************************************/ if(data->bits.use_netrc) { - if(Curl_parsenetrc(data->hostname, data->user, data->passwd)) { + if(Curl_parsenetrc(conn->hostname, data->user, data->passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", - data->hostname); + conn->hostname); } else data->bits.user_passwd = 1; /* enable user+password */ @@ -1195,6 +1520,39 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->remote_port = atoi(tmp); } + /* copy the port-specifics to the connection struct */ + conn->port = data->port; + conn->remote_port = data->remote_port; + + /************************************************************* + * Check the current list of connections to see if we can + * re-use an already existing one or if we have to create a + * new one. + *************************************************************/ + + if(ConnectionExists(data, conn, &conn_temp)) { + /* + * We already have a connection for this, we got the former connection + * in the conn_temp variable and thus we need to cleanup the one we + * just allocated before we can move along and use the previously + * existing one. + */ + char *path = conn->path; /* setup the current path pointer properly */ + free(conn); /* we don't need this new one */ + conn = conn_temp; /* use this connection from now on */ + free(conn->path); /* free the previous path pointer */ + conn->path = path; /* use this one */ + conn->ppath = path; /* set this too */ + } + else { + /* + * This is a brand new connection, so let's store it in the connection + * cache of ours! + */ + ConnectionStore(data, conn); + } + *in_connect = conn; + /************************************************************* * Resolve the name of the server or proxy *************************************************************/ @@ -1203,12 +1561,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) * there, thus overriding any defaults that might have been set above. */ data->port = data->remote_port; /* it is the same port */ - /* Connect to target host right on */ + /* Resolve target host right on */ #ifdef ENABLE_IPV6 - conn->res = Curl_getaddrinfo(data, conn->name, data->port); + if(!conn->res) + /* it might already be set if reusing a connection */ + conn->res = Curl_getaddrinfo(data, conn->name, data->port); if(!conn->res) #else - conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); + if(!conn->hp) + /* it might already be set if reusing a connection */ + conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); if(!conn->hp) #endif { @@ -1216,7 +1578,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_COULDNT_RESOLVE_HOST; } } - else { + else if(!conn->hp) { + /* This is a proxy that hasn't been resolved yet. It may be resolved + if we're reusing an existing connection. */ #ifdef ENABLE_IPV6 failf(data, "proxy yet to be supported"); return CURLE_OUT_OF_MEMORY; @@ -1261,7 +1625,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->port = data->proxyport; } - /* connect to proxy */ + /* resolve proxy */ conn->hp = Curl_gethost(data, proxyptr, &conn->hostent_buf); if(!conn->hp) { failf(data, "Couldn't resolve proxy '%s'", proxyptr); @@ -1273,210 +1637,12 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } Curl_pgrsTime(data, TIMER_NAMELOOKUP); -#ifndef ENABLE_IPV6 - data->firstsocket = socket(AF_INET, SOCK_STREAM, 0); - - memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); - memcpy((char *)&(conn->serv_addr.sin_addr), - conn->hp->h_addr, conn->hp->h_length); - conn->serv_addr.sin_family = conn->hp->h_addrtype; - conn->serv_addr.sin_port = htons(data->port); -#endif - -#if !defined(WIN32)||defined(__CYGWIN32__) - /* We don't generally like checking for OS-versions, we should make this - HAVE_XXXX based, although at the moment I don't have a decent test for - this! */ - -#ifdef HAVE_INET_NTOA - -#ifndef INADDR_NONE -#define INADDR_NONE (unsigned long) ~0 -#endif - -#ifndef ENABLE_IPV6 - /************************************************************* - * Select device to bind socket to - *************************************************************/ - if (data->device && (strlen(data->device)<255)) { - struct sockaddr_in sa; - struct hostent *h=NULL; - char *hostdataptr=NULL; - size_t size; - char myhost[256] = ""; - unsigned long in; - - if(Curl_if2ip(data->device, myhost, sizeof(myhost))) { - h = Curl_gethost(data, myhost, &hostdataptr); - } - else { - if(strlen(data->device)>1) { - h = Curl_gethost(data, data->device, &hostdataptr); - } - if(h) { - /* we know data->device is shorter than the myhost array */ - strcpy(myhost, data->device); - } - } - - if(! *myhost) { - /* need to fix this - h=Curl_gethost(data, - getmyhost(*myhost,sizeof(myhost)), - hostent_buf, - sizeof(hostent_buf)); - */ - printf("in here\n"); - } - - infof(data, "We connect from %s\n", myhost); - - if ( (in=inet_addr(myhost)) != INADDR_NONE ) { - - if ( h ) { - memset((char *)&sa, 0, sizeof(sa)); - memcpy((char *)&sa.sin_addr, - h->h_addr, - h->h_length); - sa.sin_family = AF_INET; - sa.sin_addr.s_addr = in; - sa.sin_port = 0; /* get any port */ - - if( bind(data->firstsocket, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { - /* we succeeded to bind */ - struct sockaddr_in add; - - size = sizeof(add); - if(getsockname(data->firstsocket, (struct sockaddr *) &add, - (int *)&size)<0) { - failf(data, "getsockname() failed"); - return CURLE_HTTP_PORT_FAILED; - } - } - else { - switch(errno) { - case EBADF: - failf(data, "Invalid descriptor: %d", errno); - break; - case EINVAL: - failf(data, "Invalid request: %d", errno); - break; - case EACCES: - failf(data, "Address is protected, user not superuser: %d", errno); - break; - case ENOTSOCK: - failf(data, - "Argument is a descriptor for a file, not a socket: %d", - errno); - break; - case EFAULT: - failf(data, "Inaccessable memory error: %d", errno); - break; - case ENAMETOOLONG: - failf(data, "Address too long: %d", errno); - break; - case ENOMEM: - failf(data, "Insufficient kernel memory was available: %d", errno); - break; - default: - failf(data,"errno %d\n"); - } /* end of switch */ - - return CURLE_HTTP_PORT_FAILED; - } /* end of else */ - - } /* end of if h */ - else { - failf(data,"could't find my own IP address (%s)", myhost); - return CURLE_HTTP_PORT_FAILED; - } - } /* end of inet_addr */ - - else { - failf(data, "could't find my own IP address (%s)", myhost); - return CURLE_HTTP_PORT_FAILED; - } - - if(hostdataptr) - free(hostdataptr); /* allocated by Curl_gethost() */ - - } /* end of device selection support */ -#endif /* end of HAVE_INET_NTOA */ -#endif /* end of not WIN32 */ -#endif /*ENABLE_IPV6*/ - - /************************************************************* - * Connect to server/proxy - *************************************************************/ -#ifdef ENABLE_IPV6 - data->firstsocket = -1; - for (ai = conn->res; ai; ai = ai->ai_next) { - data->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (data->firstsocket < 0) - continue; - - if (connect(data->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { - close(data->firstsocket); - data->firstsocket = -1; - continue; - } - - break; - } - if (data->firstsocket < 0) { - failf(data, strerror(errno)); - return CURLE_COULDNT_CONNECT; - } -#else - if (connect(data->firstsocket, - (struct sockaddr *) &(conn->serv_addr), - sizeof(conn->serv_addr) - ) < 0) { - switch(errno) { -#ifdef ECONNREFUSED - /* this should be made nicer */ - case ECONNREFUSED: - failf(data, "Connection refused"); - break; - case EFAULT: - failf(data, "Invalid socket address: %d",errno); - break; - case EISCONN: - failf(data, "Socket already connected: %d",errno); - break; - case ETIMEDOUT: - failf(data, "Timeout while accepting connection, server busy: %d",errno); - break; - case ENETUNREACH: - failf(data, "Network is unreachable: %d",errno); - break; - case EADDRINUSE: - failf(data, "Local address already in use: %d",errno); - break; - case EINPROGRESS: - failf(data, "Socket is nonblocking and connection can not be completed immediately: %d",errno); - break; - case EALREADY: - failf(data, "Socket is nonblocking and a previous connection attempt not completed: %d",errno); - break; - case EAGAIN: - failf(data, "No more free local ports: %d",errno); - break; - case EACCES: - case EPERM: - failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno); - break; -#endif - case EINTR: - failf(data, "Connection timed out"); - break; - default: - failf(data, "Can't connect to server: %d", errno); - break; - } - return CURLE_COULDNT_CONNECT; + if(-1 == conn->firstsocket) { + /* Connect only if not already connected! */ + result = ConnectPlease(data, conn); + if(CURLE_OK != result) + return result; } -#endif /************************************************************* * Proxy authentication @@ -1621,6 +1787,7 @@ CURLcode curl_done(CURLconnect *c_connect) struct connectdata *conn = c_connect; struct UrlData *data; CURLcode result; + int index; if(!conn || (conn->handle!= STRUCT_CONNECT)) { return CURLE_BAD_FUNCTION_ARGUMENT; @@ -1641,6 +1808,14 @@ CURLcode curl_done(CURLconnect *c_connect) conn->state = CONN_DONE; + /* if bits.close is TRUE, it means that the connection should be closed + in spite of all our efforts to be nice */ + if((CURLE_OK == result) && conn->bits.close) { + index = conn->connectindex; /* get the index */ + result = curl_disconnect(conn); /* close the connection */ + data->connects[index]=NULL; /* clear the pointer */ + } + return result; } -- cgit v1.2.1 From 46e0937263df22f091cb7367182ff6095f73b82e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Feb 2001 17:46:35 +0000 Subject: corrected memory leaks when re-using connections --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0dbf4ed16..7905039b8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1653,6 +1653,8 @@ 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 = aprintf("Proxy-authorization: Basic %s\015\012", authorization); free(authorization); @@ -1665,6 +1667,8 @@ 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 = aprintf("User-Agent: %s\015\012", data->useragent); } -- cgit v1.2.1 From da06a6e7e34d9f1c9c6cf6574aec75f4ed704b9c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 21 Feb 2001 17:15:09 +0000 Subject: IPv6-adjustments --- lib/url.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7905039b8..71824ad4f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -547,8 +547,8 @@ CURLcode curl_disconnect(CURLconnect *c_connect) free(conn->proto.generic); #ifdef ENABLE_IPV6 - if(conn->res) /* host name info */ - freeaddrinfo(conn->res); + if(conn->hp) /* host name info */ + freeaddrinfo(conn->hp); #else if(conn->hostent_buf) /* host name info */ free(conn->hostent_buf); @@ -708,6 +708,9 @@ static CURLcode ConnectPlease(struct UrlData *data, conn->hp->h_addr, conn->hp->h_length); conn->serv_addr.sin_family = conn->hp->h_addrtype; conn->serv_addr.sin_port = htons(data->port); +#else + /* IPv6-style */ + struct addrinfo *ai; #endif #if !defined(WIN32)||defined(__CYGWIN32__) @@ -836,21 +839,22 @@ static CURLcode ConnectPlease(struct UrlData *data, * Connect to server/proxy *************************************************************/ #ifdef ENABLE_IPV6 - data->firstsocket = -1; - for (ai = conn->res; ai; ai = ai->ai_next) { - data->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (data->firstsocket < 0) + conn->firstsocket = -1; + for (ai = conn->hp; ai; ai = ai->ai_next) { + conn->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (conn->firstsocket < 0) continue; - if (connect(data->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { - close(data->firstsocket); - data->firstsocket = -1; + if (connect(conn->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { + close(conn->firstsocket); + conn->firstsocket = -1; continue; } break; } - if (data->firstsocket < 0) { + conn->ai = ai; + if (conn->firstsocket < 0) { failf(data, strerror(errno)); return CURLE_COULDNT_CONNECT; } @@ -923,9 +927,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) struct sigaction sigact; #endif int urllen; -#ifdef ENABLE_IPV6 - struct addrinfo *ai; -#endif /************************************************************* * Check input data @@ -1562,17 +1563,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) data->port = data->remote_port; /* it is the same port */ /* Resolve target host right on */ + if(!conn->hp) { #ifdef ENABLE_IPV6 - if(!conn->res) /* it might already be set if reusing a connection */ - conn->res = Curl_getaddrinfo(data, conn->name, data->port); - if(!conn->res) + conn->hp = Curl_getaddrinfo(data, conn->name, data->port); #else - if(!conn->hp) /* it might already be set if reusing a connection */ conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); - if(!conn->hp) #endif + } + if(!conn->hp) { failf(data, "Couldn't resolve host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; @@ -1702,6 +1702,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #else const int niflags = NI_NUMERICHOST; #endif + struct addrinfo *ai = conn->ai; + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, niflags)) { snprintf(hbuf, sizeof(hbuf), "?"); @@ -1751,8 +1753,8 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(conn->path) free(conn->path); #ifdef ENABLE_IPV6 - if(conn->res) - freeaddrinfo(conn->res); + if(conn->hp) + freeaddrinfo(conn->hp); #else if(conn->hostent_buf) free(conn->hostent_buf); -- cgit v1.2.1 From 584dbffe601f823e5d3a3ced0d035b499f1bc903 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 22 Feb 2001 23:32:02 +0000 Subject: moved the dynamicly set pointers to the connectdata struct --- lib/url.c | 63 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 26 insertions(+), 37 deletions(-) (limited to 'lib/url.c') 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); } } -- cgit v1.2.1 From 4af55809e4befb59bc341f5e6803aa80634c8fdb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 22 Feb 2001 23:51:17 +0000 Subject: added some infof() calls for persistant info --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2092b213b..904e90bf3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -546,12 +546,10 @@ CURLcode curl_disconnect(CURLconnect *c_connect) #endif /* USE_SSLEAY */ /* close possibly still open sockets */ - if(-1 != conn->secondarysocket) { + if(-1 != conn->secondarysocket) sclose(conn->secondarysocket); - } - if(-1 != conn->firstsocket) { + if(-1 != conn->firstsocket) sclose(conn->firstsocket); - } if(conn->allocptr.proxyuserpwd) free(conn->allocptr.proxyuserpwd); @@ -669,9 +667,11 @@ ConnectionStore(struct UrlData *data, if(!data->connects[i]) break; } - if(i == data->numconnects) + if(i == data->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 */ conn->connectindex = i; /* make the child know where the pointer to this -- cgit v1.2.1 From 9bc24e48768a25f308f8992ea4a671657279a9df Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 28 Feb 2001 14:03:46 +0000 Subject: cleanup better when connects fail --- lib/url.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 904e90bf3..c6ee3121c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1737,7 +1737,12 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ + struct UrlData *data; + int index; + conn = (struct connectdata *)*in_connect; + data = conn->data; +#if 0 if(conn) { if(conn->path) free(conn->path); @@ -1751,6 +1756,11 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) free(conn); *in_connect=NULL; } +#endif + index = conn->connectindex; /* get the index */ + curl_disconnect(conn); /* close the connection */ + data->connects[index]=NULL; /* clear the pointer */ + } return code; } -- cgit v1.2.1 From af4451ec2618f827016c129aca9c9362e722dc35 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 2 Mar 2001 07:43:20 +0000 Subject: improved connections --- lib/url.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c6ee3121c..5f7fe57dc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -514,6 +514,10 @@ CURLcode curl_disconnect(CURLconnect *c_connect) { struct connectdata *conn = c_connect; + if(conn->curl_disconnect) + /* This is set if protocol-specific cleanups should be made */ + conn->curl_disconnect(conn); + if(conn->proto.generic) free(conn->proto.generic); @@ -596,6 +600,15 @@ ConnectionExists(struct UrlData *data, if(strequal(needle->protostr, check->protostr) && strequal(needle->name, check->name) && (needle->port == check->port) ) { + 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)) { + /* one of them was different */ + continue; + } + } *usethis = check; return TRUE; /* yes, we found one to use! */ } @@ -1322,6 +1335,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->curl_do = Curl_ftp; conn->curl_done = Curl_ftp_done; conn->curl_connect = Curl_ftp_connect; + conn->curl_disconnect = Curl_ftp_disconnect; } conn->ppath++; /* don't include the initial slash */ @@ -1530,7 +1544,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) conn->ppath = path; /* set this too */ /* re-use init */ - conn->maxdownload = 0; /* might have been used previously! */ + conn->maxdownload = 0; /* might have been used previously! */ + conn->bits.reuse = TRUE; /* yes, we're re-using here */ infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex); } @@ -1626,13 +1641,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } Curl_pgrsTime(data, TIMER_NAMELOOKUP); - if(-1 == conn->firstsocket) { - /* Connect only if not already connected! */ - result = ConnectPlease(data, conn); - if(CURLE_OK != result) - return result; - } - /************************************************************* * Proxy authentication *************************************************************/ @@ -1663,18 +1671,25 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } } - if(conn->curl_connect) { - /* is there a connect() procedure? */ + if(-1 == conn->firstsocket) { + /* Connect only if not already connected! */ + result = ConnectPlease(data, conn); + if(CURLE_OK != result) + return result; + + if(conn->curl_connect) { + /* is there a connect() procedure? */ - /* set start time here for timeout purposes in the - * connect procedure, it is later set again for the - * progress meter purpose */ - conn->now = Curl_tvnow(); + /* set start time here for timeout purposes in the + * connect procedure, it is later set again for the + * progress meter purpose */ + conn->now = Curl_tvnow(); - /* Call the protocol-specific connect function */ - result = conn->curl_connect(conn); - if(result != CURLE_OK) - return result; /* pass back errors */ + /* Call the protocol-specific connect function */ + result = conn->curl_connect(conn); + if(result != CURLE_OK) + return result; /* pass back errors */ + } } Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */ -- cgit v1.2.1 From d1cfbd51b5f6e4246cec86ce3c9b7b1cde2f860a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 2 Mar 2001 15:34:15 +0000 Subject: remade the port number stuff so that following locations work and doing intermixed HTTP and FTP persistant connections also work! --- lib/url.c | 62 +++++++++++++++++++++++++++----------------------------------- 1 file changed, 27 insertions(+), 35 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5f7fe57dc..4281109a6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -378,7 +378,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...) data->url = va_arg(param, char *); break; case CURLOPT_PORT: - data->port = va_arg(param, long); + data->use_port = va_arg(param, long); break; case CURLOPT_POST: /* Does this option serve a purpose anymore? */ @@ -704,7 +704,7 @@ static CURLcode ConnectPlease(struct UrlData *data, memcpy((char *)&(conn->serv_addr.sin_addr), conn->hp->h_addr, conn->hp->h_length); conn->serv_addr.sin_family = conn->hp->h_addrtype; - conn->serv_addr.sin_port = htons(data->port); + conn->serv_addr.sin_port = htons(conn->port); #else /* IPv6-style */ struct addrinfo *ai; @@ -910,7 +910,9 @@ static CURLcode ConnectPlease(struct UrlData *data, } -static CURLcode _connect(CURL *curl, CURLconnect **in_connect) +static CURLcode _connect(CURL *curl, + CURLconnect **in_connect, + bool allow_port) /* allow data->use_port ? */ { char *tmp; char *buf; @@ -1275,9 +1277,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) *************************************************************/ if (strequal(conn->protostr, "HTTP")) { - if(!data->port) - data->port = PORT_HTTP; - data->remote_port = PORT_HTTP; + conn->port = (data->use_port && allow_port)?data->use_port:PORT_HTTP; + conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; @@ -1285,9 +1286,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } else if (strequal(conn->protostr, "HTTPS")) { #ifdef USE_SSLEAY - if(!data->port) - data->port = PORT_HTTPS; - data->remote_port = PORT_HTTPS; + + conn->port = (data->use_port && allow_port)?data->use_port:PORT_HTTPS; + conn->remote_port = PORT_HTTPS; conn->protocol |= PROT_HTTP; conn->protocol |= PROT_HTTPS; @@ -1302,9 +1303,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) #endif /* !USE_SSLEAY */ } else if (strequal(conn->protostr, "GOPHER")) { - if(!data->port) - data->port = PORT_GOPHER; - data->remote_port = PORT_GOPHER; + conn->port = (data->use_port && allow_port)?data->use_port:PORT_GOPHER; + conn->remote_port = PORT_GOPHER; /* Skip // in path if present */ if (isdigit((int)conn->path[1])) { conn->ppath = strchr(&conn->path[1], '/'); @@ -1318,9 +1318,8 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) } else if(strequal(conn->protostr, "FTP")) { char *type; - if(!data->port) - data->port = PORT_FTP; - data->remote_port = PORT_FTP; + conn->port = (data->use_port && allow_port)?data->use_port:PORT_FTP; + conn->remote_port = PORT_FTP; conn->protocol |= PROT_FTP; if(data->bits.httpproxy && @@ -1368,27 +1367,23 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) else if(strequal(conn->protostr, "TELNET")) { /* telnet testing factory */ conn->protocol |= PROT_TELNET; - if(!data->port) - data->port = PORT_TELNET; - data->remote_port = PORT_TELNET; + conn->port = (data->use_port && allow_port)?data->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; - if(!data->port) - data->port = PORT_DICT; - data->remote_port = PORT_DICT; + conn->port = (data->use_port && allow_port)?data->use_port:PORT_DICT; + conn->remote_port = PORT_DICT; conn->curl_do = Curl_dict; conn->curl_done = Curl_dict_done; } else if (strequal(conn->protostr, "LDAP")) { conn->protocol |= PROT_LDAP; - if(!data->port) - data->port = PORT_LDAP; - data->remote_port = PORT_LDAP; + conn->port = (data->use_port && allow_port)?data->use_port:PORT_LDAP; + conn->remote_port = PORT_LDAP; conn->curl_do = Curl_ldap; conn->curl_done = Curl_ldap_done; } @@ -1516,13 +1511,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) if (tmp) { *tmp++ = '\0'; /* cut off the name there */ - data->remote_port = atoi(tmp); + conn->remote_port = atoi(tmp); } - /* copy the port-specifics to the connection struct */ - conn->port = data->port; - conn->remote_port = data->remote_port; - /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a @@ -1564,7 +1555,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) if(!data->bits.httpproxy) { /* 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. */ - data->port = data->remote_port; /* it is the same port */ + conn->port = conn->remote_port; /* it is the same port */ /* Resolve target host right on */ if(!conn->hp) { @@ -1621,12 +1612,12 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) *prox_portno = 0x0; /* cut off number from host name */ prox_portno ++; /* now set the local port number */ - data->port = atoi(prox_portno); + conn->port = atoi(prox_portno); } else if(data->proxyport) { /* None given in the proxy string, then get the default one if it is given */ - data->port = data->proxyport; + conn->port = data->proxyport; } /* resolve proxy */ @@ -1741,13 +1732,14 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect) return CURLE_OK; } -CURLcode curl_connect(CURL *curl, CURLconnect **in_connect) +CURLcode curl_connect(CURL *curl, CURLconnect **in_connect, + bool allow_port) { CURLcode code; struct connectdata *conn; /* call the stuff that needs to be called */ - code = _connect(curl, in_connect); + code = _connect(curl, in_connect, allow_port); if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated -- cgit v1.2.1 From dd893fd8a44cffc225b85ba4909d517a1c3b085e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 3 Mar 2001 17:50:01 +0000 Subject: ipv6 fix for the 'port' no longer in urldata --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4281109a6..9318d4132 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1561,7 +1561,7 @@ static CURLcode _connect(CURL *curl, if(!conn->hp) { #ifdef ENABLE_IPV6 /* it might already be set if reusing a connection */ - conn->hp = Curl_getaddrinfo(data, conn->name, data->port); + conn->hp = Curl_getaddrinfo(data, conn->name, conn->port); #else /* it might already be set if reusing a connection */ conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); -- cgit v1.2.1 From cf8704ccdf60a34ba7862a0848724b9862158c86 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 4 Mar 2001 16:34:20 +0000 Subject: 7.7 alpha 2 commit --- lib/url.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9318d4132..123e5d480 100644 --- a/lib/url.c +++ b/lib/url.c @@ -575,6 +575,32 @@ CURLcode curl_disconnect(CURLconnect *c_connect) return CURLE_OK; } +/* + * This function should return TRUE if the socket is to be assumed to + * be dead. Most commonly this happens when the server has closed the + * connection due to inactivity. + */ +static bool SocketIsDead(int sock) +{ + int sval; + bool ret_val = TRUE; + fd_set check_set; + struct timeval to; + + FD_ZERO(&check_set); + FD_SET(sock,&check_set); + + to.tv_sec = 0; + to.tv_usec = 1; + + sval = select(sock + 1, &check_set, 0, 0, &to); + if(sval == 0) + /* timeout */ + ret_val = FALSE; + + return ret_val; +} + /* * Given one filled in connection struct, this function should detect if there * already is one that have all the significant details exactly the same and @@ -609,6 +635,16 @@ ConnectionExists(struct UrlData *data, continue; } } + { + bool dead; + dead = SocketIsDead(check->firstsocket); + if(dead) { + infof(data, "Connection %d seems to be dead!\n", i); + curl_disconnect(check); /* disconnect resources */ + data->connects[i]=NULL; /* nothing here */ + continue; /* try another one now */ + } + } *usethis = check; return TRUE; /* yes, we found one to use! */ } @@ -909,7 +945,6 @@ static CURLcode ConnectPlease(struct UrlData *data, return CURLE_OK; } - static CURLcode _connect(CURL *curl, CURLconnect **in_connect, bool allow_port) /* allow data->use_port ? */ -- cgit v1.2.1 From 84e94fda8ba36c77c80e012c52ad36a4a59de6a7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Mar 2001 13:39:01 +0000 Subject: remade FILE:// support to look more as the other protocols --- lib/url.c | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 123e5d480..9b53fbc2f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -982,6 +982,11 @@ static CURLcode _connect(CURL *curl, *in_connect = NULL; /* clear the pointer */ return CURLE_OUT_OF_MEMORY; } + /* We must set the return variable as soon as possible, so that our + parent can cleanup any possible allocs we may have done before + any failure */ + *in_connect = conn; + /* we have to init the struct */ memset(conn, 0, sizeof(struct connectdata)); @@ -994,6 +999,12 @@ static CURLcode _connect(CURL *curl, conn->secondarysocket = -1; /* no file descriptor */ conn->connectindex = -1; /* no index */ + /* Default protocol-indepent behaveiour doesn't support persistant + connections, so we set this to force-close. Protocols that support + this need to set this to FALSE in their "curl_do" functions. */ + conn->bits.close = TRUE; + + /*********************************************************** * We need to allocate memory to store the path in. We get the size of the * full URL to be sure, and we need to make it at least 256 bytes since @@ -1425,13 +1436,20 @@ static CURLcode _connect(CURL *curl, else if (strequal(conn->protostr, "FILE")) { conn->protocol |= PROT_FILE; - conn->curl_do = file; + conn->curl_do = Curl_file; /* no done() function */ - result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ + /* anyway, this is supposed to be the connect function so we better + at least check that the file is present here! */ + result = Curl_file_connect(conn); - return CURLE_OK; + /* Setup a "faked" transfer that'll do nothing */ + if(CURLE_OK == result) { + result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ + -1, NULL); /* no upload */ + } + + return result; } else { /* We fell through all checks and thus we don't support the specified @@ -1582,7 +1600,6 @@ static CURLcode _connect(CURL *curl, */ ConnectionStore(data, conn); } - *in_connect = conn; /************************************************************* * Resolve the name of the server or proxy @@ -1779,30 +1796,15 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect, if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ - struct UrlData *data; - int index; - conn = (struct connectdata *)*in_connect; - data = conn->data; -#if 0 if(conn) { - if(conn->path) - free(conn->path); -#ifdef ENABLE_IPV6 - if(conn->hp) - freeaddrinfo(conn->hp); -#else - if(conn->hostent_buf) - free(conn->hostent_buf); -#endif - free(conn); - *in_connect=NULL; + struct UrlData *data; + int index; + data = conn->data; + index = conn->connectindex; /* get the index */ + curl_disconnect(conn); /* close the connection */ + data->connects[index]=NULL; /* clear the pointer */ } -#endif - index = conn->connectindex; /* get the index */ - curl_disconnect(conn); /* close the connection */ - data->connects[index]=NULL; /* clear the pointer */ - } return code; } -- cgit v1.2.1 From 8ec4dba599df56c0eee17b45094c164882968a85 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 9 Mar 2001 15:18:25 +0000 Subject: removed handles and states from the main structs renamed prefixes from curl_ to Curl_ made persistant connections work with http proxies (at least partly) --- lib/url.c | 270 ++++++++++++++++++++++++++------------------------------------ 1 file changed, 111 insertions(+), 159 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9b53fbc2f..cb0bbe60b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -122,18 +122,7 @@ static unsigned int ConnectionStore(struct UrlData *data, struct connectdata *conn); -/* does nothing, returns OK */ -CURLcode curl_init(void) -{ - return CURLE_OK; -} - -/* does nothing */ -void curl_free(void) -{ -} - -CURLcode curl_close(CURL *curl) +CURLcode Curl_close(CURL *curl) { struct UrlData *data=(struct UrlData *)curl; @@ -178,10 +167,6 @@ CURLcode curl_close(CURL *curl) free(data->connects); free(data); - - /* global cleanup */ - curl_free(); - return CURLE_OK; } @@ -197,7 +182,7 @@ int my_getpass(void *clientp, char *prompt, char* buffer, int buflen ) } -CURLcode curl_open(CURL **curl, char *url) +CURLcode Curl_open(CURL **curl, char *url) { /* We don't yet support specifying the URL at this point */ struct UrlData *data; @@ -206,8 +191,6 @@ CURLcode curl_open(CURL **curl, char *url) data = (struct UrlData *)malloc(sizeof(struct UrlData)); if(data) { memset(data, 0, sizeof(struct UrlData)); - data->handle = STRUCT_OPEN; - data->interf = CURLI_NORMAL; /* normal interface by default */ /* We do some initial setup here, all those fields that can't be just 0 */ @@ -258,7 +241,7 @@ CURLcode curl_open(CURL **curl, char *url) return CURLE_OUT_OF_MEMORY; } -CURLcode curl_setopt(CURL *curl, CURLoption option, ...) +CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) { struct UrlData *data = curl; va_list param; @@ -510,10 +493,8 @@ RETSIGTYPE alarmfunc(int signal) } #endif -CURLcode curl_disconnect(CURLconnect *c_connect) +CURLcode Curl_disconnect(struct connectdata *conn) { - struct connectdata *conn = c_connect; - if(conn->curl_disconnect) /* This is set if protocol-specific cleanups should be made */ conn->curl_disconnect(conn); @@ -570,6 +551,9 @@ CURLcode curl_disconnect(CURLconnect *c_connect) if(conn->allocptr.host) free(conn->allocptr.host); + if(conn->proxyhost) + free(conn->proxyhost); + free(conn); /* free all the connection oriented data */ return CURLE_OK; @@ -623,24 +607,26 @@ ConnectionExists(struct UrlData *data, if(!check) /* NULL pointer means not filled-in entry */ continue; - if(strequal(needle->protostr, check->protostr) && - strequal(needle->name, check->name) && - (needle->port == check->port) ) { - 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)) { - /* one of them was different */ - continue; - } - } - { + if(!needle->bits.httpproxy) { + /* The requested connection does not use a HTTP proxy */ + + if(strequal(needle->protostr, check->protostr) && + strequal(needle->name, check->name) && + (needle->port == check->port) ) { bool dead; + 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)) { + /* one of them was different */ + continue; + } + } dead = SocketIsDead(check->firstsocket); if(dead) { infof(data, "Connection %d seems to be dead!\n", i); - curl_disconnect(check); /* disconnect resources */ + Curl_disconnect(check); /* disconnect resources */ data->connects[i]=NULL; /* nothing here */ continue; /* try another one now */ } @@ -648,6 +634,16 @@ ConnectionExists(struct UrlData *data, *usethis = check; return TRUE; /* yes, we found one to use! */ } + else { /* The requested needle connection is using a proxy, + is the checked one using the same? */ + if(check->bits.httpproxy && + strequal(needle->proxyhost, check->proxyhost) && + needle->port == check->port) { + /* This is the same proxy connection, use it! */ + *usethis = check; + return TRUE; + } + } } return FALSE; /* no matching connecting exists */ } @@ -690,7 +686,7 @@ ConnectionKillOne(struct UrlData *data) if(connindex >= 0) { /* the winner gets the honour of being disconnected */ - result = curl_disconnect(data->connects[connindex]); + result = Curl_disconnect(data->connects[connindex]); /* clean the array entry */ data->connects[connindex] = NULL; @@ -811,7 +807,7 @@ static CURLcode ConnectPlease(struct UrlData *data, size = sizeof(add); if(getsockname(conn->firstsocket, (struct sockaddr *) &add, - (int *)&size)<0) { + (socklen_t *)&size)<0) { failf(data, "getsockname() failed"); return CURLE_HTTP_PORT_FAILED; } @@ -945,15 +941,14 @@ static CURLcode ConnectPlease(struct UrlData *data, return CURLE_OK; } -static CURLcode _connect(CURL *curl, - CURLconnect **in_connect, - bool allow_port) /* allow data->use_port ? */ +static CURLcode Connect(struct UrlData *data, + struct connectdata **in_connect, + bool allow_port) /* allow data->use_port ? */ { char *tmp; char *buf; CURLcode result; char resumerange[40]=""; - struct UrlData *data = curl; struct connectdata *conn; struct connectdata *conn_temp; char endbracket; @@ -966,9 +961,6 @@ static CURLcode _connect(CURL *curl, * Check input data *************************************************************/ - if(!data || (data->handle != STRUCT_OPEN)) - return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */ - if(!data->url) return CURLE_URL_MALFORMAT; @@ -991,13 +983,12 @@ static CURLcode _connect(CURL *curl, memset(conn, 0, sizeof(struct connectdata)); /* and we setup a few fields in case we end up actually using this struct */ - conn->handle = STRUCT_CONNECT; /* this is a connection handle */ conn->data = data; /* remember our daddy */ - conn->state = CONN_INIT; /* init state */ conn->upload_bufsize = UPLOAD_BUFSIZE; /* default upload buffer size */ 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 */ /* Default protocol-indepent behaveiour doesn't support persistant connections, so we set this to force-close. Protocols that support @@ -1567,6 +1558,62 @@ static CURLcode _connect(CURL *curl, conn->remote_port = atoi(tmp); } + if(data->bits.httpproxy) { + /* 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. */ + +#ifdef ENABLE_IPV6 + failf(data, "proxy yet to be supported"); + return CURLE_OUT_OF_MEMORY; +#else + char *prox_portno; + char *endofprot; + + /* We need to make a duplicate of the proxy so that we can modify the + string safely. */ + char *proxydup=strdup(data->proxy); + + /* We use 'proxyptr' to point to the proxy name from now on... */ + char *proxyptr=proxydup; + + if(NULL == proxydup) { + failf(data, "memory shortage"); + return CURLE_OUT_OF_MEMORY; + } + + /* Daniel Dec 10, 1998: + We do the proxy host string parsing here. We want the host name and the + port name. Accept a protocol:// prefix, even though it should just be + ignored. */ + + /* 1. skip the protocol part if present */ + endofprot=strstr(proxyptr, "://"); + if(endofprot) { + proxyptr = endofprot+3; + } + + /* allow user to specify proxy.server.com:1080 if desired */ + prox_portno = strchr (proxyptr, ':'); + if (prox_portno) { + *prox_portno = 0x0; /* cut off number from host name */ + prox_portno ++; + /* now set the local port number */ + conn->port = atoi(prox_portno); + } + else if(data->proxyport) { + /* None given in the proxy string, then get the default one if it is + given */ + conn->port = data->proxyport; + } + + /* now, clone the cleaned proxy host name */ + conn->proxyhost = strdup(proxyptr); + + free(proxydup); /* free the duplicate pointer and not the modified */ +#endif /* end of IPv4-section */ + } + /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a @@ -1581,6 +1628,8 @@ static CURLcode _connect(CURL *curl, * existing one. */ char *path = conn->path; /* setup the current path pointer properly */ + if(conn->proxyhost) + free(conn->proxyhost); free(conn); /* we don't need this new one */ conn = conn_temp; /* use this connection from now on */ free(conn->path); /* free the previous path pointer */ @@ -1591,6 +1640,8 @@ static CURLcode _connect(CURL *curl, conn->maxdownload = 0; /* might have been used previously! */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ + *in_connect = conn; /* return this instead! */ + infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex); } else { @@ -1628,59 +1679,13 @@ static CURLcode _connect(CURL *curl, else if(!conn->hp) { /* This is a proxy that hasn't been resolved yet. It may be resolved if we're reusing an existing connection. */ -#ifdef ENABLE_IPV6 - failf(data, "proxy yet to be supported"); - return CURLE_OUT_OF_MEMORY; -#else - char *prox_portno; - char *endofprot; - - /* We need to make a duplicate of the proxy so that we can modify the - string safely. */ - char *proxydup=strdup(data->proxy); - - /* We use 'proxyptr' to point to the proxy name from now on... */ - char *proxyptr=proxydup; - - if(NULL == proxydup) { - failf(data, "memory shortage"); - return CURLE_OUT_OF_MEMORY; - } - - /* Daniel Dec 10, 1998: - We do the proxy host string parsing here. We want the host name and the - port name. Accept a protocol:// prefix, even though it should just be - ignored. */ - - /* 1. skip the protocol part if present */ - endofprot=strstr(proxyptr, "://"); - if(endofprot) { - proxyptr = endofprot+3; - } - - /* allow user to specify proxy.server.com:1080 if desired */ - prox_portno = strchr (proxyptr, ':'); - if (prox_portno) { - *prox_portno = 0x0; /* cut off number from host name */ - prox_portno ++; - /* now set the local port number */ - conn->port = atoi(prox_portno); - } - else if(data->proxyport) { - /* None given in the proxy string, then get the default one if it is - given */ - conn->port = data->proxyport; - } /* resolve proxy */ - conn->hp = Curl_gethost(data, proxyptr, &conn->hostent_buf); + conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf); if(!conn->hp) { - failf(data, "Couldn't resolve proxy '%s'", proxyptr); + failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); return CURLE_COULDNT_RESOLVE_PROXY; } - - free(proxydup); /* free the duplicate pointer and not the modified */ -#endif } Curl_pgrsTime(data, TIMER_NAMELOOKUP); @@ -1784,25 +1789,24 @@ static CURLcode _connect(CURL *curl, return CURLE_OK; } -CURLcode curl_connect(CURL *curl, CURLconnect **in_connect, +CURLcode Curl_connect(struct UrlData *data, + struct connectdata **in_connect, bool allow_port) { CURLcode code; struct connectdata *conn; /* call the stuff that needs to be called */ - code = _connect(curl, in_connect, allow_port); + code = Connect(data, in_connect, allow_port); if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ conn = (struct connectdata *)*in_connect; if(conn) { - struct UrlData *data; int index; - data = conn->data; index = conn->connectindex; /* get the index */ - curl_disconnect(conn); /* close the connection */ + Curl_disconnect(conn); /* close the connection */ data->connects[index]=NULL; /* clear the pointer */ } } @@ -1810,41 +1814,12 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect, } -/* - * NAME curl_connect() - * - * DESCRIPTION - * - * Connects to the peer server and performs the initial setup. This function - * writes a connect handle to its second argument that is a unique handle for - * this connect. This allows multiple connects from the same handle returned - * by curl_open(). - * - * EXAMPLE - * - * CURLCode result; - * CURL curl; - * CURLconnect connect; - * result = curl_connect(curl, &connect); - */ - - - - -CURLcode curl_done(CURLconnect *c_connect) +CURLcode Curl_done(struct connectdata *conn) { - struct connectdata *conn = c_connect; struct UrlData *data; CURLcode result; int index; - if(!conn || (conn->handle!= STRUCT_CONNECT)) { - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(conn->state != CONN_DO) { - /* This can only be called after a curl_do() */ - return CURLE_BAD_CALLING_ORDER; - } data = conn->data; /* this calls the protocol-specific function pointer previously set */ @@ -1855,48 +1830,25 @@ CURLcode curl_done(CURLconnect *c_connect) Curl_pgrsDone(data); /* done with the operation */ - conn->state = CONN_DONE; - /* if bits.close is TRUE, it means that the connection should be closed in spite of all our efforts to be nice */ if((CURLE_OK == result) && conn->bits.close) { index = conn->connectindex; /* get the index */ - result = curl_disconnect(conn); /* close the connection */ + result = Curl_disconnect(conn); /* close the connection */ data->connects[index]=NULL; /* clear the pointer */ } return result; } -CURLcode curl_do(CURLconnect *in_conn) +CURLcode Curl_do(struct connectdata *conn) { - struct connectdata *conn = in_conn; - CURLcode result; + CURLcode result=CURLE_OK; - if(!conn || (conn->handle!= STRUCT_CONNECT)) { - return CURLE_BAD_FUNCTION_ARGUMENT; - } - switch(conn->state) { - case CONN_INIT: - case CONN_DONE: - /* these two states are OK */ - break; - default: - /* anything else is bad */ - return CURLE_BAD_CALLING_ORDER; - } - - if(conn->curl_do) { + if(conn->curl_do) /* generic protocol-specific function pointer set in curl_connect() */ result = conn->curl_do(conn); - if(result) { - conn->state = CONN_ERROR; - return result; - } - } - - conn->state = CONN_DO; /* we have entered this state */ - return CURLE_OK; + return result; } -- cgit v1.2.1 From e9b763ff05d2eb2f6236e1d59e2d2181254a439c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 9 Mar 2001 16:50:08 +0000 Subject: use the new name and hostname even though an old connection is reused, since we can re-use a proxy connection that actually has different host names on the same connection --- lib/url.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cb0bbe60b..44e2328fb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -200,7 +200,7 @@ CURLcode Curl_open(CURL **curl, char *url) return CURLE_OUT_OF_MEMORY; } - data-> headersize=HEADERSIZE; + data->headersize=HEADERSIZE; data->out = stdout; /* default output to stdout */ data->in = stdin; /* default input from stdin */ @@ -1627,12 +1627,17 @@ static CURLcode Connect(struct UrlData *data, * just allocated before we can move along and use the previously * existing one. */ - char *path = conn->path; /* setup the current path pointer properly */ - if(conn->proxyhost) - free(conn->proxyhost); - free(conn); /* we don't need this new one */ + struct connectdata *old_conn = conn; + char *path = old_conn->path; /* setup the current path pointer properly */ + if(old_conn->proxyhost) + free(old_conn->proxyhost); conn = conn_temp; /* use this connection from now on */ free(conn->path); /* free the previous path pointer */ + + /* we need these pointers if we speak over a proxy */ + conn->name = old_conn->name; + conn->hostname = old_conn->hostname; + conn->path = path; /* use this one */ conn->ppath = path; /* set this too */ @@ -1640,6 +1645,8 @@ static CURLcode Connect(struct UrlData *data, conn->maxdownload = 0; /* might have been used previously! */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ + free(old_conn); /* we don't need this anymore */ + *in_connect = conn; /* return this instead! */ infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex); -- cgit v1.2.1 From 8eb8a0a8e4ee854f063d589fc97bfbf89836a5dd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Mar 2001 09:44:57 +0000 Subject: bugfix: don't use the connectindex if it is -1 --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 44e2328fb..c6e19df02 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1814,7 +1814,8 @@ CURLcode Curl_connect(struct UrlData *data, int index; index = conn->connectindex; /* get the index */ Curl_disconnect(conn); /* close the connection */ - data->connects[index]=NULL; /* clear the pointer */ + if(-1 != index) + data->connects[index]=NULL; /* clear the pointer */ } } return code; -- cgit v1.2.1 From 5bbe18942067f12dcd8745a9fecbc80ae8c1c431 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Mar 2001 10:13:42 +0000 Subject: modified Curl_disconnect() so that it unlinks itself from the data struct, it saves me from more mistakes when the connectindex is -1 ... also, there's no point in having its parent do it as all parents would do it anyway. --- lib/url.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c6e19df02..201d35eeb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -495,6 +495,10 @@ RETSIGTYPE alarmfunc(int signal) CURLcode Curl_disconnect(struct connectdata *conn) { + if(-1 != conn->connectindex) + /* unlink ourselves! */ + conn->data->connects[conn->connectindex] = NULL; + if(conn->curl_disconnect) /* This is set if protocol-specific cleanups should be made */ conn->curl_disconnect(conn); @@ -1810,13 +1814,8 @@ CURLcode Curl_connect(struct UrlData *data, /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ conn = (struct connectdata *)*in_connect; - if(conn) { - int index; - index = conn->connectindex; /* get the index */ + if(conn) Curl_disconnect(conn); /* close the connection */ - if(-1 != index) - data->connects[index]=NULL; /* clear the pointer */ - } } return code; } @@ -1824,11 +1823,8 @@ CURLcode Curl_connect(struct UrlData *data, CURLcode Curl_done(struct connectdata *conn) { - struct UrlData *data; + struct UrlData *data=conn->data; CURLcode result; - int index; - - data = conn->data; /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) @@ -1840,11 +1836,8 @@ CURLcode Curl_done(struct connectdata *conn) /* if bits.close is TRUE, it means that the connection should be closed in spite of all our efforts to be nice */ - if((CURLE_OK == result) && conn->bits.close) { - index = conn->connectindex; /* get the index */ + if((CURLE_OK == result) && conn->bits.close) result = Curl_disconnect(conn); /* close the connection */ - data->connects[index]=NULL; /* clear the pointer */ - } return result; } -- cgit v1.2.1 From d774b10afb1ac27f255a4c1507ce89778faf6f94 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Mar 2001 13:58:03 +0000 Subject: Added infof() calls for persistant connection info, we are very likely to need these at least for debugging 7.7 and probably later as well... --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 201d35eeb..aebb2b604 100644 --- a/lib/url.c +++ b/lib/url.c @@ -495,6 +495,8 @@ RETSIGTYPE alarmfunc(int signal) CURLcode Curl_disconnect(struct connectdata *conn) { + infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex); + if(-1 != conn->connectindex) /* unlink ourselves! */ conn->data->connects[conn->connectindex] = NULL; @@ -1838,6 +1840,8 @@ CURLcode Curl_done(struct connectdata *conn) in spite of all our efforts to be nice */ if((CURLE_OK == result) && conn->bits.close) result = Curl_disconnect(conn); /* close the connection */ + else + infof(data, "Connection (#%d) left alive\n", conn->connectindex); return result; } -- cgit v1.2.1 From 38c349f75101a1f47c3268e13396b61e3fade8e4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Mar 2001 15:05:54 +0000 Subject: support for a few new libcurl 7.7 CURLOPT_* options added --- lib/url.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 275 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index aebb2b604..802a5d2d4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -250,117 +250,275 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) va_start(param, option); switch(option) { + case CURLOPT_MAXCONNECTS: + /* + * Set the absolute number of maximum simultaneous alive connection that + * libcurl is allowed to have. + */ + { + long newconnects= va_arg(param, long); + struct connectdata **newptr; + + if(newconnects < data->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]); + } + if(newconnects) { + newptr= (struct connectdata **) + realloc(data->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; + } + else { + /* zero makes NO cache at all */ + if(data->connects) + free(data->connects); + data->connects=NULL; + data->numconnects=0; + } + } + break; + case CURLOPT_FORBID_REUSE: + /* + * 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; + 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; + 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; 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; 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->progress.flags |= PGRS_HIDE; break; case CURLOPT_NOBODY: + /* + * Do not include the body part in the output data stream. + */ data->bits.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; 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) /* If this is HTTP, PUT is what's needed to "upload" */ data->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; 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; 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; break; case CURLOPT_NETRC: + /* + * Parse the $HOME/.netrc file + */ data->bits.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; break; case CURLOPT_FTPASCII: + /* + * Transfer FTP using ASCII instead of BINARY. + */ data->bits.ftp_ascii = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_PUT: + /* + * Use the HTTP PUT request to transfer data. + */ data->bits.http_put = va_arg(param, long)?TRUE:FALSE; if(data->bits.http_put) data->httpreq = HTTPREQ_PUT; break; case CURLOPT_MUTE: + /* + * Stay absolutely quiet. + */ data->bits.mute = va_arg(param, long)?TRUE:FALSE; break; 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); 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); 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); break; case CURLOPT_COOKIEFILE: + /* + * Set cookie file to read and parse. + */ cookiefile = (char *)va_arg(param, void *); if(cookiefile) { data->cookies = Curl_cookie_init(cookiefile); } break; case CURLOPT_WRITEHEADER: + /* + * Callback function for header data + */ data->writeheader = (FILE *)va_arg(param, FILE *); break; case CURLOPT_COOKIE: + /* + * Cookie string to send to the remote server in the request. + */ data->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 *); break; case CURLOPT_FILE: + /* + * FILE pointer to write to or include in the data write callback + */ data->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; break; case CURLOPT_HTTPHEADER: + /* + * Set a list with HTTP headers to use (or replace internals with) + */ data->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; break; case CURLOPT_HTTPPOST: + /* + * Set to make us do HTTP POST + */ data->httppost = va_arg(param, struct HttpPost *); data->bits.http_formpost = data->httppost?1:0; if(data->bits.http_formpost) data->httpreq = HTTPREQ_POST_FORM; 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 *); 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); 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); 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); break; case CURLOPT_URL: + /* + * The URL to fetch. + */ data->url = va_arg(param, char *); break; case CURLOPT_PORT: + /* + * The port number to use when getting the URL + */ data->use_port = va_arg(param, long); break; case CURLOPT_POST: @@ -370,107 +528,206 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) data->httpreq = HTTPREQ_POST; break; case CURLOPT_POSTFIELDS: + /* + * A string with POST data. Makes curl HTTP POST. + */ data->postfields = va_arg(param, char *); data->bits.http_post = data->postfields?TRUE:FALSE; if(data->bits.http_post) data->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); 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; 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; break; case CURLOPT_PROXY: + /* + * Set proxy server:port to use as HTTP proxy + */ data->proxy = va_arg(param, char *); data->bits.httpproxy = data->proxy?1:0; 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; break; case CURLOPT_PROXYPORT: + /* + * Explicitly set HTTP proxy port number. + */ data->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); 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); break; case CURLOPT_USERAGENT: + /* + * String to use in the HTTP User-Agent field + */ data->useragent = va_arg(param, char *); break; case CURLOPT_USERPWD: + /* + * user:password to use in the operation + */ data->userpwd = va_arg(param, char *); data->bits.user_passwd = data->userpwd?1:0; break; case CURLOPT_POSTQUOTE: + /* + * List of RAW FTP commands to use after a transfer + */ data->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 *); + break; case CURLOPT_PROGRESSFUNCTION: + /* + * Progress callback function + */ data->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 *); break; case CURLOPT_PASSWDFUNCTION: + /* + * Password prompt callback + */ data->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 *); break; case CURLOPT_PROXYUSERPWD: + /* + * user:password needed to use the proxy + */ data->proxyuserpwd = va_arg(param, char *); data->bits.proxy_user_passwd = data->proxyuserpwd?1:0; break; case CURLOPT_RANGE: + /* + * What range of the file you want to transfer + */ data->range = va_arg(param, char *); data->bits.set_range = data->range?1:0; break; case CURLOPT_RESUME_FROM: + /* + * Resume transfer at the give file position + */ data->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 *); break; case CURLOPT_WRITEFUNCTION: + /* + * Set data write callback + */ data->fwrite = va_arg(param, curl_write_callback); break; case CURLOPT_READFUNCTION: + /* + * Read data callback + */ data->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 *); break; case CURLOPT_SSLCERTPASSWD: + /* + * String that holds the SSL certificate password. + */ data->cert_passwd = va_arg(param, char *); break; case CURLOPT_CRLF: + /* + * Kludgy option to enable CRLF convertions. Subject for + * removal. + */ data->crlf = va_arg(param, long); break; - case CURLOPT_QUOTE: - data->quote = va_arg(param, struct curl_slist *); - 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 *); 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; break; case CURLOPT_SSL_VERIFYPEER: + /* + * Enable peer SSL verifying. + */ data->ssl.verifypeer = 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.*/ break; case CURLOPT_TELNETOPTIONS: + /* + * Set a linked list of telnet options + */ data->telnet_options = va_arg(param, struct curl_slist *); break; default: @@ -495,6 +752,9 @@ RETSIGTYPE alarmfunc(int signal) CURLcode Curl_disconnect(struct connectdata *conn) { + if(!conn) + return CURLE_OK; /* this is closed and fine already */ + infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex); if(-1 != conn->connectindex) @@ -1626,7 +1886,10 @@ static CURLcode Connect(struct UrlData *data, * new one. *************************************************************/ - if(ConnectionExists(data, conn, &conn_temp)) { + /* reuse_fresh is set TRUE if we are told to use a fresh connection + by force */ + if(!data->bits.reuse_fresh && + ConnectionExists(data, conn, &conn_temp)) { /* * We already have a connection for this, we got the former connection * in the conn_temp variable and thus we need to cleanup the one we @@ -1836,9 +2099,14 @@ CURLcode Curl_done(struct connectdata *conn) Curl_pgrsDone(data); /* done with the operation */ - /* if bits.close is TRUE, it means that the connection should be closed - in spite of all our efforts to be nice */ - if((CURLE_OK == result) && conn->bits.close) + /* if data->bits.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 || + ((CURLE_OK == result) && conn->bits.close)) result = Curl_disconnect(conn); /* close the connection */ else infof(data, "Connection (#%d) left alive\n", conn->connectindex); -- cgit v1.2.1 From f2fd1b8856559ef9a8dfb2d996fa452e4ee6f41a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Mar 2001 15:47:17 +0000 Subject: two new random seed options: CURLOPT_RANDOM_FILE and CURLOPT_EGDSOCKET --- lib/url.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 802a5d2d4..3194cbe20 100644 --- a/lib/url.c +++ b/lib/url.c @@ -250,6 +250,19 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) va_start(param, option); switch(option) { + case CURLOPT_RANDOM_FILE: + /* + * 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 *); + break; + case CURLOPT_EGDSOCKET: + /* + * The Entropy Gathering Daemon socket pathname + */ + data->ssl.egdsocket = va_arg(param, char *); + break; case CURLOPT_MAXCONNECTS: /* * Set the absolute number of maximum simultaneous alive connection that -- cgit v1.2.1 From 87b0b7cab9924848aa7be2fc154379b39356132b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Mar 2001 07:54:18 +0000 Subject: initial close policy support --- lib/url.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3194cbe20..fc9b33e15 100644 --- a/lib/url.c +++ b/lib/url.c @@ -941,6 +941,9 @@ ConnectionKillOne(struct UrlData *data) int connindex=-1; int score; CURLcode result; + struct timeval now; + + now = Curl_tvnow(); for(i=0; i< data->numconnects; i++) { conn = data->connects[i]; @@ -952,8 +955,20 @@ ConnectionKillOne(struct UrlData *data) * By using the set policy, we score each connection. */ switch(data->closepolicy) { + case CURLCLOSEPOLICY_LEAST_RECENTLY_USED: default: - score = 1; /* not implemented yet */ + /* + * Set higher score for the age passed since the connection + * was used. + */ + score = Curl_tvlong(now) - Curl_tvlong(conn->now); + break; + case CURLCLOSEPOLICY_OLDEST: + /* + * Set higher score for the age passed since the connection + * was created. + */ + score = Curl_tvlong(now) - Curl_tvlong(conn->created); break; } @@ -1269,11 +1284,13 @@ static CURLcode Connect(struct UrlData *data, conn->connectindex = -1; /* no index */ conn->bits.httpproxy = data->bits.httpproxy; /* proxy-or-not status */ - /* Default protocol-indepent behaveiour doesn't support persistant + /* Default protocol-independent behavior doesn't support persistant connections, so we set this to force-close. Protocols that support this need to set this to FALSE in their "curl_do" functions. */ conn->bits.close = TRUE; + /* Store creation time to help future close decision making */ + conn->created = Curl_tvnow(); /*********************************************************** * We need to allocate memory to store the path in. We get the size of the -- cgit v1.2.1 From f8e1fc32de60c5f4c30d20d2bc8c55ac13405752 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 14 Mar 2001 14:11:11 +0000 Subject: Edin Kadribaic's bug report #408488 forced a rearrange of two struct fields from urldata to connectdata, quite correctly. --- lib/url.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fc9b33e15..7d57bcb37 100644 --- a/lib/url.c +++ b/lib/url.c @@ -613,7 +613,6 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) * user:password to use in the operation */ data->userpwd = va_arg(param, char *); - data->bits.user_passwd = data->userpwd?1:0; break; case CURLOPT_POSTQUOTE: /* @@ -657,7 +656,6 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) * user:password needed to use the proxy */ data->proxyuserpwd = va_arg(param, char *); - data->bits.proxy_user_passwd = data->proxyuserpwd?1:0; break; case CURLOPT_RANGE: /* @@ -1288,10 +1286,15 @@ static CURLcode Connect(struct UrlData *data, connections, so we set this to force-close. Protocols that support this need to set this to FALSE in their "curl_do" functions. */ 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; /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); + /*********************************************************** * We need to allocate memory to store the path in. We get the size of the * full URL to be sure, and we need to make it at least 256 bytes since @@ -1406,7 +1409,7 @@ static CURLcode Connect(struct UrlData *data, * Take care of user and password authentication stuff *************************************************************/ - if(data->bits.user_passwd && !data->bits.use_netrc) { + if(conn->bits.user_passwd && !data->bits.use_netrc) { data->user[0] =0; data->passwd[0]=0; @@ -1431,7 +1434,7 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * Take care of proxy authentication stuff *************************************************************/ - if(data->bits.proxy_user_passwd) { + if(conn->bits.proxy_user_passwd) { data->proxyuser[0] =0; data->proxypasswd[0]=0; @@ -1754,7 +1757,7 @@ static CURLcode Connect(struct UrlData *data, conn->hostname); } else - data->bits.user_passwd = 1; /* enable user+password */ + conn->bits.user_passwd = 1; /* enable user+password */ /* weather we failed or not, we don't know which fields that were filled in anyway */ @@ -1763,7 +1766,7 @@ static CURLcode Connect(struct UrlData *data, if(!data->passwd[0]) strcpy(data->passwd, CURL_DEFAULT_PASSWORD); } - else if(!(data->bits.user_passwd) && + else if(!(conn->bits.user_passwd) && (conn->protocol & (PROT_FTP|PROT_HTTP)) ) { /* This is a FTP or HTTP URL, and we haven't got the user+password in * the extra parameter, we will now try to extract the possible @@ -1812,7 +1815,7 @@ static CURLcode Connect(struct UrlData *data, } conn->name = ++ptr; - data->bits.user_passwd=1; /* enable user+password */ + conn->bits.user_passwd=TRUE; /* enable user+password */ } else { strcpy(data->user, CURL_DEFAULT_USER); @@ -1998,7 +2001,7 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * Proxy authentication *************************************************************/ - if(data->bits.proxy_user_passwd) { + if(conn->bits.proxy_user_passwd) { char *authorization; snprintf(data->buffer, BUFSIZE, "%s:%s", data->proxyuser, data->proxypasswd); -- cgit v1.2.1 From b7fc1e45b52b09dd6eb78eec584eab63c6343c63 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 14 Mar 2001 18:18:02 +0000 Subject: now works with IPv6 and HTTP proxy --- lib/url.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7d57bcb37..b6339826d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -766,11 +766,11 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(!conn) return CURLE_OK; /* this is closed and fine already */ - infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex); - - if(-1 != conn->connectindex) + if(-1 != conn->connectindex) { /* unlink ourselves! */ + infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex); conn->data->connects[conn->connectindex] = NULL; + } if(conn->curl_disconnect) /* This is set if protocol-specific cleanups should be made */ @@ -1162,12 +1162,14 @@ static CURLcode ConnectPlease(struct UrlData *data, #ifdef ENABLE_IPV6 conn->firstsocket = -1; for (ai = conn->hp; ai; ai = ai->ai_next) { - conn->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + conn->firstsocket = socket(ai->ai_family, + ai->ai_socktype, + ai->ai_protocol); if (conn->firstsocket < 0) continue; if (connect(conn->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { - close(conn->firstsocket); + sclose(conn->firstsocket); conn->firstsocket = -1; continue; } @@ -1862,10 +1864,6 @@ static CURLcode Connect(struct UrlData *data, host name name, so that we can re-use an existing connection that may exist registered to the same proxy host. */ -#ifdef ENABLE_IPV6 - failf(data, "proxy yet to be supported"); - return CURLE_OUT_OF_MEMORY; -#else char *prox_portno; char *endofprot; @@ -1910,7 +1908,6 @@ static CURLcode Connect(struct UrlData *data, conn->proxyhost = strdup(proxyptr); free(proxydup); /* free the duplicate pointer and not the modified */ -#endif /* end of IPv4-section */ } /************************************************************* @@ -1990,7 +1987,12 @@ static CURLcode Connect(struct UrlData *data, if we're reusing an existing connection. */ /* resolve proxy */ +#ifdef ENABLE_IPV6 + /* it might already be set if reusing a connection */ + conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port); +#else conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf); +#endif if(!conn->hp) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); return CURLE_COULDNT_RESOLVE_PROXY; -- cgit v1.2.1 From d6c456db85858bf111ceeb5f3c2b5a9b4e9f03c7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 15 Mar 2001 14:38:30 +0000 Subject: added connect timeout support --- lib/url.c | 88 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 38 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b6339826d..b8c42325f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -122,6 +122,19 @@ static unsigned int ConnectionStore(struct UrlData *data, struct connectdata *conn); +#if !defined(WIN32)||defined(__CYGWIN32__) +#ifndef RETSIGTYPE +#define RETSIGTYPE void +#endif +static +RETSIGTYPE alarmfunc(int signal) +{ + /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ + (void)signal; + return; +} +#endif + CURLcode Curl_close(CURL *curl) { struct UrlData *data=(struct UrlData *)curl; @@ -186,6 +199,9 @@ CURLcode Curl_open(CURL **curl, char *url) { /* We don't yet support specifying the URL at this point */ struct UrlData *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)); @@ -234,6 +250,26 @@ CURLcode Curl_open(CURL **curl, char *url) memset(data->connects, 0, sizeof(struct connectdata *)*data->numconnects); *curl = data; + + /************************************************************* + * Set signal handler + *************************************************************/ +#ifdef HAVE_SIGACTION + sigaction(SIGALRM, NULL, &sigact); + sigact.sa_handler = alarmfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; +#endif + sigaction(SIGALRM, &sigact, NULL); +#else + /* no sigaction(), revert to the much lamer signal() */ +#ifdef HAVE_SIGNAL + signal(SIGALRM, alarmfunc); +#endif + +#endif + return CURLE_OK; } @@ -595,6 +631,12 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) */ data->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); + break; case CURLOPT_MAXREDIRS: /* * The maximum amount of hops you allow curl to follow Location: @@ -748,19 +790,6 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) return CURLE_OK; } -#if !defined(WIN32)||defined(__CYGWIN32__) -#ifndef RETSIGTYPE -#define RETSIGTYPE void -#endif -static -RETSIGTYPE alarmfunc(int signal) -{ - /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ - (void)signal; - return; -} -#endif - CURLcode Curl_disconnect(struct connectdata *conn) { if(!conn) @@ -1246,9 +1275,6 @@ static CURLcode Connect(struct UrlData *data, struct connectdata *conn; struct connectdata *conn_temp; char endbracket; -#ifdef HAVE_SIGACTION - struct sigaction sigact; -#endif int urllen; /************************************************************* @@ -1388,25 +1414,6 @@ static CURLcode Connect(struct UrlData *data, buf = data->buffer; /* this is our buffer */ - /************************************************************* - * Set signal handler - *************************************************************/ -#ifdef HAVE_SIGACTION - sigaction(SIGALRM, NULL, &sigact); - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - sigaction(SIGALRM, &sigact, NULL); -#else - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - signal(SIGALRM, alarmfunc); -#endif - -#endif - /************************************************************* * Take care of user and password authentication stuff *************************************************************/ @@ -1603,11 +1610,16 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * Set timeout if that is being used *************************************************************/ - if(data->timeout) { + if(data->timeout || data->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(data->timeout); /* this sends a signal when the timeout fires - off, and that will abort system calls */ + + /* myalarm() makes a signal get sent when the timeout fires off, and that + will abort system calls */ + if(data->connecttimeout) + myalarm(data->connecttimeout); + else + myalarm(data->timeout); } /************************************************************* -- cgit v1.2.1 From 76576cd1e28ad07f098de464f6da1c93e262f652 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Mar 2001 07:46:14 +0000 Subject: ConnectionExists() wrongly returned TRUE for too many connections if proxy was not used... --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b8c42325f..d7f1f004f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -936,9 +936,11 @@ ConnectionExists(struct UrlData *data, data->connects[i]=NULL; /* nothing here */ continue; /* try another one now */ } + + *usethis = check; + return TRUE; /* yes, we found one to use! */ + } - *usethis = check; - return TRUE; /* yes, we found one to use! */ } else { /* The requested needle connection is using a proxy, is the checked one using the same? */ -- cgit v1.2.1 From b1328430c9f73bededc274ce8bac5aa8f36f7afe Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Mar 2001 08:16:55 +0000 Subject: ftps:// support added --- lib/url.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d7f1f004f..2840d32e5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1399,6 +1399,8 @@ static CURLcode Connect(struct UrlData *data, #ifdef USE_SSLEAY else if(strnequal(conn->gname, "HTTPS", 5)) strcpy(conn->protostr, "https"); + else if(strnequal(conn->gname, "FTPS", 4)) + strcpy(conn->protostr, "ftps"); #endif /* USE_SSLEAY */ else if(strnequal(conn->gname, "TELNET", 6)) strcpy(conn->protostr, "telnet"); @@ -1668,8 +1670,19 @@ static CURLcode Connect(struct UrlData *data, conn->curl_done = Curl_http_done; conn->curl_close = Curl_http_close; } - else if(strequal(conn->protostr, "FTP")) { + else if(strequal(conn->protostr, "FTP") || + strequal(conn->protostr, "FTPS")) { char *type; + + if(strequal(conn->protostr, "FTPS")) { +#ifdef USE_SSLEAY + conn->protocol |= PROT_FTPS; +#else + failf(data, "libcurl was built with SSL disabled, ftps: not supported!"); + return CURLE_UNSUPPORTED_PROTOCOL; +#endif /* !USE_SSLEAY */ + } + conn->port = (data->use_port && allow_port)?data->use_port:PORT_FTP; conn->remote_port = PORT_FTP; conn->protocol |= PROT_FTP; @@ -1678,6 +1691,12 @@ static CURLcode Connect(struct UrlData *data, !data->bits.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) { + /* FTPS is a hacked protocol and does not work through your + ordinary http proxy! */ + failf(data, "ftps does not work through http proxy!"); + return CURLE_UNSUPPORTED_PROTOCOL; + } conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; conn->curl_close = Curl_http_close; -- cgit v1.2.1 From 28497e7ee40e8e2bf3c50f20c311bf9abff34ea6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Apr 2001 10:20:23 +0000 Subject: better error checks for failure conditions (based on Puneet Pawaia's reports) --- lib/url.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2840d32e5..5bb34be71 100644 --- a/lib/url.c +++ b/lib/url.c @@ -816,6 +816,9 @@ CURLcode Curl_disconnect(struct connectdata *conn) free(conn->hostent_buf); #endif + if(conn->newurl) + free(conn->newurl); + if(conn->path) /* the URL path part */ free(conn->path); @@ -2147,8 +2150,10 @@ CURLcode Curl_connect(struct UrlData *data, /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ conn = (struct connectdata *)*in_connect; - if(conn) + if(conn) { Curl_disconnect(conn); /* close the connection */ + *in_connect = NULL; /* return a NULL */ + } } return code; } -- cgit v1.2.1 From 90bb87b40eb935e6cc833b677abec4cabe06c884 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Apr 2001 06:51:25 +0000 Subject: setopt() works with the new CURLOPT_HEADERFUNCTION: --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5bb34be71..80469587e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -719,6 +719,12 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) */ data->err = va_arg(param, FILE *); break; + case CURLOPT_HEADERFUNCTION: + /* + * Set header write callback + */ + data->fwrite_header = va_arg(param, curl_write_callback); + break; case CURLOPT_WRITEFUNCTION: /* * Set data write callback -- cgit v1.2.1 From 022099266ea8d2cbe2abef54f39b1df1322f4d68 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Apr 2001 06:41:54 +0000 Subject: SM made the connection timeout work for windows boxes! --- lib/url.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 80469587e..7e771e75f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1060,6 +1060,11 @@ ConnectionStore(struct UrlData *data, static CURLcode ConnectPlease(struct UrlData *data, struct connectdata *conn) { +#if defined(WIN32) + unsigned long nonblock = 0; + fd_set connectfd; + struct timeval conntimeout; +#endif #ifndef ENABLE_IPV6 conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); @@ -1222,10 +1227,29 @@ static CURLcode ConnectPlease(struct UrlData *data, return CURLE_COULDNT_CONNECT; } #else + /* non-zero nonblock value sets socket as nonblocking under Win32 */ +#if defined(WIN32) + FD_ZERO (&connectfd); + FD_SET(conn->firstsocket, &connectfd); + if (conn->data->connecttimeout > 0) { + nonblock = 1; + } + ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); +#endif if (connect(conn->firstsocket, (struct sockaddr *) &(conn->serv_addr), sizeof(conn->serv_addr) ) < 0) { +#if defined(WIN32) + conntimeout.tv_sec = conn->data->connecttimeout; + conntimeout.tv_usec = 0; + if(-1 != select (conn->firstsocket + 1, NULL, &connectfd, NULL, &conntimeout)) { + if (FD_ISSET(conn->firstsocket, &connectfd)) + return CURLE_OK; + else + errno = EINTR; + } +#endif switch(errno) { #ifdef ECONNREFUSED /* this should be made nicer */ -- cgit v1.2.1 From 62056a644f712c47d56fa9ddcebda2539c4609a6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Apr 2001 06:59:00 +0000 Subject: oops, missed the shut-off non-blocking fix --- lib/url.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7e771e75f..0a01e54d2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1232,7 +1232,7 @@ static CURLcode ConnectPlease(struct UrlData *data, FD_ZERO (&connectfd); FD_SET(conn->firstsocket, &connectfd); if (conn->data->connecttimeout > 0) { - nonblock = 1; + nonblock = 1; } ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); #endif @@ -1241,14 +1241,18 @@ static CURLcode ConnectPlease(struct UrlData *data, sizeof(conn->serv_addr) ) < 0) { #if defined(WIN32) - conntimeout.tv_sec = conn->data->connecttimeout; - conntimeout.tv_usec = 0; - if(-1 != select (conn->firstsocket + 1, NULL, &connectfd, NULL, &conntimeout)) { - if (FD_ISSET(conn->firstsocket, &connectfd)) - return CURLE_OK; - else - errno = EINTR; - } + conntimeout.tv_sec = conn->data->connecttimeout; + conntimeout.tv_usec = 0; + if(-1 != select (conn->firstsocket + 1, NULL, &connectfd, NULL, &conntimeout)) { + if (FD_ISSET(conn->firstsocket, &connectfd)) { + /* shut off non-blocking again */ + nonblock = 0; + ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); + return CURLE_OK; + } + else + errno = EINTR; + } #endif switch(errno) { #ifdef ECONNREFUSED -- cgit v1.2.1 From 18f044f19d26f2b6dcd41796966f488a62a1bdca Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Apr 2001 14:13:52 +0000 Subject: we don't use the HTTP_PROXY environment variable in uppercase anymore, since it might become a security problem (Bugs item #415391) --- lib/url.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0a01e54d2..8880c1eb2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1579,7 +1579,19 @@ static CURLcode Connect(struct UrlData *data, /* read the protocol proxy: */ prox=curl_getenv(proxy_env); - if(!prox) { + /* + * We don't try the uppercase version of HTTP_PROXY because of + * security reasons: + * + * When curl is used in a webserver application + * environment (cgi or php), this environment variable can + * be controlled by the web server user by setting the + * http header 'Proxy:' to some value. + * + * This can cause 'internal' http/ftp requests to be + * arbitrarily redirected by any external attacker. + */ + if(!prox && !strequal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ for(envp = proxy_env; *envp; envp++) *envp = toupper(*envp); -- cgit v1.2.1 From 3fd65fb7d83a8e3e6acd1a40c48b46088ebd536f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 18 Apr 2001 07:25:11 +0000 Subject: Remade resume stuff to keep data in the connectdata struct instead of the main handle struct to work with persistant connections --- lib/url.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8880c1eb2..4fa180dea 100644 --- a/lib/url.c +++ b/lib/url.c @@ -153,13 +153,6 @@ CURLcode Curl_close(CURL *curl) data->bits.httpproxy=FALSE; } - - if(data->bits.rangestringalloc) { - free(data->range); - data->range=NULL; - data->bits.rangestringalloc=0; /* free now */ - } - /* check for allocated [URL] memory to free: */ if(data->freethis) free(data->freethis); @@ -703,14 +696,14 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) /* * What range of the file you want to transfer */ - data->range = va_arg(param, char *); - data->bits.set_range = data->range?1:0; + data->set_range = va_arg(param, char *); + data->bits.set_range = data->set_range?1:0; break; case CURLOPT_RESUME_FROM: /* * Resume transfer at the give file position */ - data->resume_from = va_arg(param, long); + data->set_resume_from = va_arg(param, long); break; case CURLOPT_STDERR: /* @@ -801,6 +794,16 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(!conn) return CURLE_OK; /* this is closed and fine already */ + /* + * The range string is usually freed in curl_done(), but we might + * get here *instead* if we fail prematurely. Thus we need to be able + * to free this resource here as well. + */ + if(conn->bits.rangestringalloc) { + free(conn->range); + conn->bits.rangestringalloc = FALSE; + } + if(-1 != conn->connectindex) { /* unlink ourselves! */ infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex); @@ -1348,6 +1351,9 @@ static CURLcode Connect(struct UrlData *data, 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 */ /* Default protocol-independent behavior doesn't support persistant connections, so we set this to force-close. Protocols that support @@ -1650,13 +1656,13 @@ static CURLcode Connect(struct UrlData *data, * server, we just fail since we can't rewind the file writing from within * this function. ***********************************************************/ - if(data->resume_from) { - if(!data->bits.set_range) { + if(conn->resume_from) { + if(!conn->bits.use_range) { /* if it already was in use, we just skip this */ - snprintf(resumerange, sizeof(resumerange), "%d-", data->resume_from); - data->range=strdup(resumerange); /* tell ourselves to fetch this range */ - data->bits.rangestringalloc = TRUE; /* mark as allocated */ - data->bits.set_range = 1; /* switch on range usage */ + snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from); + conn->range=strdup(resumerange); /* tell ourselves to fetch this range */ + conn->bits.rangestringalloc = TRUE; /* mark as allocated */ + conn->bits.use_range = 1; /* switch on range usage */ } } @@ -2210,13 +2216,20 @@ CURLcode Curl_done(struct connectdata *conn) struct UrlData *data=conn->data; CURLcode result; + /* cleanups done even if the connection is re-used */ + + if(conn->bits.rangestringalloc) { + free(conn->range); + conn->bits.rangestringalloc = FALSE; + } + /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) result = conn->curl_done(conn); else result = CURLE_OK; - Curl_pgrsDone(data); /* done with the operation */ + Curl_pgrsDone(conn); /* done with the operation */ /* if data->bits.reuse_forbid is TRUE, it means the libcurl client has forced us to close this no matter what we think. -- cgit v1.2.1 From 2cf26d4fb7e8a15a08f5922ba0a46b7332d3fdc4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 22 Apr 2001 16:47:55 +0000 Subject: copy the name properly when re-using a connection --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4fa180dea..44d4adef4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2022,8 +2022,9 @@ static CURLcode Connect(struct UrlData *data, free(conn->path); /* free the previous path pointer */ /* we need these pointers if we speak over a proxy */ - conn->name = old_conn->name; - conn->hostname = old_conn->hostname; + strcpy(conn->gname, old_conn->gname); /* copy the name */ + conn->name = conn->gname; + conn->hostname = old_conn->gname; conn->path = path; /* use this one */ conn->ppath = path; /* set this too */ -- cgit v1.2.1 From fde31f0988bebc963260294e4d048cdd0c5aeb99 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Apr 2001 06:11:08 +0000 Subject: no need to copy the name when re-using the connection, we already have the same name in that buffer from the URL parsing! --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 44d4adef4..013ebac70 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2022,7 +2022,6 @@ static CURLcode Connect(struct UrlData *data, free(conn->path); /* free the previous path pointer */ /* we need these pointers if we speak over a proxy */ - strcpy(conn->gname, old_conn->gname); /* copy the name */ conn->name = conn->gname; conn->hostname = old_conn->gname; -- cgit v1.2.1 From 583c2e2f092937d6f3978fb63130d0db9262d507 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 25 Apr 2001 21:24:27 +0000 Subject: connection re-using didn't work on non-default ports when not using proxy until now --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 013ebac70..d85c61404 100644 --- a/lib/url.c +++ b/lib/url.c @@ -930,7 +930,7 @@ ConnectionExists(struct UrlData *data, if(strequal(needle->protostr, check->protostr) && strequal(needle->name, check->name) && - (needle->port == check->port) ) { + (needle->remote_port == check->remote_port) ) { bool dead; if(strequal(needle->protostr, "FTP")) { /* This is FTP, verify that we're using the same name and -- cgit v1.2.1 From 3974f30ed466c1ec8430061574f9c3530982660d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 27 Apr 2001 08:02:10 +0000 Subject: improved treatment of "Content-Length: 0", which is done by having maxdownload set to -1 when not used --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d85c61404..924f342bb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1364,6 +1364,9 @@ static CURLcode Connect(struct UrlData *data, conn->bits.user_passwd = data->userpwd?1:0; conn->bits.proxy_user_passwd = data->proxyuserpwd?1:0; + /* maxdownload must be -1 on init, as 0 is a valid value! */ + conn->maxdownload = -1; /* might have been used previously! */ + /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); @@ -2029,8 +2032,8 @@ static CURLcode Connect(struct UrlData *data, conn->ppath = path; /* set this too */ /* re-use init */ - conn->maxdownload = 0; /* might have been used previously! */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ + conn->maxdownload = -1; /* might have been used previously! */ free(old_conn); /* we don't need this anymore */ -- cgit v1.2.1 From 350c536f6c6b5f7179ffcce19f195a94b0c83fd7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 May 2001 10:53:01 +0000 Subject: Cris Bailiff's fix to disable chunked transfers on re-used persistent connections. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 924f342bb..c54cfe8d0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2033,6 +2033,7 @@ static CURLcode Connect(struct UrlData *data, /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ + conn->bits.chunk = FALSE; /* always assume not chunked unless told otherwise */ conn->maxdownload = -1; /* might have been used previously! */ free(old_conn); /* we don't need this anymore */ -- cgit v1.2.1 From 9304055df518e5b9c85bd4559fcff12b09fed0f0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 4 May 2001 07:47:11 +0000 Subject: 'FILE *' changed to 'void *' in all callback functions --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c54cfe8d0..3fef8b651 100644 --- a/lib/url.c +++ b/lib/url.c @@ -216,10 +216,10 @@ CURLcode Curl_open(CURL **curl, char *url) data->err = stderr; /* default stderr to stderr */ /* use fwrite as default function to store output */ - data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))fwrite; + data->fwrite = (curl_write_callback)fwrite; /* use fread as default function to read input */ - data->fread = (size_t (*)(char *, size_t, size_t, FILE *))fread; + data->fread = (curl_read_callback)fread; /* set the default passwd function */ data->fpasswd = my_getpass; -- cgit v1.2.1 From 7be8993f9429db4cd3633cce941d066922c25189 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 10 May 2001 09:31:48 +0000 Subject: When re-using a connection, the path pointers were not setup properly so that multiple FTP transfers were not possible --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3fef8b651..8c23ae998 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2022,14 +2022,20 @@ static CURLcode Connect(struct UrlData *data, if(old_conn->proxyhost) free(old_conn->proxyhost); conn = conn_temp; /* use this connection from now on */ - free(conn->path); /* free the previous path pointer */ /* we need these pointers if we speak over a proxy */ conn->name = conn->gname; conn->hostname = old_conn->gname; conn->path = path; /* use this one */ - conn->ppath = path; /* set this too */ + + /* The 'ppath' may have been advanced a few steps from the 'path' start + point. We must also advance our new pointer as many steps as the + previous one was! This was the cause of the multiple ftp file bug + found on May 9 2001 libcurl 7.7.3 */ + conn->ppath = (old_conn->ppath - old_conn->path)+path; + + free(old_conn->path); /* free the previous path pointer */ /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ -- cgit v1.2.1 From fef1fc0d32455fe4d04250862bce607900c1439e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 May 2001 06:10:48 +0000 Subject: Ingo Wilken's redirect fixes --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8c23ae998..787bc18be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2233,6 +2233,12 @@ CURLcode Curl_done(struct connectdata *conn) conn->bits.rangestringalloc = FALSE; } + /* Cleanup possible redirect junk */ + if(conn->newurl) { + free(conn->newurl); + conn->newurl = NULL; + } + /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) result = conn->curl_done(conn); -- cgit v1.2.1 From 282939c6fe6d6ca443aacfcabd867e63ad8c4682 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 May 2001 06:40:04 +0000 Subject: another multiple FTP transfer fix --- lib/url.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 787bc18be..2e8b8b695 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2019,6 +2019,7 @@ static CURLcode Connect(struct UrlData *data, */ 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); conn = conn_temp; /* use this connection from now on */ @@ -2027,19 +2028,17 @@ static CURLcode Connect(struct UrlData *data, conn->name = conn->gname; conn->hostname = old_conn->gname; - conn->path = path; /* use this one */ + free(conn->path); /* free the previously allocated path pointer */ - /* The 'ppath' may have been advanced a few steps from the 'path' start - point. We must also advance our new pointer as many steps as the - previous one was! This was the cause of the multiple ftp file bug - found on May 9 2001 libcurl 7.7.3 */ - conn->ppath = (old_conn->ppath - old_conn->path)+path; - - free(old_conn->path); /* free the previous 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; /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ - conn->bits.chunk = FALSE; /* always assume not chunked unless told otherwise */ + conn->bits.chunk = FALSE; /* always assume not chunked unless told + otherwise */ conn->maxdownload = -1; /* might have been used previously! */ free(old_conn); /* we don't need this anymore */ -- cgit v1.2.1 From 8526fa97ce02e55e480c8d29e50e1d0ac31934ee Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 15 May 2001 07:21:13 +0000 Subject: Pawel A. Gajda fixed resumed transfers on persistent connections --- lib/url.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2e8b8b695..364e10881 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2043,6 +2043,21 @@ static CURLcode Connect(struct UrlData *data, free(old_conn); /* we don't need this anymore */ + /* + * If we're doing a resumed transfer, we need to setup our stuff + * properly. + */ + conn->resume_from = data->set_resume_from; + if (conn->resume_from) { + snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from); + if (conn->bits.rangestringalloc == TRUE) + free(conn->range); + + /* tell ourselves to fetch this range */ + conn->range = strdup(resumerange); + conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ + } + *in_connect = conn; /* return this instead! */ infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex); -- cgit v1.2.1 From d300cf4d84182b111f6b364a89a9af00eca7f425 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 28 May 2001 14:12:43 +0000 Subject: T. Bharath's comments about SSL cleanup incorporated, and the two new curl_global_* functions --- lib/url.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 364e10881..726e259ca 100644 --- a/lib/url.c +++ b/lib/url.c @@ -833,6 +833,17 @@ CURLcode Curl_disconnect(struct connectdata *conn) #ifdef USE_SSLEAY if (conn->ssl.use) { + /* + ERR_remove_state() frees the error queue associated with + thread pid. If pid == 0, the current thread will have its + error queue removed. + + Since error queue data structures are allocated + automatically for new threads, they must be freed when + threads are terminated in oder to avoid memory leaks. + */ + ERR_remove_state(0); + if(conn->ssl.handle) { (void)SSL_shutdown(conn->ssl.handle); SSL_set_connect_state(conn->ssl.handle); -- cgit v1.2.1 From d567659bf4003c0808c309a52100a32a82a4b128 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 29 May 2001 19:17:39 +0000 Subject: strtok() replaced with strtok_r() --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 726e259ca..55d4463c8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1560,6 +1560,7 @@ static CURLcode Connect(struct UrlData *data, * checked if the lowercase versions don't exist. */ char *no_proxy=NULL; + char *no_proxy_tok_buf; char *proxy=NULL; char proxy_env[128]; @@ -1571,7 +1572,7 @@ static CURLcode Connect(struct UrlData *data, /* NO_PROXY wasn't specified or it wasn't just an asterisk */ char *nope; - nope=no_proxy?strtok(no_proxy, ", "):NULL; + nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; while(nope) { if(strlen(nope) <= strlen(conn->name)) { char *checkn= @@ -1581,7 +1582,7 @@ static CURLcode Connect(struct UrlData *data, break; } } - nope=strtok(NULL, ", "); + nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); } if(!nope) { /* It was not listed as without proxy */ -- cgit v1.2.1 From 870bacd6897b62666aeaaa8b8b2c937529abac90 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 May 2001 11:06:56 +0000 Subject: include strtok.h to get the prototype --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 55d4463c8..c42e05e8b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -91,6 +91,7 @@ #include "cookie.h" #include "strequal.h" #include "escape.h" +#include "strtok.h" /* And now for the protocols */ #include "ftp.h" -- cgit v1.2.1 From ffa7c1311779f38cc3c8531de9e4336afbda3a3c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 May 2001 12:51:24 +0000 Subject: libcurl now has MUTE and NOPROGRESS set by default --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c42e05e8b..8338af242 100644 --- a/lib/url.c +++ b/lib/url.c @@ -231,6 +231,11 @@ CURLcode Curl_open(CURL **curl, char *url) data->httpreq = HTTPREQ_GET; /* Default HTTP request */ + /* make libcurl quiet by default: */ + data->bits.mute = TRUE; /* CURLOPT_MUTE changes this */ + data->bits.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ + data->progress.flags |= PGRS_HIDE; + /* create an array with connection data struct pointers */ data->numconnects = 5; /* hard-coded right now */ data->connects = (struct connectdata **) @@ -363,6 +368,8 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) data->bits.hide_progress = va_arg(param, long)?TRUE:FALSE; if(data->bits.hide_progress) data->progress.flags |= PGRS_HIDE; + else + data->progress.flags &= ~PGRS_HIDE; break; case CURLOPT_NOBODY: /* -- cgit v1.2.1 From fe82ddda46774d092dcc0ca6460f17f2dea14dd2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 31 May 2001 13:50:28 +0000 Subject: CURLOPT_MUTE and data->bits.mute are history, removed, gone! --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8338af242..17e4549ff 100644 --- a/lib/url.c +++ b/lib/url.c @@ -232,7 +232,6 @@ CURLcode Curl_open(CURL **curl, char *url) data->httpreq = HTTPREQ_GET; /* Default HTTP request */ /* make libcurl quiet by default: */ - data->bits.mute = TRUE; /* CURLOPT_MUTE changes this */ data->bits.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ data->progress.flags |= PGRS_HIDE; @@ -439,12 +438,15 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) if(data->bits.http_put) data->httpreq = HTTPREQ_PUT; break; +#if 0 + /* obsolete stuff, kept here a while for informational purposes */ case CURLOPT_MUTE: /* * Stay absolutely quiet. */ data->bits.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 -- cgit v1.2.1 From 5e326014cd8afc0a1409b758da738694b482a561 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 7 Jun 2001 05:59:20 +0000 Subject: SDavila posted a fix that sets conn->bits.use_range properly when doing resumed downloads --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 17e4549ff..bb70cd7aa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2077,6 +2077,7 @@ static CURLcode Connect(struct UrlData *data, /* tell ourselves to fetch this range */ conn->range = strdup(resumerange); + conn->bits.use_range = TRUE; /* enable range download */ conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ } -- cgit v1.2.1 From 9a78db6e59e5d815a3145f8f696a6fbef92f2447 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 12 Jun 2001 09:21:37 +0000 Subject: =?UTF-8?q?Salvador=20D=E1vila's=20ftp=20range=20download=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bb70cd7aa..bcb801405 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2080,6 +2080,12 @@ static CURLcode Connect(struct UrlData *data, conn->bits.use_range = TRUE; /* enable range download */ conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ } + else if (data->set_range) { + /* There is a range, but is not a resume, useful for random ftp access */ + conn->range = strdup(data->set_range); + conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ + conn->bits.use_range = TRUE; /* enable range download */ + } *in_connect = conn; /* return this instead! */ -- cgit v1.2.1 From 89872447585d6d279bb9cb23fda30855932143a2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 3 Aug 2001 11:52:53 +0000 Subject: httpreq cleanup fix --- lib/url.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bcb801405..404a26faa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -432,10 +432,10 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_PUT: /* - * Use the HTTP PUT request to transfer data. + * Use the HTTP PUT request to transfer data if this is TRUE. If this is + * FALSE, don't set the httpreq. We can't know what to revert it to! */ - data->bits.http_put = va_arg(param, long)?TRUE:FALSE; - if(data->bits.http_put) + if(va_arg(param, long)) data->httpreq = HTTPREQ_PUT; break; #if 0 @@ -529,10 +529,18 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) * Set to make us do HTTP POST */ data->httppost = va_arg(param, struct HttpPost *); - data->bits.http_formpost = data->httppost?1:0; - if(data->bits.http_formpost) + if(data->httppost) data->httpreq = HTTPREQ_POST_FORM; break; + + case CURLOPT_HTTPGET: + /* + * Set to force us do HTTP GET + */ + if(va_arg(param, long)) + data->httpreq = HTTPREQ_GET; + break; + case CURLOPT_INFILE: /* * FILE pointer to read the file to be uploaded from. Or possibly @@ -575,8 +583,8 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_POST: /* Does this option serve a purpose anymore? */ - data->bits.http_post = va_arg(param, long)?TRUE:FALSE; - if(data->bits.http_post) + + if(va_arg(param, long)) data->httpreq = HTTPREQ_POST; break; case CURLOPT_POSTFIELDS: @@ -584,8 +592,7 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) * A string with POST data. Makes curl HTTP POST. */ data->postfields = va_arg(param, char *); - data->bits.http_post = data->postfields?TRUE:FALSE; - if(data->bits.http_post) + if(data->postfields) data->httpreq = HTTPREQ_POST; break; case CURLOPT_POSTFIELDSIZE: -- cgit v1.2.1 From 5ab1a10e9c1526cf48a9f6691bf1b91f9fd7e912 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Aug 2001 08:18:15 +0000 Subject: corrected the comment for CURLOPT_WRITEHEADER in setopt(), and made it read a void * and not a FILE *, as that was how it used to work and not anymore... --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 404a26faa..4b5fbb379 100644 --- a/lib/url.c +++ b/lib/url.c @@ -480,9 +480,9 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) break; case CURLOPT_WRITEHEADER: /* - * Callback function for header data + * Custom pointer to pass the header write callback function */ - data->writeheader = (FILE *)va_arg(param, FILE *); + data->writeheader = (void *)va_arg(param, void *); break; case CURLOPT_COOKIE: /* -- cgit v1.2.1 From 7948b0becc07056de67d3aa12717dedd21ed8f27 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Aug 2001 12:14:53 +0000 Subject: VMS #include fixes, file:// URL treatment improvements --- lib/url.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4b5fbb379..48e1d6b06 100644 --- a/lib/url.c +++ b/lib/url.c @@ -67,6 +67,12 @@ #include #endif +#ifdef VMS +#include +#include +#endif + + #ifndef HAVE_SELECT #error "We can't compile without select() support!" #endif @@ -1429,12 +1435,34 @@ static CURLcode Connect(struct UrlData *data, * hostname other than "localhost" and "127.0.0.1", which is unique among * the URL protocols specified in RFC 1738 */ - - if (strnequal(conn->path, "localhost/", 10) || - strnequal(conn->path, "127.0.0.1/", 10)) - /* If there's another host name than the one we support, / is - * quietly ommitted */ - strcpy(conn->path, &conn->path[10]); + if(conn->path[0] != '/') { + /* the URL included a host name, we ignore host names in file:// URLs + as the standards don't define what to do with them */ + char *ptr=strchr(conn->path, '/'); + if(ptr) { + /* there was a slash present + + RFC1738 (section 3.1, page 5) says: + + The rest of the locator consists of data specific to the scheme, + and is known as the "url-path". It supplies the details of how the + specified resource can be accessed. Note that the "/" between the + host (or port) and the url-path is NOT part of the url-path. + + As most agents use file://localhost/foo to get '/foo' although the + slash preceeding foo is a separator and not a slash for the path, + a URL as file://localhost//foo must be valid as well, to refer to + the same file with an absolute path. + */ + + if(ptr[1] && ('/' == ptr[1])) + /* if there was two slashes, we skip the first one as that is then + used truly as a separator */ + ptr++; + + strcpy(conn->path, ptr); + } + } strcpy(conn->protostr, "file"); /* store protocol string lowercase */ } -- cgit v1.2.1 From 95837043e269b4e8eb96d0d2933c75c86a399419 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 8 Aug 2001 07:16:47 +0000 Subject: Patrick Bihan-Faou introduced CURLOPT_SSL_VERIFYHOST and code to deal with it. --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 48e1d6b06..a40d1bbe9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -792,6 +792,12 @@ CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) */ data->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); + break; case CURLOPT_CAINFO: /* * Set CA info for SSL connection. Specify file name of the CA certificate -- cgit v1.2.1 From 616d8eda41e692bdf6f4f848542a0b6bd8920bce Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 14 Aug 2001 08:40:06 +0000 Subject: Curl_open() only take one argument now, Curl_ldap_done() and Curl_dict_done() were removed, compiler warnings corrected --- lib/url.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a40d1bbe9..7358caf46 100644 --- a/lib/url.c +++ b/lib/url.c @@ -184,9 +184,11 @@ CURLcode Curl_close(CURL *curl) } static -int my_getpass(void *clientp, char *prompt, char* buffer, int buflen ) +int my_getpass(void *clientp, const char *prompt, char* buffer, int buflen ) { char *retbuf; + clientp=NULL; /* prevent compiler warning */ + retbuf = getpass_r(prompt, buffer, buflen); if(NULL == retbuf) return 1; @@ -195,7 +197,7 @@ int my_getpass(void *clientp, char *prompt, char* buffer, int buflen ) } -CURLcode Curl_open(CURL **curl, char *url) +CURLcode Curl_open(CURL **curl) { /* We don't yet support specifying the URL at this point */ struct UrlData *data; @@ -953,7 +955,7 @@ ConnectionExists(struct UrlData *data, struct connectdata *needle, struct connectdata **usethis) { - size_t i; + long i; struct connectdata *check; for(i=0; i< data->numconnects; i++) { @@ -1016,7 +1018,7 @@ ConnectionExists(struct UrlData *data, static int ConnectionKillOne(struct UrlData *data) { - size_t i; + long i; struct connectdata *conn; int highscore=-1; int connindex=-1; @@ -1082,7 +1084,7 @@ static unsigned int ConnectionStore(struct UrlData *data, struct connectdata *conn) { - size_t i; + long i; for(i=0; i< data->numconnects; i++) { if(!data->connects[i]) break; @@ -1870,14 +1872,14 @@ static CURLcode Connect(struct UrlData *data, conn->port = (data->use_port && allow_port)?data->use_port:PORT_DICT; conn->remote_port = PORT_DICT; conn->curl_do = Curl_dict; - conn->curl_done = Curl_dict_done; + 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->remote_port = PORT_LDAP; conn->curl_do = Curl_ldap; - conn->curl_done = Curl_ldap_done; + conn->curl_done = NULL; /* no LDAP-specific done */ } else if (strequal(conn->protostr, "FILE")) { conn->protocol |= PROT_FILE; -- cgit v1.2.1 From 10ab0821887f1e82e6ffbca0ba82c1619d3684bb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 15 Aug 2001 06:55:42 +0000 Subject: non-public functions should not use CURL * as arguments, so I changed them to use 'struct UrlData *' instead --- lib/url.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7358caf46..edbbf7b41 100644 --- a/lib/url.c +++ b/lib/url.c @@ -106,6 +106,7 @@ #include "http.h" #include "file.h" #include "ldap.h" +#include "url.h" #include @@ -142,10 +143,8 @@ RETSIGTYPE alarmfunc(int signal) } #endif -CURLcode Curl_close(CURL *curl) +CURLcode Curl_close(struct UrlData *data) { - struct UrlData *data=(struct UrlData *)curl; - /* Loop through all open connections and kill them one by one */ while(-1 != ConnectionKillOne(data)); @@ -197,7 +196,7 @@ int my_getpass(void *clientp, const char *prompt, char* buffer, int buflen ) } -CURLcode Curl_open(CURL **curl) +CURLcode Curl_open(struct UrlData **curl) { /* We don't yet support specifying the URL at this point */ struct UrlData *data; @@ -283,9 +282,8 @@ CURLcode Curl_open(CURL **curl) return CURLE_OUT_OF_MEMORY; } -CURLcode Curl_setopt(CURL *curl, CURLoption option, ...) +CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) { - struct UrlData *data = curl; va_list param; char *cookiefile; -- cgit v1.2.1 From 9518e06413938c0a23c0de120a708fc1ecc0a313 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 15 Aug 2001 21:40:09 +0000 Subject: extract IPv6-style specified IP-addresses properly --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index edbbf7b41..afd66a4c7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1996,7 +1996,10 @@ static CURLcode Connect(struct UrlData *data, failf(data, "You haven't enabled IPv6 support"); return CURLE_URL_MALFORMAT; #else + conn->name++; /* pass the starting bracket */ + tmp = strchr(conn->name, ']'); + *tmp = 0; /* zero terminate */ tmp++; /* pass the ending bracket */ if(':' != *tmp) -- cgit v1.2.1 From 9ce94207e291b8a04290f4ece51cbae741e41ff2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 15 Aug 2001 21:54:24 +0000 Subject: IPv6-addresses can have dots too! --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index afd66a4c7..76c2c732b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1989,7 +1989,7 @@ static CURLcode Connect(struct UrlData *data, * IPv6-specified addresses in the [0::1] style. *************************************************************/ - if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:]%c", &endbracket)) && + if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && (']' == endbracket)) { /* this is a IPv6-style specified IP-address */ #ifndef ENABLE_IPV6 -- cgit v1.2.1 From 0f425b01aa37aea99c1cfab1646f3e5f38b65c90 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 22 Aug 2001 11:24:57 +0000 Subject: CURLOPT_FTPASCII is the old name, CURLOPT_TRANSFERTEXT is the new --- lib/url.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 76c2c732b..6a0d62a81 100644 --- a/lib/url.c +++ b/lib/url.c @@ -430,9 +430,12 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) */ data->bits.http_follow_location = va_arg(param, long)?TRUE:FALSE; break; - case CURLOPT_FTPASCII: + case CURLOPT_TRANSFERTEXT: /* - * Transfer FTP using ASCII instead of BINARY. + * This option was previously named 'FTPASCII'. Renamed to work with + * more protocols than merely FTP. + * + * Transfer using ASCII (instead of BINARY). */ data->bits.ftp_ascii = va_arg(param, long)?TRUE:FALSE; break; -- cgit v1.2.1 From 12acab9b86196ca6ed7d084269c8484820686713 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 23 Aug 2001 14:06:38 +0000 Subject: When setting *_URL or *_PROXY in *_setopt(), it is important that we check and possibly free the existing pointer first, and then clear the "allocated" bit. We previously mistakenly could free the new pointer passed to us by the friendly user...! --- lib/url.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6a0d62a81..66eedf473 100644 --- a/lib/url.c +++ b/lib/url.c @@ -483,9 +483,8 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * Set cookie file to read and parse. */ cookiefile = (char *)va_arg(param, void *); - if(cookiefile) { - data->cookies = Curl_cookie_init(cookiefile); - } + if(cookiefile) + data->cookies = Curl_cookie_init(cookiefile, data->cookies); break; case CURLOPT_WRITEHEADER: /* @@ -582,6 +581,11 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) /* * The URL to fetch. */ + if(data->bits.urlstringalloc) { + /* the already set URL is allocated, free it first! */ + free(data->url); + data->bits.urlstringalloc=FALSE; + } data->url = va_arg(param, char *); break; case CURLOPT_PORT: @@ -628,6 +632,13 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) /* * Set proxy server:port to use as HTTP proxy */ + if(data->bits.proxystringalloc) { + /* + * The already set string is allocated, free that first + */ + data->bits.proxystringalloc=FALSE;; + free(data->proxy); + } data->proxy = va_arg(param, char *); data->bits.httpproxy = data->proxy?1:0; break; -- cgit v1.2.1 From 3c52c53dddd3193d20bcb6fb335b1813eb1c07dd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 28 Aug 2001 08:37:54 +0000 Subject: Added SSL session ID caching, moved some SSL code from url.c to ssluse.c --- lib/url.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 66eedf473..294a5db9b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -148,6 +148,11 @@ CURLcode Curl_close(struct UrlData *data) /* Loop through all open connections and kill them one by one */ while(-1 != ConnectionKillOne(data)); +#ifdef USE_SSLEAY + /* Close down all open info open SSL and sessions */ + Curl_SSL_Close_All(data); +#endif + if(data->bits.proxystringalloc) { data->bits.proxystringalloc=FALSE;; free(data->proxy); @@ -242,6 +247,9 @@ CURLcode Curl_open(struct UrlData **curl) data->bits.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; + /* create an array with connection data struct pointers */ data->numconnects = 5; /* hard-coded right now */ data->connects = (struct connectdata **) @@ -875,31 +883,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) free(conn->path); #ifdef USE_SSLEAY - if (conn->ssl.use) { - /* - ERR_remove_state() frees the error queue associated with - thread pid. If pid == 0, the current thread will have its - error queue removed. - - Since error queue data structures are allocated - automatically for new threads, they must be freed when - threads are terminated in oder to avoid memory leaks. - */ - ERR_remove_state(0); - - if(conn->ssl.handle) { - (void)SSL_shutdown(conn->ssl.handle); - SSL_set_connect_state(conn->ssl.handle); - - SSL_free (conn->ssl.handle); - conn->ssl.handle = NULL; - } - if(conn->ssl.ctx) { - SSL_CTX_free (conn->ssl.ctx); - conn->ssl.ctx = NULL; - } - conn->ssl.use = FALSE; /* get back to ordinary socket usage */ - } + Curl_SSL_Close(conn); #endif /* USE_SSLEAY */ /* close possibly still open sockets */ -- cgit v1.2.1 From a2b6ef3478e2c37982521a326ea7b90d856adc8c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Aug 2001 09:32:18 +0000 Subject: cookie jar adjustments --- lib/url.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 294a5db9b..20111d0ed 100644 --- a/lib/url.c +++ b/lib/url.c @@ -178,6 +178,10 @@ CURLcode Curl_close(struct UrlData *data) /* the URL is allocated, free it! */ free(data->url); + if(data->cookiejar) + /* we have a "destination" for all the cookies to get dumped to */ + Curl_cookie_output(data->cookies, data->cookiejar); + Curl_cookie_cleanup(data->cookies); /* free the connection cache */ @@ -488,12 +492,19 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) case CURLOPT_COOKIEFILE: /* - * Set cookie file to read and parse. + * Set cookie file to read and parse. Can be used multiple times. */ cookiefile = (char *)va_arg(param, void *); if(cookiefile) data->cookies = Curl_cookie_init(cookiefile, data->cookies); break; + + case CURLOPT_COOKIEJAR: + /* + * Set cookie file name to dump all cookies to when we're done. + */ + data->cookiejar = cookiefile = (char *)va_arg(param, void *); + break; case CURLOPT_WRITEHEADER: /* * Custom pointer to pass the header write callback function -- cgit v1.2.1 From 0ece1b5c34c049a3226f7dd793cf75e470c46e4d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 30 Aug 2001 22:48:34 +0000 Subject: Major rename and redesign of the internal "backbone" structs. Details will be posted in a minute to the libcurl list. --- lib/url.c | 572 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 281 insertions(+), 291 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 20111d0ed..571362bf6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -122,11 +122,11 @@ #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); @@ -143,7 +143,7 @@ RETSIGTYPE alarmfunc(int signal) } #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)); @@ -153,39 +153,25 @@ CURLcode Curl_close(struct UrlData *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; @@ -205,66 +191,67 @@ int my_getpass(void *clientp, const char *prompt, char* buffer, int buflen ) } -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; @@ -294,7 +281,7 @@ CURLcode Curl_open(struct UrlData **curl) 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; @@ -307,13 +294,13 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * 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: /* @@ -324,30 +311,30 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) 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; @@ -356,34 +343,34 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * 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; @@ -392,55 +379,55 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) /* * 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: /* @@ -449,7 +436,7 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * * 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: /* @@ -457,7 +444,7 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * 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 */ @@ -465,7 +452,7 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) /* * 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: @@ -473,21 +460,21 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * 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: @@ -503,61 +490,61 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) /* * 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: @@ -565,7 +552,7 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * 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: @@ -573,276 +560,279 @@ CURLcode Curl_setopt(struct UrlData *data, CURLoption option, ...) * 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: */ @@ -869,7 +859,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) 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) @@ -958,19 +948,19 @@ static bool SocketIsDead(int sock) * 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; @@ -984,8 +974,8 @@ ConnectionExists(struct UrlData *data, 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; } @@ -994,7 +984,7 @@ ConnectionExists(struct UrlData *data, 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 */ } @@ -1023,7 +1013,7 @@ ConnectionExists(struct UrlData *data, * of the connections to kill. */ static int -ConnectionKillOne(struct UrlData *data) +ConnectionKillOne(struct SessionHandle *data) { long i; struct connectdata *conn; @@ -1035,8 +1025,8 @@ ConnectionKillOne(struct UrlData *data) 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; @@ -1044,7 +1034,7 @@ ConnectionKillOne(struct UrlData *data) /* * By using the set policy, we score each connection. */ - switch(data->closepolicy) { + switch(data->set.closepolicy) { case CURLCLOSEPOLICY_LEAST_RECENTLY_USED: default: /* @@ -1070,10 +1060,10 @@ ConnectionKillOne(struct UrlData *data) 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 */ @@ -1088,28 +1078,28 @@ ConnectionKillOne(struct UrlData *data) * 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) @@ -1146,7 +1136,7 @@ static CURLcode ConnectPlease(struct UrlData *data, /************************************************************* * 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; @@ -1154,16 +1144,16 @@ static CURLcode ConnectPlease(struct UrlData *data, 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); } } @@ -1283,7 +1273,7 @@ static CURLcode ConnectPlease(struct UrlData *data, #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); @@ -1293,7 +1283,7 @@ static CURLcode ConnectPlease(struct UrlData *data, 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)) { @@ -1355,9 +1345,9 @@ static CURLcode ConnectPlease(struct UrlData *data, 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; @@ -1372,7 +1362,7 @@ static CURLcode Connect(struct UrlData *data, * 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 @@ -1399,10 +1389,10 @@ static CURLcode Connect(struct UrlData *data, 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 @@ -1410,8 +1400,8 @@ static CURLcode Connect(struct UrlData *data, 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! */ @@ -1426,7 +1416,7 @@ static CURLcode Connect(struct UrlData *data, * 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; @@ -1442,7 +1432,7 @@ static CURLcode Connect(struct UrlData *data, * 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")) { /* @@ -1486,7 +1476,7 @@ static CURLcode Connect(struct UrlData *data, 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)) { @@ -1494,7 +1484,7 @@ static CURLcode Connect(struct UrlData *data, * 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. @@ -1533,30 +1523,31 @@ static CURLcode Connect(struct UrlData *data, } } - 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; } } @@ -1565,25 +1556,25 @@ static CURLcode Connect(struct UrlData *data, * 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; } @@ -1600,7 +1591,7 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * 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: * @@ -1690,9 +1681,8 @@ static CURLcode Connect(struct UrlData *data, 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 '*' */ @@ -1703,22 +1693,19 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * 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 */ } @@ -1744,16 +1731,16 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * 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); } /************************************************************* @@ -1761,7 +1748,7 @@ static CURLcode Connect(struct UrlData *data, *************************************************************/ 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; @@ -1771,7 +1758,7 @@ static CURLcode Connect(struct UrlData *data, 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; @@ -1787,7 +1774,7 @@ static CURLcode Connect(struct UrlData *data, #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 // in path if present */ if (isdigit((int)conn->path[1])) { @@ -1813,12 +1800,12 @@ static CURLcode Connect(struct UrlData *data, #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) { @@ -1852,15 +1839,15 @@ static CURLcode Connect(struct UrlData *data, 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; } } @@ -1869,21 +1856,21 @@ static CURLcode Connect(struct UrlData *data, /* 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 */ @@ -1916,8 +1903,10 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * .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); } @@ -1926,10 +1915,10 @@ static CURLcode Connect(struct UrlData *data, /* 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)) ) { @@ -1941,22 +1930,22 @@ static CURLcode Connect(struct UrlData *data, 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 */ @@ -1964,17 +1953,18 @@ static CURLcode Connect(struct UrlData *data, } /* 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); } @@ -1983,8 +1973,8 @@ static CURLcode Connect(struct UrlData *data, 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); } } @@ -2025,7 +2015,7 @@ static CURLcode Connect(struct UrlData *data, 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. */ @@ -2035,7 +2025,7 @@ static CURLcode Connect(struct UrlData *data, /* 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; @@ -2064,10 +2054,10 @@ static CURLcode Connect(struct UrlData *data, /* 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 */ @@ -2084,7 +2074,7 @@ static CURLcode Connect(struct UrlData *data, /* 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 @@ -2122,7 +2112,7 @@ static CURLcode Connect(struct UrlData *data, * 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) @@ -2133,9 +2123,9 @@ static CURLcode Connect(struct UrlData *data, 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 */ } @@ -2155,7 +2145,7 @@ static CURLcode Connect(struct UrlData *data, /************************************************************* * 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 */ @@ -2199,9 +2189,9 @@ static CURLcode Connect(struct UrlData *data, *************************************************************/ 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); @@ -2215,12 +2205,12 @@ static CURLcode Connect(struct UrlData *data, * 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); } } @@ -2286,7 +2276,7 @@ static CURLcode Connect(struct UrlData *data, * 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 @@ -2294,7 +2284,7 @@ static CURLcode Connect(struct UrlData *data, return CURLE_OK; } -CURLcode Curl_connect(struct UrlData *data, +CURLcode Curl_connect(struct SessionHandle *data, struct connectdata **in_connect, bool allow_port) { @@ -2319,7 +2309,7 @@ CURLcode Curl_connect(struct UrlData *data, 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 */ @@ -2343,13 +2333,13 @@ CURLcode Curl_done(struct connectdata *conn) 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 -- cgit v1.2.1 From bae1a75731b4e712d16398205104721b05ee2ca1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 3 Sep 2001 07:01:49 +0000 Subject: use the LIBCURL_NAME instead of the "hardcoded" string --- lib/url.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 571362bf6..3bfcafb18 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2000, Daniel Stenberg, , et al. + * Copyright (C) 2001, Daniel Stenberg, , et al. * * In order to be useful for every potential user, curl and libcurl are * dual-licensed under the MPL and the MIT/X-derivate licenses. @@ -1769,7 +1769,8 @@ static CURLcode Connect(struct SessionHandle *data, conn->curl_close = Curl_http_close; #else /* USE_SSLEAY */ - failf(data, "libcurl was built with SSL disabled, https: not supported!"); + failf(data, LIBCURL_NAME + " was built with SSL disabled, https: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; #endif /* !USE_SSLEAY */ } @@ -1795,7 +1796,8 @@ static CURLcode Connect(struct SessionHandle *data, #ifdef USE_SSLEAY conn->protocol |= PROT_FTPS; #else - failf(data, "libcurl was built with SSL disabled, ftps: not supported!"); + failf(data, LIBCURL_NAME + " was built with SSL disabled, ftps: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; #endif /* !USE_SSLEAY */ } -- cgit v1.2.1 From 6147879837a53d22c9be04e7a4fc315a297ba2b3 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Fri, 7 Sep 2001 04:01:32 +0000 Subject: Added formatting sections for emacs and vim --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3bfcafb18..42a531271 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2361,3 +2361,10 @@ CURLcode Curl_do(struct connectdata *conn) return result; } +/* + * local variables: + * eval: (load-file "../curl-mode.el") + * end: + * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker + * vim<600: et sw=2 ts=2 sts=2 tw=78 + */ -- cgit v1.2.1 From a2c78607a6f195eac8b9ecadb9a94d94f92bc5bd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Sep 2001 22:23:16 +0000 Subject: CURLOPT_SSL_CIPHER_LIST support --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 42a531271..4a7c57ff9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -289,6 +289,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) va_start(param, option); switch(option) { + case CURLOPT_SSL_CIPHER_LIST: + /* set a list of cipher we want to use in the SSL connection */ + data->set.ssl.cipher_list = va_arg(param, char *); + break; + case CURLOPT_RANDOM_FILE: /* * This is the path name to a file that contains random data to seed -- cgit v1.2.1 From bec97a0999f92a02ddae393a0aca3e78a30fd485 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 Sep 2001 08:00:30 +0000 Subject: ConnectionKillOne() _can_ return -1 as an indication of error This is T. Bharath's fix --- lib/url.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4a7c57ff9..cfcac7322 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1097,10 +1097,14 @@ ConnectionStore(struct SessionHandle *data, infof(data, "Connection (#%d) was killed to make room\n", i); } - data->state.connects[i] = conn; /* fill in this */ - conn->connectindex = i; /* make the child know where the pointer to this - particular data is stored */ - + if(-1 != i) { + /* only do this if a true index was returned, if -1 was returned there + is no room in the cache for an unknown reason and we cannot store + this there. */ + 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; } -- cgit v1.2.1 From 146413a53c1e7092602bcc14c70a7690dcd3cc21 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 18 Sep 2001 15:30:38 +0000 Subject: the stuff formerly done in Curl_http_close is now done in Curl_close --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cfcac7322..81a238653 100644 --- a/lib/url.c +++ b/lib/url.c @@ -153,17 +153,21 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_SSL_Close_All(data); #endif + if(data->state.auth_host) + free(data->state.auth_host); + 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); if(data->state.headerbuff) free(data->state.headerbuff); - if(data->set.cookiejar) /* we have a "destination" for all the cookies to get dumped to */ Curl_cookie_output(data->cookies, data->set.cookiejar); @@ -1762,7 +1766,6 @@ static CURLcode Connect(struct SessionHandle *data, conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; - conn->curl_close = Curl_http_close; } else if (strequal(conn->protostr, "HTTPS")) { #ifdef USE_SSLEAY @@ -1775,7 +1778,6 @@ static CURLcode Connect(struct SessionHandle *data, conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; - conn->curl_close = Curl_http_close; #else /* USE_SSLEAY */ failf(data, LIBCURL_NAME @@ -1795,7 +1797,6 @@ static CURLcode Connect(struct SessionHandle *data, conn->protocol |= PROT_GOPHER; conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; - conn->curl_close = Curl_http_close; } else if(strequal(conn->protostr, "FTP") || strequal(conn->protostr, "FTPS")) { @@ -1827,7 +1828,6 @@ static CURLcode Connect(struct SessionHandle *data, } conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; - conn->curl_close = Curl_http_close; } else { conn->curl_do = Curl_ftp; -- cgit v1.2.1 From b556d6caeecc01d919c91b4d1408e8e718d6a3b3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 18 Sep 2001 18:33:25 +0000 Subject: fixed bug report #462600, following a Location: when the initial URL didn't have a protocol:// part did wrong --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 81a238653..a3b7a025e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1704,12 +1704,12 @@ static CURLcode Connect(struct SessionHandle *data, } /* if not using proxy */ /************************************************************* - * No protocol but proxy usage needs attention + * No protocol part in URL was used, add it! *************************************************************/ - 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! - */ + if(conn->protocol&PROT_MISSING) { + /* We're guessing prefixes here and if we're told to use a proxy or if + we're gonna follow a Location: later or... then we need the protocol + part added so that we have a valid URL. */ char *reurl; reurl = aprintf("%s://%s", conn->protostr, data->change.url); -- cgit v1.2.1 From 48dc74aeccab16febc770ccc5fec7ec96af26a97 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 28 Sep 2001 07:05:26 +0000 Subject: more transparant support for IPv6 name resolving --- lib/url.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a3b7a025e..65443d7a8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1158,11 +1158,11 @@ static CURLcode ConnectPlease(struct SessionHandle *data, unsigned long in; if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { - h = Curl_gethost(data, myhost, &hostdataptr); + h = Curl_getaddrinfo(data, myhost, 0, &hostdataptr); } else { if(strlen(data->set.device)>1) { - h = Curl_gethost(data, data->set.device, &hostdataptr); + h = Curl_getaddrinfo(data, data->set.device, 0, &hostdataptr); } if(h) { /* we know data->set.device is shorter than the myhost array */ @@ -2163,16 +2163,11 @@ static CURLcode Connect(struct SessionHandle *data, /* Resolve target host right on */ if(!conn->hp) { -#ifdef ENABLE_IPV6 - /* it might already be set if reusing a connection */ - conn->hp = Curl_getaddrinfo(data, conn->name, conn->port); -#else /* it might already be set if reusing a connection */ - conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf); -#endif + conn->hp = Curl_getaddrinfo(data, conn->name, conn->port, + &conn->hostent_buf); } - if(!conn->hp) - { + if(!conn->hp) { failf(data, "Couldn't resolve host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; } @@ -2182,12 +2177,10 @@ static CURLcode Connect(struct SessionHandle *data, if we're reusing an existing connection. */ /* resolve proxy */ -#ifdef ENABLE_IPV6 - /* it might already be set if reusing a connection */ - conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port); -#else - conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf); -#endif + /* it might already be set if reusing a connection */ + conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port, + &conn->hostent_buf); + if(!conn->hp) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); return CURLE_COULDNT_RESOLVE_PROXY; -- cgit v1.2.1 From c5fdeef41d50d5207c52507e17eadc1ba1e4c5f0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 1 Oct 2001 08:59:17 +0000 Subject: introduced non-blocking connects --- lib/url.c | 115 +++++--------------------------------------------------------- 1 file changed, 8 insertions(+), 107 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 65443d7a8..ba6c36a6b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -107,6 +107,7 @@ #include "file.h" #include "ldap.h" #include "url.h" +#include "connect.h" #include @@ -1123,12 +1124,6 @@ static CURLcode ConnectPlease(struct SessionHandle *data, #ifndef ENABLE_IPV6 conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); - - memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); - memcpy((char *)&(conn->serv_addr.sin_addr), - conn->hp->h_addr, conn->hp->h_length); - conn->serv_addr.sin_family = conn->hp->h_addrtype; - conn->serv_addr.sin_port = htons(conn->port); #else /* IPv6-style */ struct addrinfo *ai; @@ -1259,108 +1254,14 @@ static CURLcode ConnectPlease(struct SessionHandle *data, /************************************************************* * Connect to server/proxy *************************************************************/ -#ifdef ENABLE_IPV6 - conn->firstsocket = -1; - for (ai = conn->hp; ai; ai = ai->ai_next) { - conn->firstsocket = socket(ai->ai_family, - ai->ai_socktype, - ai->ai_protocol); - if (conn->firstsocket < 0) - continue; - - if (connect(conn->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) { - sclose(conn->firstsocket); - conn->firstsocket = -1; - continue; - } - - break; - } - conn->ai = ai; - if (conn->firstsocket < 0) { - failf(data, strerror(errno)); - return CURLE_COULDNT_CONNECT; - } -#else - /* non-zero nonblock value sets socket as nonblocking under Win32 */ -#if defined(WIN32) - FD_ZERO (&connectfd); - FD_SET(conn->firstsocket, &connectfd); - if (conn->data->set.connecttimeout > 0) { - nonblock = 1; - } - ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); -#endif - if (connect(conn->firstsocket, - (struct sockaddr *) &(conn->serv_addr), - sizeof(conn->serv_addr) - ) < 0) { -#if defined(WIN32) - 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)) { - /* shut off non-blocking again */ - nonblock = 0; - ioctlsocket(conn->firstsocket, FIONBIO, &nonblock); - return CURLE_OK; - } - else - errno = EINTR; - } -#endif - switch(errno) { -#ifdef ECONNREFUSED - /* this should be made nicer */ - case ECONNREFUSED: - failf(data, "Connection refused"); - break; - case EFAULT: - failf(data, "Invalid socket address: %d",errno); - break; - case EISCONN: - failf(data, "Socket already connected: %d",errno); - break; - case ETIMEDOUT: - failf(data, "Timeout while accepting connection, server busy: %d",errno); - break; - case ENETUNREACH: - failf(data, "Network is unreachable: %d",errno); - break; - case EADDRINUSE: - failf(data, "Local address already in use: %d",errno); - break; - case EINPROGRESS: - failf(data, "Socket is nonblocking and connection can not be completed immediately: %d",errno); - break; - case EALREADY: - failf(data, "Socket is nonblocking and a previous connection attempt not completed: %d",errno); - break; - case EAGAIN: - failf(data, "No more free local ports: %d",errno); - break; - case EACCES: - case EPERM: - failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno); - break; -#endif - case EINTR: - failf(data, "Connection timed out"); - break; - default: - failf(data, "Can't connect to server: %d", errno); - break; - } - return CURLE_COULDNT_CONNECT; - } -#endif - - return CURLE_OK; + return Curl_connecthost(conn, + conn->firstsocket, /* might be bind()ed */ + &conn->firstsocket); } -static CURLcode Connect(struct SessionHandle *data, - struct connectdata **in_connect, - bool allow_port) /* allow data->set.use_port ? */ +static CURLcode CreateConnection(struct SessionHandle *data, + struct connectdata **in_connect, + bool allow_port) /* allow set.use_port? */ { char *tmp; char *buf; @@ -2296,7 +2197,7 @@ CURLcode Curl_connect(struct SessionHandle *data, struct connectdata *conn; /* call the stuff that needs to be called */ - code = Connect(data, in_connect, allow_port); + code = CreateConnection(data, in_connect, allow_port); if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated -- cgit v1.2.1 From 09da90076f67725000e09d4c128fd052b31cd727 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 1 Oct 2001 11:27:39 +0000 Subject: moved the myalarm() usage, and now makes sure to switch it off after the name resolving, as that should be the *ONLY* section in libcurl that may take a while in a synchronous call. --- lib/url.c | 66 ++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 20 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ba6c36a6b..ec0e5110d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1116,11 +1116,7 @@ ConnectionStore(struct SessionHandle *data, static CURLcode ConnectPlease(struct SessionHandle *data, struct connectdata *conn) { -#if defined(WIN32) - unsigned long nonblock = 0; - fd_set connectfd; - struct timeval conntimeout; -#endif + long max_time=300000; /* milliseconds, default to five minutes */ #ifndef ENABLE_IPV6 conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); @@ -1251,10 +1247,35 @@ static CURLcode ConnectPlease(struct SessionHandle *data, #endif /* end of not WIN32 */ #endif /*ENABLE_IPV6*/ + /************************************************************* + * Figure out what maximum time we have left + *************************************************************/ + if(data->set.timeout || data->set.connecttimeout) { + double has_passed; + + /* Evaluate how much that that has passed */ + has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + + /* get the most strict timeout of the ones converted to milliseconds */ + max_time = min(data->set.timeout, data->set.connecttimeout)*1000; + + /* subtract the passed time */ + max_time -= (long)(has_passed * 1000); + + if(max_time < 0) + /* a precaution, no need to continue if time already is up */ + return CURLE_OPERATION_TIMEOUTED; + } + /************************************************************* * Connect to server/proxy *************************************************************/ return Curl_connecthost(conn, + max_time, conn->firstsocket, /* might be bind()ed */ &conn->firstsocket); } @@ -1642,21 +1663,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } - /************************************************************* - * Set timeout if that is being used - *************************************************************/ - 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->set.connecttimeout) - myalarm(data->set.connecttimeout); - else - myalarm(data->set.timeout); - } - /************************************************************* * Setup internals depending on protocol *************************************************************/ @@ -2054,6 +2060,23 @@ static CURLcode CreateConnection(struct SessionHandle *data, ConnectionStore(data, conn); } + /************************************************************* + * Set timeout if that is being used + *************************************************************/ + if(data->set.timeout || data->set.connecttimeout) { + /* We set the timeout on the name resolving phase first, separately from + * the download/upload part to allow a maximum time on everything. This is + * a signal-based timeout, why it won't work and shouldn't be used in + * multi-threaded environments. */ + + /* myalarm() makes a signal get sent when the timeout fires off, and that + will abort system calls */ + if(data->set.connecttimeout) + myalarm(data->set.connecttimeout); + else + myalarm(data->set.timeout); + } + /************************************************************* * Resolve the name of the server or proxy *************************************************************/ @@ -2088,6 +2111,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } Curl_pgrsTime(data, TIMER_NAMELOOKUP); + if(data->set.timeout || data->set.connecttimeout) + /* switch off signal-based timeouts */ + myalarm(0); /************************************************************* * Proxy authentication -- cgit v1.2.1 From 6918427faefa32212423cd8eb3db789d84264929 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 1 Oct 2001 22:32:37 +0000 Subject: conn->hp is now conn->hostaddr changed the Curl_connethost() proto again --- lib/url.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ec0e5110d..810c387a7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -880,8 +880,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) free(conn->proto.generic); #ifdef ENABLE_IPV6 - if(conn->hp) /* host name info */ - freeaddrinfo(conn->hp); + if(conn->hostaddr) /* host name info */ + freeaddrinfo(conn->hostaddr); #else if(conn->hostent_buf) /* host name info */ free(conn->hostent_buf); @@ -1276,6 +1276,8 @@ static CURLcode ConnectPlease(struct SessionHandle *data, *************************************************************/ return Curl_connecthost(conn, max_time, + conn->hostaddr, + conn->port, conn->firstsocket, /* might be bind()ed */ &conn->firstsocket); } @@ -2086,26 +2088,26 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = conn->remote_port; /* it is the same port */ /* Resolve target host right on */ - if(!conn->hp) { + if(!conn->hostaddr) { /* it might already be set if reusing a connection */ - conn->hp = Curl_getaddrinfo(data, conn->name, conn->port, + conn->hostaddr = Curl_getaddrinfo(data, conn->name, conn->port, &conn->hostent_buf); } - if(!conn->hp) { + if(!conn->hostaddr) { failf(data, "Couldn't resolve host '%s'", conn->name); return CURLE_COULDNT_RESOLVE_HOST; } } - else if(!conn->hp) { + else if(!conn->hostaddr) { /* This is a proxy that hasn't been resolved yet. It may be resolved if we're reusing an existing connection. */ /* resolve proxy */ /* it might already be set if reusing a connection */ - conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port, + conn->hostaddr = Curl_getaddrinfo(data, conn->proxyhost, conn->port, &conn->hostent_buf); - if(!conn->hp) { + if(!conn->hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); return CURLE_COULDNT_RESOLVE_PROXY; } @@ -2195,8 +2197,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else { struct in_addr in; - (void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in)); + (void) memcpy(&in.s_addr, *conn->hostaddr->h_addr_list, sizeof (in.s_addr)); + infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, inet_ntoa(in)); } #endif -- cgit v1.2.1 From 56ff2aa059361c19c420c5321efe86e50074e0ac Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 1 Oct 2001 23:25:59 +0000 Subject: pick the correct timeout before the connecthost call --- lib/url.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 810c387a7..f721d5051 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1118,13 +1118,6 @@ static CURLcode ConnectPlease(struct SessionHandle *data, { long max_time=300000; /* milliseconds, default to five minutes */ -#ifndef ENABLE_IPV6 - conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); -#else - /* IPv6-style */ - struct addrinfo *ai; -#endif - #if !defined(WIN32)||defined(__CYGWIN32__) /* We don't generally like checking for OS-versions, we should make this HAVE_XXXX based, although at the moment I don't have a decent test for @@ -1137,6 +1130,8 @@ static CURLcode ConnectPlease(struct SessionHandle *data, #endif #ifndef ENABLE_IPV6 + conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); + /************************************************************* * Select device to bind socket to *************************************************************/ @@ -1261,7 +1256,11 @@ static CURLcode ConnectPlease(struct SessionHandle *data, #endif /* get the most strict timeout of the ones converted to milliseconds */ - max_time = min(data->set.timeout, data->set.connecttimeout)*1000; + if(data->set.timeout && + (data->set.timeout>data->set.connecttimeout)) + max_time = data->set.timeout*1000; + else + max_time = data->set.connecttimeout*1000; /* subtract the passed time */ max_time -= (long)(has_passed * 1000); -- cgit v1.2.1 From 51ca5fcbe0745cc4e245ffb69b339d1987be3b88 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Oct 2001 09:40:06 +0000 Subject: major connecting updates --- lib/url.c | 198 +++++++++----------------------------------------------------- 1 file changed, 29 insertions(+), 169 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f721d5051..bbd40e827 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1113,172 +1113,35 @@ ConnectionStore(struct SessionHandle *data, return i; } -static CURLcode ConnectPlease(struct SessionHandle *data, - struct connectdata *conn) +static CURLcode ConnectPlease(struct connectdata *conn) { - long max_time=300000; /* milliseconds, default to five minutes */ - -#if !defined(WIN32)||defined(__CYGWIN32__) - /* We don't generally like checking for OS-versions, we should make this - HAVE_XXXX based, although at the moment I don't have a decent test for - this! */ - -#ifdef HAVE_INET_NTOA - -#ifndef INADDR_NONE -#define INADDR_NONE (unsigned long) ~0 -#endif - -#ifndef ENABLE_IPV6 - conn->firstsocket = socket(AF_INET, SOCK_STREAM, 0); - - /************************************************************* - * Select device to bind socket to - *************************************************************/ - if (data->set.device && (strlen(data->set.device)<255)) { - struct sockaddr_in sa; - struct hostent *h=NULL; - char *hostdataptr=NULL; - size_t size; - char myhost[256] = ""; - unsigned long in; - - if(Curl_if2ip(data->set.device, myhost, sizeof(myhost))) { - h = Curl_getaddrinfo(data, myhost, 0, &hostdataptr); - } - else { - if(strlen(data->set.device)>1) { - h = Curl_getaddrinfo(data, data->set.device, 0, &hostdataptr); - } - if(h) { - /* we know data->set.device is shorter than the myhost array */ - strcpy(myhost, data->set.device); - } - } - - if(! *myhost) { - /* need to fix this - h=Curl_gethost(data, - getmyhost(*myhost,sizeof(myhost)), - hostent_buf, - sizeof(hostent_buf)); - */ - printf("in here\n"); - } - - infof(data, "We connect from %s\n", myhost); - - if ( (in=inet_addr(myhost)) != INADDR_NONE ) { - - if ( h ) { - memset((char *)&sa, 0, sizeof(sa)); - memcpy((char *)&sa.sin_addr, - h->h_addr, - h->h_length); - sa.sin_family = AF_INET; - sa.sin_addr.s_addr = in; - sa.sin_port = 0; /* get any port */ - - if( bind(conn->firstsocket, (struct sockaddr *)&sa, sizeof(sa)) >= 0) { - /* we succeeded to bind */ - struct sockaddr_in add; - - size = sizeof(add); - if(getsockname(conn->firstsocket, (struct sockaddr *) &add, - (socklen_t *)&size)<0) { - failf(data, "getsockname() failed"); - return CURLE_HTTP_PORT_FAILED; - } - } - else { - switch(errno) { - case EBADF: - failf(data, "Invalid descriptor: %d", errno); - break; - case EINVAL: - failf(data, "Invalid request: %d", errno); - break; - case EACCES: - failf(data, "Address is protected, user not superuser: %d", errno); - break; - case ENOTSOCK: - failf(data, - "Argument is a descriptor for a file, not a socket: %d", - errno); - break; - case EFAULT: - failf(data, "Inaccessable memory error: %d", errno); - break; - case ENAMETOOLONG: - failf(data, "Address too long: %d", errno); - break; - case ENOMEM: - failf(data, "Insufficient kernel memory was available: %d", errno); - break; - default: - failf(data,"errno %d\n"); - } /* end of switch */ - - return CURLE_HTTP_PORT_FAILED; - } /* end of else */ - - } /* end of if h */ - else { - failf(data,"could't find my own IP address (%s)", myhost); - return CURLE_HTTP_PORT_FAILED; - } - } /* end of inet_addr */ - - else { - failf(data, "could't find my own IP address (%s)", myhost); - return CURLE_HTTP_PORT_FAILED; - } - - if(hostdataptr) - free(hostdataptr); /* allocated by Curl_gethost() */ - - } /* end of device selection support */ -#endif /* end of HAVE_INET_NTOA */ -#endif /* end of not WIN32 */ -#endif /*ENABLE_IPV6*/ + CURLcode result; + Curl_ipconnect *addr; /************************************************************* - * Figure out what maximum time we have left + * Connect to server/proxy *************************************************************/ - if(data->set.timeout || data->set.connecttimeout) { - double has_passed; - - /* Evaluate how much that that has passed */ - has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); - -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) + result= Curl_connecthost(conn, + conn->hostaddr, + conn->port, + &conn->firstsocket, + &addr); + if(CURLE_OK == result) { + /* All is cool, then we store the current information from the hostaddr + struct to the serv_addr, as it might be needed later. The address + returned from the function above is crucial here. */ +#ifdef ENABLE_IPV6 + conn->serv_addr = addr; +#else + memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); + memcpy((char *)&(conn->serv_addr.sin_addr), + (struct in_addr *)addr, sizeof(struct in_addr)); + conn->serv_addr.sin_family = conn->hostaddr->h_addrtype; + conn->serv_addr.sin_port = htons(conn->port); #endif - - /* get the most strict timeout of the ones converted to milliseconds */ - if(data->set.timeout && - (data->set.timeout>data->set.connecttimeout)) - max_time = data->set.timeout*1000; - else - max_time = data->set.connecttimeout*1000; - - /* subtract the passed time */ - max_time -= (long)(has_passed * 1000); - - if(max_time < 0) - /* a precaution, no need to continue if time already is up */ - return CURLE_OPERATION_TIMEOUTED; } - /************************************************************* - * Connect to server/proxy - *************************************************************/ - return Curl_connecthost(conn, - max_time, - conn->hostaddr, - conn->port, - conn->firstsocket, /* might be bind()ed */ - &conn->firstsocket); + return result; } static CURLcode CreateConnection(struct SessionHandle *data, @@ -1904,16 +1767,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, * port number of various reasons. * * To be able to detect port number flawlessly, we must not confuse them - * IPv6-specified addresses in the [0::1] style. + * IPv6-specified addresses in the [0::1] style. (RFC2732) *************************************************************/ if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && (']' == endbracket)) { - /* this is a IPv6-style specified IP-address */ -#ifndef ENABLE_IPV6 - failf(data, "You haven't enabled IPv6 support"); - return CURLE_URL_MALFORMAT; -#else + /* This is a (IPv6-style) specified IP-address. We support _any_ + IP within brackets to be really generic. */ conn->name++; /* pass the starting bracket */ tmp = strchr(conn->name, ']'); @@ -1922,7 +1782,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, tmp++; /* pass the ending bracket */ if(':' != *tmp) tmp = NULL; /* no port number available */ -#endif } else { /* traditional IPv4-style port-extracting */ @@ -2148,7 +2007,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(-1 == conn->firstsocket) { /* Connect only if not already connected! */ - result = ConnectPlease(data, conn); + result = ConnectPlease(conn); if(CURLE_OK != result) return result; @@ -2196,8 +2055,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else { struct in_addr in; - (void) memcpy(&in.s_addr, *conn->hostaddr->h_addr_list, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, inet_ntoa(in)); + (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); + infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, + inet_ntoa(in)); } #endif -- cgit v1.2.1 From ced89553250030849a9896dae1d446c5ccf1ac3c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Oct 2001 11:26:53 +0000 Subject: IPv6 adjustments, connect()ing to bad ports still don't work properly for IPv6 --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bbd40e827..bc4ae3b2c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1949,7 +1949,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(!conn->hostaddr) { /* it might already be set if reusing a connection */ conn->hostaddr = Curl_getaddrinfo(data, conn->name, conn->port, - &conn->hostent_buf); + &conn->hostent_buf); } if(!conn->hostaddr) { failf(data, "Couldn't resolve host '%s'", conn->name); @@ -1963,7 +1963,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* resolve proxy */ /* it might already be set if reusing a connection */ conn->hostaddr = Curl_getaddrinfo(data, conn->proxyhost, conn->port, - &conn->hostent_buf); + &conn->hostent_buf); if(!conn->hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); @@ -2040,7 +2040,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else const int niflags = NI_NUMERICHOST; #endif - struct addrinfo *ai = conn->ai; + struct addrinfo *ai = conn->serv_addr; if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, niflags)) { -- cgit v1.2.1 From dd028817884ca3262ae4e136332a7fdf469787e9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Oct 2001 12:51:15 +0000 Subject: added port number in informational connect message --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bc4ae3b2c..198170dce 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2047,9 +2047,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, snprintf(hbuf, sizeof(hbuf), "?"); } if (ai->ai_canonname) { - infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf); + infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf, + conn->port); } else { - infof(data, "Connected to %s\n", hbuf); + infof(data, "Connected to %s port %d\n", hbuf, conn->port); } } #else -- cgit v1.2.1 From 5d9ae88f58349022ee437fdf4dfc9e3a7f755beb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 4 Oct 2001 13:25:12 +0000 Subject: getaddrinfo() cleanups --- lib/url.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 198170dce..ddbdc3b16 100644 --- a/lib/url.c +++ b/lib/url.c @@ -879,13 +879,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(conn->proto.generic) free(conn->proto.generic); -#ifdef ENABLE_IPV6 - if(conn->hostaddr) /* host name info */ - freeaddrinfo(conn->hostaddr); -#else if(conn->hostent_buf) /* host name info */ - free(conn->hostent_buf); -#endif + Curl_freeaddrinfo(conn->hostent_buf); if(conn->newurl) free(conn->newurl); -- cgit v1.2.1 From 3685f792cbd271ecdc623de2e0b48e1debab6109 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 9 Oct 2001 06:23:26 +0000 Subject: ignore SIGPIPE, as that can be actually get sent when we write to a socket --- lib/url.c | 119 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 57 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ddbdc3b16..f9dc3a7f3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -206,84 +206,89 @@ CURLcode Curl_open(struct SessionHandle **curl) /* Very simple start-up: alloc the struct, init it with zeroes and return */ data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle)); - if(data) { - memset(data, 0, sizeof(struct SessionHandle)); - - /* We do some initial setup here, all those fields that can't be just 0 */ - - data->state.headerbuff=(char*)malloc(HEADERSIZE); - if(!data->state.headerbuff) { - free(data); /* free the memory again */ - return CURLE_OUT_OF_MEMORY; - } - - data->state.headersize=HEADERSIZE; - - data->set.out = stdout; /* default output to stdout */ - data->set.in = stdin; /* default input from stdin */ - data->set.err = stderr; /* default stderr to stderr */ + if(!data) + /* this is a very serious error */ + return CURLE_OUT_OF_MEMORY; + + memset(data, 0, sizeof(struct SessionHandle)); - /* use fwrite as default function to store output */ - data->set.fwrite = (curl_write_callback)fwrite; + /* We do some initial setup here, all those fields that can't be just 0 */ - /* use fread as default function to read input */ - data->set.fread = (curl_read_callback)fread; + data->state.headerbuff=(char*)malloc(HEADERSIZE); + if(!data->state.headerbuff) { + free(data); /* free the memory again */ + return CURLE_OUT_OF_MEMORY; + } - /* set the default passwd function */ - data->set.fpasswd = my_getpass; + data->state.headersize=HEADERSIZE; - data->set.infilesize = -1; /* we don't know any size */ + 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->set.fwrite = (curl_write_callback)fwrite; - data->state.current_speed = -1; /* init to negative == impossible */ + /* use fread as default function to read input */ + data->set.fread = (curl_read_callback)fread; + + /* set the default passwd function */ + data->set.fpasswd = my_getpass; - data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ + data->set.infilesize = -1; /* we don't know any size */ - /* make libcurl quiet by default: */ - data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ - data->progress.flags |= PGRS_HIDE; + data->state.current_speed = -1; /* init to negative == impossible */ - /* Set the default size of the SSL session ID cache */ - data->set.ssl.numsessions = 5; + data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ - /* create an array with connection data struct pointers */ - data->state.numconnects = 5; /* hard-coded right now */ - data->state.connects = (struct connectdata **) - malloc(sizeof(struct connectdata *) * data->state.numconnects); + /* make libcurl quiet by default: */ + data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ + data->progress.flags |= PGRS_HIDE; - if(!data->state.connects) { - free(data); - return CURLE_OUT_OF_MEMORY; - } + /* Set the default size of the SSL session ID cache */ + data->set.ssl.numsessions = 5; - memset(data->state.connects, 0, - sizeof(struct connectdata *)*data->state.numconnects); + /* create an array with connection data struct pointers */ + data->state.numconnects = 5; /* hard-coded right now */ + data->state.connects = (struct connectdata **) + malloc(sizeof(struct connectdata *) * data->state.numconnects); + + if(!data->state.connects) { + free(data); + return CURLE_OUT_OF_MEMORY; + } + + memset(data->state.connects, 0, + sizeof(struct connectdata *)*data->state.numconnects); - *curl = data; + *curl = data; - /************************************************************* - * Set signal handler - *************************************************************/ + /************************************************************* + * Set signal handler to catch SIGALRM + *************************************************************/ #ifdef HAVE_SIGACTION - sigaction(SIGALRM, NULL, &sigact); - sigact.sa_handler = alarmfunc; + sigaction(SIGALRM, NULL, &sigact); + sigact.sa_handler = alarmfunc; #ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; #endif - sigaction(SIGALRM, &sigact, NULL); + sigaction(SIGALRM, &sigact, NULL); #else - /* no sigaction(), revert to the much lamer signal() */ + /* no sigaction(), revert to the much lamer signal() */ #ifdef HAVE_SIGNAL - signal(SIGALRM, alarmfunc); + signal(SIGALRM, alarmfunc); #endif - #endif - return CURLE_OK; - } - - /* this is a very serious error */ - return CURLE_OUT_OF_MEMORY; + /************************************************************* + * Tell signal handler to ignore SIGPIPE + *************************************************************/ +#if defined(HAVE_SIGNAL) && defined(SIGPIPE) + (void) signal(SIGPIPE, SIG_IGN); +#endif + + return CURLE_OK; } CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) -- cgit v1.2.1 From a9181f8f00d5bdfda39e227ed2ec4076ee4d2baa Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 9 Oct 2001 06:52:37 +0000 Subject: added the option CURLOPT_HTTP_VERSION that can specify which HTTP version libcurl should use in its request --- lib/url.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f9dc3a7f3..a9f12d670 100644 --- a/lib/url.c +++ b/lib/url.c @@ -444,6 +444,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_HTTP_VERSION: + /* + * This sets a requested HTTP version to be used. The value is one of + * the listed enums in curl/curl.h. + */ + data->set.httpversion = va_arg(param, long); + break; case CURLOPT_TRANSFERTEXT: /* * This option was previously named 'FTPASCII'. Renamed to work with @@ -461,15 +468,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) if(va_arg(param, long)) data->set.httpreq = HTTPREQ_PUT; break; -#if 0 - /* obsolete stuff, kept here a while for informational purposes */ - case CURLOPT_MUTE: - /* - * Stay absolutely quiet. - */ - 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 -- cgit v1.2.1 From f2a25966cf7d18070a7f0e7a61379c3a6e7605b5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 10 Oct 2001 12:48:32 +0000 Subject: cookiejar now enables the cookie engine --- lib/url.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a9f12d670..dd44b3864 100644 --- a/lib/url.c +++ b/lib/url.c @@ -503,7 +503,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set cookie file name to dump all cookies to when we're done. */ - data->set.cookiejar = cookiefile = (char *)va_arg(param, void *); + data->set.cookiejar = (char *)va_arg(param, void *); + + /* + * Activate the cookie parser. This may or may not already + * have been made. + */ + data->cookies = Curl_cookie_init(NULL, data->cookies); break; case CURLOPT_WRITEHEADER: /* -- cgit v1.2.1 From 8e91d5de8e4e17ce3d4936cc91171d09726e7bb3 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Thu, 11 Oct 2001 09:32:19 +0000 Subject: looks nicer and is better compatible with older vim versions --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dd44b3864..2f85212e6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2160,6 +2160,6 @@ CURLcode Curl_do(struct connectdata *conn) * local variables: * eval: (load-file "../curl-mode.el") * end: - * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker - * vim<600: et sw=2 ts=2 sts=2 tw=78 + * vim600: fdm=marker + * vim: et sw=2 ts=2 sts=2 tw=78 */ -- cgit v1.2.1 From 532bca41e59e10a86c356058831cf046a3ba78c9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Oct 2001 12:32:20 +0000 Subject: Curl_tvdiff() now returns a millisecond diff, no double like before --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2f85212e6..9b24a221b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1055,14 +1055,14 @@ ConnectionKillOne(struct SessionHandle *data) * Set higher score for the age passed since the connection * was used. */ - score = Curl_tvlong(now) - Curl_tvlong(conn->now); + score = Curl_tvdiff(now, conn->now); break; case CURLCLOSEPOLICY_OLDEST: /* * Set higher score for the age passed since the connection * was created. */ - score = Curl_tvlong(now) - Curl_tvlong(conn->created); + score = Curl_tvdiff(now, conn->created); break; } -- cgit v1.2.1 From 4e37187e44b85aa11fee92eca4d87b3839cd435f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Oct 2001 11:58:32 +0000 Subject: now counts header size return from server and if nothing is returned from a HTTP server we return error --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9b24a221b..60be9322e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2034,6 +2034,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->now = Curl_tvnow(); /* time this *after* the connect is done */ conn->bytecount = 0; + conn->headerbytecount = 0; /* Figure out the ip-number and display the first host name it shows: */ #ifdef ENABLE_IPV6 -- cgit v1.2.1 From 42a9d96faebb068516697473a6180c0027c65e6f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 Oct 2001 10:10:21 +0000 Subject: fixed conn->name error on connection re-use and enlarged the 'gname' array to hold 512 bytes (for user+password+hostname) --- lib/url.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 60be9322e..e16766fce 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1280,14 +1280,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, strcpy(conn->path, "/"); if (2 > sscanf(data->change.url, - "%64[^\n:]://%256[^\n/]%[^\n]", + "%64[^\n:]://%512[^\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->change.url, "%256[^\n/]%[^\n]", + if((1 > sscanf(data->change.url, "%512[^\n/]%[^\n]", conn->gname, conn->path)) ) { /* * We couldn't even get this format. @@ -1872,7 +1872,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn = conn_temp; /* use this connection from now on */ /* we need these pointers if we speak over a proxy */ - conn->name = conn->gname; conn->hostname = old_conn->gname; free(conn->path); /* free the previously allocated path pointer */ -- cgit v1.2.1 From dbd32278f869331683fcf15c4c04fc6c3e0d1611 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 30 Oct 2001 15:21:45 +0000 Subject: Added an additional SSL check for a dead socket before we re-use an SSL connection. The simple socket-check is not enough in these cases. --- lib/url.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e16766fce..bd01136d8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -935,7 +935,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) * be dead. Most commonly this happens when the server has closed the * connection due to inactivity. */ -static bool SocketIsDead(int sock) +static bool SocketIsDead(struct connectdata *conn, int sock) { int sval; bool ret_val = TRUE; @@ -949,9 +949,17 @@ static bool SocketIsDead(int sock) to.tv_usec = 1; sval = select(sock + 1, &check_set, 0, 0, &to); - if(sval == 0) + if(sval == 0) { /* timeout */ - ret_val = FALSE; + ret_val = FALSE; +#ifdef USE_SSLEAY + /* the socket seems fine, but is the SSL later fine too? */ + if(conn->ssl.use) { + if(SSL_get_shutdown(conn->ssl.handle)) + return TRUE; /* this connection is dead! */ + } +#endif + } return ret_val; } @@ -994,7 +1002,7 @@ ConnectionExists(struct SessionHandle *data, continue; } } - dead = SocketIsDead(check->firstsocket); + dead = SocketIsDead(check, check->firstsocket); if(dead) { infof(data, "Connection %d seems to be dead!\n", i); Curl_disconnect(check); /* disconnect resources */ -- cgit v1.2.1 From b07e2a08f9a98f7261d82f3ad5931ac5bcfb05a4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 31 Oct 2001 08:44:11 +0000 Subject: nonblock => Curl_nonblock, remade the check for a live SSL connection (again) --- lib/url.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bd01136d8..b11d33aac 100644 --- a/lib/url.c +++ b/lib/url.c @@ -955,8 +955,27 @@ static bool SocketIsDead(struct connectdata *conn, int sock) #ifdef USE_SSLEAY /* the socket seems fine, but is the SSL later fine too? */ if(conn->ssl.use) { - if(SSL_get_shutdown(conn->ssl.handle)) - return TRUE; /* this connection is dead! */ + int peek; + int error; + Curl_nonblock(sock, TRUE); + + peek = SSL_peek(conn->ssl.handle, + conn->data->state.buffer, BUFSIZE); + + infof(conn->data, "SSL_peek returned %d\n", peek); + + if(-1 == peek) { + error = SSL_get_error(conn->ssl.handle, peek); + infof(conn->data, "SSL_error returned %d\n", error); + + if(SSL_ERROR_WANT_READ != error) + ret_val = TRUE; + } + else + /* peek did not return -1 */ + ret_val = TRUE; + + Curl_nonblock(sock, FALSE); } #endif } -- cgit v1.2.1 From c4f1a9f690449482ee4333e1ec58169d5e5a3d25 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 31 Oct 2001 15:14:52 +0000 Subject: Removed the SocketIsDead() stuff for SSL again as it doesn't work. We must rely on the new go-ahead-and-try mechanism that I just added to Transfer() --- lib/url.c | 37 +++++-------------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b11d33aac..0d0cf6ab5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -877,7 +877,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(-1 != conn->connectindex) { /* unlink ourselves! */ - infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex); + infof(conn->data, "Closing connection #%d\n", conn->connectindex); conn->data->state.connects[conn->connectindex] = NULL; } @@ -935,7 +935,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) * be dead. Most commonly this happens when the server has closed the * connection due to inactivity. */ -static bool SocketIsDead(struct connectdata *conn, int sock) +static bool SocketIsDead(int sock) { int sval; bool ret_val = TRUE; @@ -949,36 +949,9 @@ static bool SocketIsDead(struct connectdata *conn, int sock) to.tv_usec = 1; sval = select(sock + 1, &check_set, 0, 0, &to); - if(sval == 0) { + if(sval == 0) /* timeout */ ret_val = FALSE; -#ifdef USE_SSLEAY - /* the socket seems fine, but is the SSL later fine too? */ - if(conn->ssl.use) { - int peek; - int error; - Curl_nonblock(sock, TRUE); - - peek = SSL_peek(conn->ssl.handle, - conn->data->state.buffer, BUFSIZE); - - infof(conn->data, "SSL_peek returned %d\n", peek); - - if(-1 == peek) { - error = SSL_get_error(conn->ssl.handle, peek); - infof(conn->data, "SSL_error returned %d\n", error); - - if(SSL_ERROR_WANT_READ != error) - ret_val = TRUE; - } - else - /* peek did not return -1 */ - ret_val = TRUE; - - Curl_nonblock(sock, FALSE); - } -#endif - } return ret_val; } @@ -1021,7 +994,7 @@ ConnectionExists(struct SessionHandle *data, continue; } } - dead = SocketIsDead(check, check->firstsocket); + dead = SocketIsDead(check->firstsocket); if(dead) { infof(data, "Connection %d seems to be dead!\n", i); Curl_disconnect(check); /* disconnect resources */ @@ -2167,7 +2140,7 @@ CURLcode Curl_done(struct connectdata *conn) ((CURLE_OK == result) && conn->bits.close)) result = Curl_disconnect(conn); /* close the connection */ else - infof(data, "Connection (#%d) left alive\n", conn->connectindex); + infof(data, "Connection #%d left intact\n", conn->connectindex); return result; } -- cgit v1.2.1 From 9b6545c479394e5ca7c52c1c1d59086533783521 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 1 Nov 2001 13:54:32 +0000 Subject: ConnectionExists() now returns FALSE immediately if it finds a connection that is dead, because it can only find one entry anyway and if that is dead there won't be any other entry that matches --- lib/url.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0d0cf6ab5..6b2a3a8c2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -996,10 +996,20 @@ ConnectionExists(struct SessionHandle *data, } dead = SocketIsDead(check->firstsocket); if(dead) { + /* + * Even though the connection seems to have passed away, we could + * still make an effort to get the name information, as we intend to + * connect to the same host again. + * + * This is now subject to discussion. What do you think? + */ infof(data, "Connection %d seems to be dead!\n", i); Curl_disconnect(check); /* disconnect resources */ data->state.connects[i]=NULL; /* nothing here */ - continue; /* try another one now */ + + /* There's no need to continue search, because we only store + one connection for each unique set of identifiers */ + return FALSE; } *usethis = check; -- cgit v1.2.1 From 2e32d415c0e7df143b93d6c112ffb88103f51058 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 6 Nov 2001 19:33:13 +0000 Subject: myalarm() is history, we now use HAVE_ALARM and we now do our very best to 1 - restore the previous sigaction struct as soon as we are about to shut off our timeout 2 - restore the previous alarm() timeout, in case an application or similar had it running before we "borrowed" it for a while. No, this does not fix the multi-thread problem you get with alarm(). This patch should correct bug report #478780: //sourceforge.net/tracker/?func=detail&atid=100976&aid=478780&group_id=976 If not, please post details! --- lib/url.c | 112 ++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 33 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6b2a3a8c2..5810e859b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -72,7 +72,6 @@ #include #endif - #ifndef HAVE_SELECT #error "We can't compile without select() support!" #endif @@ -200,10 +199,6 @@ CURLcode Curl_open(struct SessionHandle **curl) { /* We don't yet support specifying the URL at this point */ 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 SessionHandle *)malloc(sizeof(struct SessionHandle)); if(!data) @@ -263,24 +258,6 @@ CURLcode Curl_open(struct SessionHandle **curl) *curl = data; - /************************************************************* - * Set signal handler to catch SIGALRM - *************************************************************/ -#ifdef HAVE_SIGACTION - sigaction(SIGALRM, NULL, &sigact); - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - sigaction(SIGALRM, &sigact, NULL); -#else - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - signal(SIGALRM, alarmfunc); -#endif -#endif - /************************************************************* * Tell signal handler to ignore SIGPIPE *************************************************************/ @@ -1170,6 +1147,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata *conn_temp; char endbracket; int urllen; +#ifdef HAVE_ALARM + unsigned int prev_alarm; +#endif + +#ifdef HAVE_SIGACTION + struct sigaction keep_sigact; /* store the old struct here */ + bool keep_copysig; /* did copy it? */ +#endif /************************************************************* * Check input data @@ -1937,17 +1922,43 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Set timeout if that is being used *************************************************************/ if(data->set.timeout || data->set.connecttimeout) { + /************************************************************* + * Set signal handler to catch SIGALRM + * Store the old value to be able to set it back later! + *************************************************************/ + +#ifdef HAVE_SIGACTION + struct sigaction sigact; + sigaction(SIGALRM, NULL, &sigact); + sigact.sa_handler = alarmfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; +#endif + /* now set the new struct */ + sigaction(SIGALRM, &sigact, NULL); +#else + /* no sigaction(), revert to the much lamer signal() */ +#ifdef HAVE_SIGNAL + signal(SIGALRM, alarmfunc); +#endif +#endif + /* We set the timeout on the name resolving phase first, separately from * the download/upload part to allow a maximum time on everything. This is * a signal-based timeout, why it won't work and shouldn't be used in * multi-threaded environments. */ - /* myalarm() makes a signal get sent when the timeout fires off, and that +#ifdef HAVE_ALARM + /* alarm() makes a signal get sent when the timeout fires off, and that will abort system calls */ - if(data->set.connecttimeout) - myalarm(data->set.connecttimeout); - else - myalarm(data->set.timeout); + prev_alarm = alarm(data->set.connecttimeout? + data->set.connecttimeout: + data->set.timeout); + /* We can expect the conn->created time to be "now", as that was just + recently set in the beginning of this function and nothing slow + has been done since then until now. */ +#endif } /************************************************************* @@ -1966,7 +1977,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if(!conn->hostaddr) { failf(data, "Couldn't resolve host '%s'", conn->name); - return CURLE_COULDNT_RESOLVE_HOST; + result = CURLE_COULDNT_RESOLVE_HOST; + /* don't return yet, we need to clean up the timeout first */ } } else if(!conn->hostaddr) { @@ -1980,13 +1992,47 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(!conn->hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); - return CURLE_COULDNT_RESOLVE_PROXY; + result = CURLE_COULDNT_RESOLVE_PROXY; + /* don't return yet, we need to clean up the timeout first */ } } Curl_pgrsTime(data, TIMER_NAMELOOKUP); - if(data->set.timeout || data->set.connecttimeout) - /* switch off signal-based timeouts */ - myalarm(0); +#ifdef HAVE_ALARM + if(data->set.timeout || data->set.connecttimeout) { +#ifdef HAVE_SIGACTION + if(keep_copysig) { + /* we got a struct as it looked before, now put that one back nice + and clean */ + sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ + } +#endif + /* switch back the alarm() to either zero or to what it was before minus + the time we spent until now! */ + if(prev_alarm) { + /* there was an alarm() set before us, now put it back */ + long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); + long alarm_set; + + /* the alarm period is counted in even number of seconds */ + alarm_set = prev_alarm - elapsed_ms/1000; + + if(alarm_set<=0) { + /* if it turned negative, we should fire off a SIGALRM here, but we + won't, and zero would be to switch it off so we never set it to + less than 1! */ + alarm(1); + result = CURLE_OPERATION_TIMEOUTED; + failf(data, "Previous alarm fired off!"); + } + else + alarm(alarm_set); + } + else + alarm(0); /* just shut it off */ + } +#endif + if(result) + return result; /************************************************************* * Proxy authentication -- cgit v1.2.1 From 1a984ea84771a85df08f6a97e7cbac3ce379743e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Nov 2001 12:56:13 +0000 Subject: get the previous struct keep_sigact --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5810e859b..31e1459ca 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1930,6 +1930,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_SIGACTION struct sigaction sigact; sigaction(SIGALRM, NULL, &sigact); + keep_sigact = sigact; sigact.sa_handler = alarmfunc; #ifdef SA_RESTART /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ -- cgit v1.2.1 From fe3a78ab1997f650dd6e76a7a0ba51b72546221e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Nov 2001 14:13:29 +0000 Subject: we use signal() to ignore signals only as long as we have to, and we now restore the previous (if any) signal handler properly on return. --- lib/url.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 31e1459ca..079e9575a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -143,13 +143,23 @@ RETSIGTYPE alarmfunc(int signal) } #endif + +/* + * This is the internal function curl_easy_cleanup() calls. This should + * cleanup and free all resources associated with this sessionhandle. + * + * NOTE: if we ever add something that attempts to write to a socket or + * similar here, we must ignore SIGPIPE first. It is currently only done + * when curl_easy_perform() is invoked. + */ + CURLcode Curl_close(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ while(-1 != ConnectionKillOne(data)); #ifdef USE_SSLEAY - /* Close down all open info open SSL and sessions */ + /* Close down all open SSL info and sessions */ Curl_SSL_Close_All(data); #endif @@ -258,13 +268,6 @@ CURLcode Curl_open(struct SessionHandle **curl) *curl = data; - /************************************************************* - * Tell signal handler to ignore SIGPIPE - *************************************************************/ -#if defined(HAVE_SIGNAL) && defined(SIGPIPE) - (void) signal(SIGPIPE, SIG_IGN); -#endif - return CURLE_OK; } @@ -1141,7 +1144,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, { char *tmp; char *buf; - CURLcode result; + CURLcode result=CURLE_OK; char resumerange[40]=""; struct connectdata *conn; struct connectdata *conn_temp; @@ -1154,6 +1157,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ bool keep_copysig; /* did copy it? */ +#else +#ifdef HAVE_SIGNAL + void *keep_sigact; /* store the old handler here */ +#endif #endif /************************************************************* @@ -1941,7 +1948,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else /* no sigaction(), revert to the much lamer signal() */ #ifdef HAVE_SIGNAL - signal(SIGALRM, alarmfunc); + keep_sigact = signal(SIGALRM, alarmfunc); #endif #endif @@ -2006,6 +2013,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, and clean */ sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ } +#else +#ifdef HAVE_SIGNAL + /* restore the previous SIGALRM handler */ + signal(SIGALRM, keep_sigact); +#endif #endif /* switch back the alarm() to either zero or to what it was before minus the time we spent until now! */ -- cgit v1.2.1 From 05f3ca880fa092e4fd8684d39cb52401fedc9db7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Nov 2001 14:08:41 +0000 Subject: made CURLOPT_HTTPPROXYTUNNEL work for plain HTTP as well --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 079e9575a..1b836c45b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1543,6 +1543,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; + conn->curl_connect = Curl_http_connect; } else if (strequal(conn->protostr, "HTTPS")) { #ifdef USE_SSLEAY -- cgit v1.2.1 From 332eb7651a651ef03dc15197a8d11baa54873f8d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 28 Nov 2001 23:20:14 +0000 Subject: CURLOPT_FTP_USE_EPSV can now be set to FALSE to prevent libcurl from attempting to use EPSV before the standard PASV. --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1b836c45b..c1a58be61 100644 --- a/lib/url.c +++ b/lib/url.c @@ -245,6 +245,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->state.current_speed = -1; /* init to negative == impossible */ data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ + data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ /* make libcurl quiet by default: */ data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ @@ -523,6 +524,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ftpport = va_arg(param, char *); data->set.ftp_use_port = data->set.ftpport?1:0; break; + + case CURLOPT_FTP_USE_EPSV: + data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; + break; + case CURLOPT_HTTPHEADER: /* * Set a list with HTTP headers to use (or replace internals with) -- cgit v1.2.1 From 533c24a4712d0565ae0de89cd64e0d3adce78966 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Nov 2001 12:49:10 +0000 Subject: disabling EPSV is now possible --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c1a58be61..2275d399f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1945,6 +1945,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct sigaction sigact; sigaction(SIGALRM, NULL, &sigact); keep_sigact = sigact; + keep_copysig = TRUE; /* yes, we have a copy */ sigact.sa_handler = alarmfunc; #ifdef SA_RESTART /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ -- cgit v1.2.1 From c16c017f8beca4ac56820e7aef072f2d0714f5b3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 2 Dec 2001 14:16:34 +0000 Subject: more careful re-use of connections when SSL is used over proxies --- lib/url.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2275d399f..1ffe5dae9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -943,9 +943,9 @@ static bool SocketIsDead(int sock) } /* - * Given one filled in connection struct, this function should detect if there - * already is one that have all the significant details exactly the same and - * thus should be used instead. + * Given one filled in connection struct (named needle), this function should + * detect if there already is one that have all the significant details + * exactly the same and thus should be used instead. */ static bool ConnectionExists(struct SessionHandle *data, @@ -964,8 +964,14 @@ ConnectionExists(struct SessionHandle *data, if(!check) /* NULL pointer means not filled-in entry */ continue; - if(!needle->bits.httpproxy) { - /* The requested connection does not use a HTTP proxy */ + if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) { + /* The requested connection does not use a HTTP proxy or it + uses SSL. */ + + if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy) + /* we don't do SSL but the cached connection has a proxy, + then don't match this */ + continue; if(strequal(needle->protostr, check->protostr) && strequal(needle->name, check->name) && @@ -1556,8 +1562,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, 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; + conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; @@ -1588,7 +1593,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(strequal(conn->protostr, "FTPS")) { #ifdef USE_SSLEAY - conn->protocol |= PROT_FTPS; + conn->protocol |= PROT_FTPS|PROT_SSL; #else failf(data, LIBCURL_NAME " was built with SSL disabled, ftps: not supported!"); -- cgit v1.2.1 From 7b832e1745f0d264489b45d0ef88e845238b1871 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 5 Dec 2001 06:47:01 +0000 Subject: Jon Travis suggested fix. when CURLOPT_HTTPGET is used we must assign set.upload to FALSE or else we might still get an upload if the previous operation was an upload! --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1ffe5dae9..3b5482c2b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -556,8 +556,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set to force us do HTTP GET */ - if(va_arg(param, long)) + if(va_arg(param, long)) { data->set.httpreq = HTTPREQ_GET; + data->set.upload = FALSE; /* switch off upload */ + } break; case CURLOPT_INFILE: -- cgit v1.2.1 From af6c394785d9ca41ec34ab26a9308b8a4d2a1260 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 17 Dec 2001 23:01:39 +0000 Subject: =?UTF-8?q?G=F6tz=20Babin-Ebell's=20OpenSSL=20ENGINE=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3b5482c2b..808f9c0be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -790,11 +790,75 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.cert = va_arg(param, char *); break; - case CURLOPT_SSLCERTPASSWD: + case CURLOPT_SSLCERTTYPE: /* - * String that holds the SSL certificate password. + * String that holds file type of the SSL certificate to use */ - data->set.cert_passwd = va_arg(param, char *); + data->set.cert_type = va_arg(param, char *); + break; + case CURLOPT_SSLKEY: + /* + * String that holds file name of the SSL certificate to use + */ + data->set.key = va_arg(param, char *); + break; + case CURLOPT_SSLKEYTYPE: + /* + * String that holds file type of the SSL certificate to use + */ + data->set.key_type = va_arg(param, char *); + break; + case CURLOPT_SSLKEYPASSWD: + /* + * String that holds the SSL private key password. + */ + data->set.key_passwd = va_arg(param, char *); + break; + case CURLOPT_SSLENGINE: + /* + * String that holds the SSL crypto engine. + */ +#ifdef HAVE_OPENSSL_ENGINE_H + { + const char *cpTemp = va_arg(param, char *); + ENGINE *e; + if (cpTemp && cpTemp[0]) { + e = ENGINE_by_id(cpTemp); + if (e) { + if (data->engine) { + ENGINE_free(data->engine); + } + data->engine = e; + } + else { + failf(data, "SSL Engine '%s' not found", cpTemp); + return CURLE_SSL_ENGINE_NOTFOUND; + } + } + } +#else + return CURLE_SSL_ENGINE_NOTFOUND; +#endif + break; + case CURLOPT_SSLENGINE_DEFAULT: + /* + * flag to set engine as default. + */ +#ifdef HAVE_OPENSSL_ENGINE_H + if (data->engine) { + if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) { +#ifdef DEBUG + fprintf(stderr,"set default crypto engine\n"); +#endif + } + else { +#ifdef DEBUG + failf(data, "set default crypto engine failed"); +#endif + return CURLE_SSL_ENGINE_SETFAILED; + } + } +#endif break; case CURLOPT_CRLF: /* -- cgit v1.2.1 From 8a9098a36c1723a5fdae9b585c9c10eae738efc5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 20 Dec 2001 15:58:22 +0000 Subject: =?UTF-8?q?*cool*=20fix=20by=20Bj=F6rn=20Stenberg,=20makes=20proxy?= =?UTF-8?q?=20transfers=20work=20better...!=20:-)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 808f9c0be..79e6ced7b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1566,6 +1566,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* we have a proxy here to set */ data->change.proxy = proxy; data->change.proxy_alloc=TRUE; /* this needs to be freed later */ + conn->bits.httpproxy = TRUE; } } /* if (!nope) - it wasn't specified non-proxy */ } /* NO_PROXY wasn't specified or '*' */ -- cgit v1.2.1 From 6de7dc5879b3605a180dafa05f792f132eafdcaa Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Jan 2002 10:22:59 +0000 Subject: Sterling Hughes' provided initial DNS cache source code. --- lib/url.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 79e6ced7b..5a477a26d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -940,9 +940,6 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(conn->proto.generic) free(conn->proto.generic); - if(conn->hostent_buf) /* host name info */ - Curl_freeaddrinfo(conn->hostent_buf); - if(conn->newurl) free(conn->newurl); @@ -2060,8 +2057,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Resolve target host right on */ if(!conn->hostaddr) { /* it might already be set if reusing a connection */ - conn->hostaddr = Curl_getaddrinfo(data, conn->name, conn->port, - &conn->hostent_buf); + conn->hostaddr = Curl_resolv(data, conn->name, conn->port, + &conn->hostent_buf); } if(!conn->hostaddr) { failf(data, "Couldn't resolve host '%s'", conn->name); @@ -2075,8 +2072,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* resolve proxy */ /* it might already be set if reusing a connection */ - conn->hostaddr = Curl_getaddrinfo(data, conn->proxyhost, conn->port, - &conn->hostent_buf); + conn->hostaddr = Curl_resolv(data, conn->proxyhost, conn->port, + &conn->hostent_buf); if(!conn->hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); -- cgit v1.2.1 From 8b6314ccfbe48bba2cd560812dd1841425f3bd79 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Jan 2002 15:01:22 +0000 Subject: merged the multi-dev branch back into MAIN again --- lib/url.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5a477a26d..3973902ef 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1214,8 +1214,7 @@ static CURLcode ConnectPlease(struct connectdata *conn) } static CURLcode CreateConnection(struct SessionHandle *data, - struct connectdata **in_connect, - bool allow_port) /* allow set.use_port? */ + struct connectdata **in_connect) { char *tmp; char *buf; @@ -1614,7 +1613,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, *************************************************************/ if (strequal(conn->protostr, "HTTP")) { - conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTP; + conn->port = (data->set.use_port && data->state.allow_port)? + data->set.use_port:PORT_HTTP; conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; @@ -1624,7 +1624,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, else if (strequal(conn->protostr, "HTTPS")) { #ifdef USE_SSLEAY - conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTPS; + conn->port = (data->set.use_port && data->state.allow_port)? + data->set.use_port:PORT_HTTPS; conn->remote_port = PORT_HTTPS; conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; @@ -1639,7 +1640,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif /* !USE_SSLEAY */ } else if (strequal(conn->protostr, "GOPHER")) { - conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_GOPHER; + conn->port = (data->set.use_port && data->state.allow_port)? + data->set.use_port:PORT_GOPHER; conn->remote_port = PORT_GOPHER; /* Skip // in path if present */ if (isdigit((int)conn->path[1])) { @@ -1665,7 +1667,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif /* !USE_SSLEAY */ } - conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_FTP; + conn->port = (data->set.use_port && data->state.allow_port)? + data->set.use_port:PORT_FTP; conn->remote_port = PORT_FTP; conn->protocol |= PROT_FTP; @@ -1720,21 +1723,24 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* telnet testing factory */ conn->protocol |= PROT_TELNET; - conn->port = (data->set.use_port && allow_port)?data->set.use_port: PORT_TELNET; + conn->port = (data->set.use_port && data->state.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->set.use_port && allow_port)?data->set.use_port:PORT_DICT; + conn->port = (data->set.use_port && data->state.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->set.use_port && allow_port)?data->set.use_port:PORT_LDAP; + conn->port = (data->set.use_port && data->state.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 */ @@ -2228,14 +2234,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, } CURLcode Curl_connect(struct SessionHandle *data, - struct connectdata **in_connect, - bool allow_port) + struct connectdata **in_connect) { CURLcode code; struct connectdata *conn; /* call the stuff that needs to be called */ - code = CreateConnection(data, in_connect, allow_port); + code = CreateConnection(data, in_connect); if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated @@ -2291,14 +2296,38 @@ CURLcode Curl_done(struct connectdata *conn) return result; } -CURLcode Curl_do(struct connectdata *conn) +CURLcode Curl_do(struct connectdata **connp) { CURLcode result=CURLE_OK; + struct connectdata *conn = *connp; + struct SessionHandle *data=conn->data; - if(conn->curl_do) + if(conn->curl_do) { /* generic protocol-specific function pointer set in curl_connect() */ result = conn->curl_do(conn); + /* This was formerly done in transfer.c, but we better do it here */ + + if((CURLE_WRITE_ERROR == result) && conn->bits.reuse) { + /* This was a re-use of a connection and we got a write error in the + * DO-phase. Then we DISCONNECT this connection and have another attempt + * to CONNECT and then DO again! The retry cannot possibly find another + * connection to re-use, since we only keep one possible connection for + * each. */ + + infof(data, "Re-used connection seems dead, get a new one\n"); + + conn->bits.close = TRUE; /* enforce close of this connetion */ + result = Curl_done(conn); /* we are so done with this */ + if(CURLE_OK == result) { + /* Now, redo the connect and get a new connection */ + result = Curl_connect(data, connp); + if(CURLE_OK == result) + /* ... finally back to actually retry the DO phase */ + result = conn->curl_do(*connp); + } + } + } return result; } -- cgit v1.2.1 From f75ff58b4b2ddf2181a69199f65a7d7cc55aaa52 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 4 Jan 2002 09:38:52 +0000 Subject: an unconditional occurance of inet_ntoa() now uses inet_ntoa_r() on all platforms that have such a function. This affects multi-thread running libcurls on IPv4 systems that have VERBOSE switched on. The previous version was risking that another thread overwrote the data before it was read out in this thread. There could possibly also be a slight risk that the data isn't zero terminated for a short while and thus could cause the thread to crash... --- lib/url.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3973902ef..5f7568005 100644 --- a/lib/url.c +++ b/lib/url.c @@ -110,6 +110,10 @@ #include +#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) +#include "inet_ntoa_r.h" +#endif + #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -1224,6 +1228,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata *conn_temp; char endbracket; int urllen; +#ifdef HAVE_INET_NTOA_R + char ntoa_buf[64]; +#endif #ifdef HAVE_ALARM unsigned int prev_alarm; #endif @@ -2214,7 +2221,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, - inet_ntoa(in)); +#if defined(HAVE_INET_NTOA_R) + inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)) +#else + inet_ntoa(in) +#endif + ); } #endif -- cgit v1.2.1 From 8d7f402efbcace85851c6bb8f6aa2452c15a9595 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Mon, 7 Jan 2002 20:52:32 +0000 Subject: Make cach'ing work with threads now, there are now three cases: - Use a global dns cache (via setting the tentatively named, CURLOPT_DNS_USE_GLOBAL_CACHE option to true) - Use a per-handle dns cache, by default - Use a pooled dns cache when in the "multi" interface --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5f7568005..56e7fa73f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -284,6 +284,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) va_start(param, option); switch(option) { + case CURLOPT_DNS_USE_GLOBAL_CACHE: { + int use_cache = va_arg(param, int); + if (use_cache) { + Curl_global_host_cache_init(); + } + + data->set.global_dns_cache = use_cache; + } + break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ data->set.ssl.cipher_list = va_arg(param, char *); -- cgit v1.2.1 From 22ac08e06db32cb2a7872316a669eb81ec3ea204 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Tue, 8 Jan 2002 04:26:47 +0000 Subject: Add support for DNS cache timeouts via the CURLOPT_DNS_CACHE_TIMEOUT option. The default cache timeout for this is 60 seconds, which is arbitrary and completely subject to change :) --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 56e7fa73f..63d9ae56a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -251,13 +251,15 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ + data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + /* make libcurl quiet by default: */ 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->set.ssl.numsessions = 5; - + /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ data->state.connects = (struct connectdata **) @@ -284,7 +286,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) va_start(param, option); switch(option) { - case CURLOPT_DNS_USE_GLOBAL_CACHE: { + case CURLOPT_DNS_CACHE_TIMEOUT: + data->set.dns_cache_timeout = va_arg(param, int); + break; + case CURLOPT_DNS_USE_GLOBAL_CACHE: + { int use_cache = va_arg(param, int); if (use_cache) { Curl_global_host_cache_init(); -- cgit v1.2.1 From c341b11aafedb8beb209342dbfb12f9d70f742b4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 28 Jan 2002 19:31:26 +0000 Subject: Steve Marx helped us realize that we shouldn't treat customrequest as a request of its own, it just changes the keyword of a request. --- lib/url.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 63d9ae56a..52b70f638 100644 --- a/lib/url.c +++ b/lib/url.c @@ -559,8 +559,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Set a custom string to use as request */ data->set.customrequest = va_arg(param, char *); - if(data->set.customrequest) - data->set.httpreq = HTTPREQ_CUSTOM; + + /* we don't set + data->set.httpreq = HTTPREQ_CUSTOM; + here, we continue as if we were using the already set type + and this just changes the actual request keyword */ break; case CURLOPT_HTTPPOST: /* -- cgit v1.2.1 From 76c53c690cefa62e09aa553d0f1f9a26122c0ff1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 29 Jan 2002 10:49:32 +0000 Subject: Giaslas Georgios introduced CURLINFO_CONTENT_TYPE --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 52b70f638..6092c281c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -191,6 +191,9 @@ CURLcode Curl_close(struct SessionHandle *data) /* free the connection cache */ free(data->state.connects); + if(data->info.contenttype) + free(data->info.contenttype); + free(data); return CURLE_OK; } -- cgit v1.2.1 From be2f3071b50dcf6cde1d30a76a5b40464594c4bf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 29 Jan 2002 20:34:30 +0000 Subject: conn->upload_bufsize exists no more --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6092c281c..c26f2a199 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1292,7 +1292,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* and we setup a few fields in case we end up actually using this struct */ conn->data = data; /* remember our daddy */ - conn->upload_bufsize = UPLOAD_BUFSIZE; /* default upload buffer size */ conn->firstsocket = -1; /* no file descriptor */ conn->secondarysocket = -1; /* no file descriptor */ conn->connectindex = -1; /* no index */ -- cgit v1.2.1 From feb6b6445ee7ad619dbae742b3f81ebe4011faa6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 Feb 2002 11:17:37 +0000 Subject: Giaslas Georgios's Host: over proxy fix --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c26f2a199..fc2031c94 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1984,6 +1984,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* we need these pointers if we speak over a proxy */ conn->hostname = old_conn->gname; + conn->name = old_conn->name; free(conn->path); /* free the previously allocated path pointer */ -- cgit v1.2.1 From 80b004a57d6fe8ce2d2fceb29b6eb4a7101da958 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Feb 2002 23:31:23 +0000 Subject: Wesley Laxton's CURLOPT_PREQUOTE work --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fc2031c94..e88a65e85 100644 --- a/lib/url.c +++ b/lib/url.c @@ -735,6 +735,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.postquote = va_arg(param, struct curl_slist *); break; + case CURLOPT_PREQUOTE: + /* + * List of RAW FTP commands to use prior to RETR (Wesley Laxton) + */ + data->set.prequote = va_arg(param, struct curl_slist *); + break; case CURLOPT_QUOTE: /* * List of RAW FTP commands to use before a transfer @@ -1983,8 +1989,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn = conn_temp; /* use this connection from now on */ /* we need these pointers if we speak over a proxy */ - conn->hostname = old_conn->gname; - conn->name = old_conn->name; + conn->hostname = conn->gname; + conn->name = &conn->gname[old_conn->name - old_conn->gname]; free(conn->path); /* free the previously allocated path pointer */ -- cgit v1.2.1 From 017be8a882113c5414ac283266491ca8035c0092 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 8 Mar 2002 15:06:42 +0000 Subject: Jean-Philippe Barrette-LaPierre fixed the CURLOPT_PASSWDFUNCTION to make NULL set back the internal default function --- lib/url.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e88a65e85..e42ce9aed 100644 --- a/lib/url.c +++ b/lib/url.c @@ -765,6 +765,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Password prompt callback */ data->set.fpasswd = va_arg(param, curl_passwd_callback); + /* + * if the callback provided is null, reset the default callback + */ + if(!data->set.fpasswd) + { + data->set.fpasswd = my_getpass; + } break; case CURLOPT_PASSWDDATA: /* @@ -1456,11 +1463,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* check for password, if no ask for one */ if( !data->state.passwd[0] ) { - if(!data->set.fpasswd || + if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, - "password:", data->state.passwd, + "password:", data->state.passwd, sizeof(data->state.passwd))) + { + failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; + } } } @@ -1486,8 +1496,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, data->set.fpasswd( data->set.passwd_client, "proxy password:", data->state.proxypasswd, - sizeof(data->state.proxypasswd))) + sizeof(data->state.proxypasswd))) { + failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; + } } } @@ -1860,8 +1872,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(!data->set.fpasswd || data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, - sizeof(data->state.passwd))) + sizeof(data->state.passwd))) { + failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; + } } else { /* we have a password found in the URL, decode it! */ -- cgit v1.2.1 From e1bae4fc7e3c565ea4ccd8a61b68f2f68c9a931d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 13 Mar 2002 13:10:52 +0000 Subject: Setting CURLOPT_PASSWDFUNCTION to NULL now restores the internal function. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e42ce9aed..cd1854328 100644 --- a/lib/url.c +++ b/lib/url.c @@ -752,7 +752,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Progress callback function */ data->set.fprogress = va_arg(param, curl_progress_callback); - data->progress.callback = TRUE; /* no longer internal */ + if(data->set.fprogress) + data->progress.callback = TRUE; /* no longer internal */ + else + data->progress.callback = FALSE; /* NULL enforces internal */ + break; case CURLOPT_PROGRESSDATA: /* -- cgit v1.2.1 From 7886f120f3cf98c337386f335ce67e85714620b6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Mar 2002 14:37:16 +0000 Subject: CURLOPT_POST deserved a new comment with the new POST-by-callback support --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cd1854328..a75fafbc4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -634,8 +634,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.use_port = va_arg(param, long); break; case CURLOPT_POST: - /* Does this option serve a purpose anymore? */ - + /* Does this option serve a purpose anymore? Yes it does, when + CURLOPT_POSTFIELDS isn't used and the POST data is read off the + callback! */ if(va_arg(param, long)) data->set.httpreq = HTTPREQ_POST; break; -- cgit v1.2.1 From 974f314f5785156af6983675aeb28313cc8ba2ea Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 19 Mar 2002 07:54:55 +0000 Subject: copyright string (year) update --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a75fafbc4..9cd8fdb0e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2001, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. * * In order to be useful for every potential user, curl and libcurl are * dual-licensed under the MPL and the MIT/X-derivate licenses. -- cgit v1.2.1 From a03fd7b81c67c703d45bec58836ccacf3b249ddd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 4 Apr 2002 12:23:14 +0000 Subject: T. Bharath pointed out the flaw in ConnectionExists() for how we didn't check proxy connections for "deadness" before they were re-used --- lib/url.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9cd8fdb0e..b7233c074 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1062,6 +1062,7 @@ ConnectionExists(struct SessionHandle *data, struct connectdata *check; for(i=0; i< data->state.numconnects; i++) { + bool match = FALSE; /* * Note that if we use a HTTP proxy, we check connections to that * proxy and not to the actual remote server. @@ -1082,7 +1083,6 @@ ConnectionExists(struct SessionHandle *data, if(strequal(needle->protostr, check->protostr) && strequal(needle->name, check->name) && (needle->remote_port == check->remote_port) ) { - bool dead; if(strequal(needle->protostr, "FTP")) { /* This is FTP, verify that we're using the same name and password as well */ @@ -1092,27 +1092,7 @@ ConnectionExists(struct SessionHandle *data, continue; } } - dead = SocketIsDead(check->firstsocket); - if(dead) { - /* - * Even though the connection seems to have passed away, we could - * still make an effort to get the name information, as we intend to - * connect to the same host again. - * - * This is now subject to discussion. What do you think? - */ - infof(data, "Connection %d seems to be dead!\n", i); - Curl_disconnect(check); /* disconnect resources */ - data->state.connects[i]=NULL; /* nothing here */ - - /* There's no need to continue search, because we only store - one connection for each unique set of identifiers */ - return FALSE; - } - - *usethis = check; - return TRUE; /* yes, we found one to use! */ - + match = TRUE; } } else { /* The requested needle connection is using a proxy, @@ -1121,9 +1101,26 @@ ConnectionExists(struct SessionHandle *data, strequal(needle->proxyhost, check->proxyhost) && needle->port == check->port) { /* This is the same proxy connection, use it! */ - *usethis = check; - return TRUE; + match = TRUE; + } + } + + if(match) { + bool dead = SocketIsDead(check->firstsocket); + if(dead) { + /* + */ + infof(data, "Connection %d seems to be dead!\n", i); + Curl_disconnect(check); /* disconnect resources */ + data->state.connects[i]=NULL; /* nothing here */ + + /* There's no need to continue searching, because we only store + one connection for each unique set of identifiers */ + return FALSE; } + + *usethis = check; + return TRUE; /* yes, we found one to use! */ } } return FALSE; /* no matching connecting exists */ -- cgit v1.2.1 From e8109b09b117749dc9b7e2ab7d51bd100e254d7e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 10 Apr 2002 13:44:42 +0000 Subject: error code cleanup, use the new SEND/RECV errors --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b7233c074..0859dead1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -950,7 +950,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; default: /* unknown tag and its companion, just ignore: */ - return CURLE_READ_ERROR; /* correct this */ + return CURLE_FAILED_INIT; /* correct this */ } return CURLE_OK; } @@ -2363,7 +2363,7 @@ CURLcode Curl_do(struct connectdata **connp) /* This was formerly done in transfer.c, but we better do it here */ - if((CURLE_WRITE_ERROR == result) && conn->bits.reuse) { + if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { /* This was a re-use of a connection and we got a write error in the * DO-phase. Then we DISCONNECT this connection and have another attempt * to CONNECT and then DO again! The retry cannot possibly find another -- cgit v1.2.1 From 1cd5cdfccba2fada71237a710a6815b89f5f5e51 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 10 Apr 2002 14:07:03 +0000 Subject: default proxy port set, as reported by Sebastien Willemijns --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0859dead1..ed8d67b8b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -262,6 +262,8 @@ CURLcode Curl_open(struct SessionHandle **curl) /* Set the default size of the SSL session ID cache */ data->set.ssl.numsessions = 5; + + data->set.proxyport = 1080; /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ -- cgit v1.2.1 From 3f6133be2735936631c4bfe5aedd28ae9b084f3f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Apr 2002 07:21:11 +0000 Subject: Jean-Philippe Barrette-LaPierre provided his patch that introduces CURLOPT_DEBUGFUNCTION and CURLOPT_DEBUGDATA. --- lib/url.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ed8d67b8b..365250e2d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -804,12 +804,29 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.set_resume_from = va_arg(param, long); break; + case CURLOPT_DEBUGFUNCTION: + /* + * stderr write callback. + */ + data->set.fdebug = va_arg(param, curl_debug_callback); + /* + * if the callback provided is NULL, it'll use the default callback + */ + break; + case CURLOPT_DEBUGDATA: + /* + * Set to a void * that should receive all error writes. This + * defaults to CURLOPT_STDERR for normal operations. + */ + data->set.debugdata = va_arg(param, void *); case CURLOPT_STDERR: /* * Set to a FILE * that should receive all error writes. This * defaults to stderr for normal operations. */ data->set.err = va_arg(param, FILE *); + if(!data->set.err) + data->set.err = stderr; break; case CURLOPT_HEADERFUNCTION: /* @@ -2265,13 +2282,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, { struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, + infof(data, "Connected to %s (%s) port %d\n", conn->hostaddr->h_name, #if defined(HAVE_INET_NTOA_R) - inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)) + inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), #else - inet_ntoa(in) + inet_ntoa(in), #endif - ); + conn->port); } #endif -- cgit v1.2.1 From 5528c1eaa55551d0a668318674f4f485b0102a10 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Apr 2002 08:18:38 +0000 Subject: corrected the verbose output for connects and fixed the connect time stamp better for FTP (any protocol with protocol-specific connect actions) --- lib/url.c | 104 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 45 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 365250e2d..ca0bc2db1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1272,6 +1272,50 @@ static CURLcode ConnectPlease(struct connectdata *conn) return result; } +static void verboseconnect(struct connectdata *conn) +{ +#ifdef HAVE_INET_NTOA_R + char ntoa_buf[64]; +#endif + struct SessionHandle *data = conn->data; + + /* Figure out the ip-number and display the first host name it shows: */ +#ifdef ENABLE_IPV6 + { + char hbuf[NI_MAXHOST]; +#ifdef NI_WITHSCOPEID + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; +#else + const int niflags = NI_NUMERICHOST; +#endif + struct addrinfo *ai = conn->serv_addr; + + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, + niflags)) { + snprintf(hbuf, sizeof(hbuf), "?"); + } + if (ai->ai_canonname) { + infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf, + conn->port); + } else { + infof(data, "Connected to %s port %d\n", hbuf, conn->port); + } + } +#else + { + struct in_addr in; + (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); + infof(data, "Connected to %s (%s) port %d\n", conn->hostaddr->h_name, +#if defined(HAVE_INET_NTOA_R) + inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), +#else + inet_ntoa(in), +#endif + conn->port); + } +#endif +} + static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata **in_connect) { @@ -1283,9 +1327,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata *conn_temp; char endbracket; int urllen; -#ifdef HAVE_INET_NTOA_R - char ntoa_buf[64]; -#endif #ifdef HAVE_ALARM unsigned int prev_alarm; #endif @@ -2229,14 +2270,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } + conn->bytecount = 0; + conn->headerbytecount = 0; + if(-1 == conn->firstsocket) { /* Connect only if not already connected! */ result = ConnectPlease(conn); if(CURLE_OK != result) return result; + Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */ + if(data->set.verbose) + verboseconnect(conn); + if(conn->curl_connect) { - /* is there a connect() procedure? */ + /* is there a protocol-specific connect() procedure? */ /* set start time here for timeout purposes in the * connect procedure, it is later set again for the @@ -2249,48 +2297,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, return result; /* pass back errors */ } } - - Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */ - - conn->now = Curl_tvnow(); /* time this *after* the connect is done */ - conn->bytecount = 0; - conn->headerbytecount = 0; - - /* Figure out the ip-number and display the first host name it shows: */ -#ifdef ENABLE_IPV6 - { - char hbuf[NI_MAXHOST]; -#ifdef NI_WITHSCOPEID - const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; -#else - const int niflags = NI_NUMERICHOST; -#endif - struct addrinfo *ai = conn->serv_addr; - - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, - niflags)) { - snprintf(hbuf, sizeof(hbuf), "?"); - } - if (ai->ai_canonname) { - infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf, - conn->port); - } else { - infof(data, "Connected to %s port %d\n", hbuf, conn->port); - } - } -#else - { - struct in_addr in; - (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s) port %d\n", conn->hostaddr->h_name, -#if defined(HAVE_INET_NTOA_R) - inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), -#else - inet_ntoa(in), -#endif - conn->port); + else { + Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ + if(data->set.verbose) + verboseconnect(conn); } -#endif + + conn->now = Curl_tvnow(); /* time this *after* the connect is done, we + set this here perhaps a second time */ #ifdef __EMX__ /* 20000330 mgs -- cgit v1.2.1 From c06171a8027d3f9974c209e357ba9f2b3647be2e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Apr 2002 10:03:59 +0000 Subject: store TIMER_CONNECT even if the connect failed --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ca0bc2db1..fbe7afc94 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2276,10 +2276,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(-1 == conn->firstsocket) { /* Connect only if not already connected! */ result = ConnectPlease(conn); + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done, good or bad */ + if(CURLE_OK != result) return result; - Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */ if(data->set.verbose) verboseconnect(conn); -- cgit v1.2.1 From 471f1d694f1495941e338410374f64a44c5a4175 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 23 Apr 2002 13:34:28 +0000 Subject: fixes bug report #547484, no_proxy doesn't properly strip off port numbers from the host names before comparing --- lib/url.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fbe7afc94..514cbd0dc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1611,9 +1611,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; while(nope) { - if(strlen(nope) <= strlen(conn->name)) { + int namelen; + char *endptr = strchr(conn->name, ':'); + if(endptr) + namelen=endptr-conn->name; + else + namelen=strlen(conn->name); + + if(strlen(nope) <= namelen) { char *checkn= - conn->name + strlen(conn->name) - strlen(nope); + conn->name + namelen - strlen(nope); if(strnequal(nope, checkn, strlen(nope))) { /* no proxy for this host! */ break; -- cgit v1.2.1 From 3b9ef8dfc882ee64075aaaf46b4015071dd7ed52 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 23 Apr 2002 14:57:37 +0000 Subject: removed warning about signed/unsigned comparison --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 514cbd0dc..bd010e6df 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1611,7 +1611,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; while(nope) { - int namelen; + unsigned int namelen; char *endptr = strchr(conn->name, ':'); if(endptr) namelen=endptr-conn->name; -- cgit v1.2.1 From 8927ddec1687a438354eae6c527da92c6c63b50b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 25 Apr 2002 19:00:57 +0000 Subject: In order to not get problems with DNS cache pruning, we no longer store any name resolved data in any curl handle struct. That way, we won't mind if the cache entries are pruned for the next time we need them. We'll just resolve them again instead. This changes the Curl_resolv() proto. It modifies the SessionHandle struct but perhaps most importantly, it'll make the internals somewhat dependent on the DNS cache not being disabled as that will cripple operations somewhat. Especially for persistant connections. --- lib/url.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bd010e6df..553c67e74 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1241,7 +1241,8 @@ ConnectionStore(struct SessionHandle *data, return i; } -static CURLcode ConnectPlease(struct connectdata *conn) +static CURLcode ConnectPlease(struct connectdata *conn, + Curl_addrinfo *hostaddr) { CURLcode result; Curl_ipconnect *addr; @@ -1250,7 +1251,7 @@ static CURLcode ConnectPlease(struct connectdata *conn) * Connect to server/proxy *************************************************************/ result= Curl_connecthost(conn, - conn->hostaddr, + hostaddr, conn->port, &conn->firstsocket, &addr); @@ -1264,7 +1265,7 @@ static CURLcode ConnectPlease(struct connectdata *conn) memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); memcpy((char *)&(conn->serv_addr.sin_addr), (struct in_addr *)addr, sizeof(struct in_addr)); - conn->serv_addr.sin_family = conn->hostaddr->h_addrtype; + conn->serv_addr.sin_family = hostaddr->h_addrtype; conn->serv_addr.sin_port = htons(conn->port); #endif } @@ -1272,7 +1273,8 @@ static CURLcode ConnectPlease(struct connectdata *conn) return result; } -static void verboseconnect(struct connectdata *conn) +static void verboseconnect(struct connectdata *conn, + Curl_addrinfo *hostaddr) { #ifdef HAVE_INET_NTOA_R char ntoa_buf[64]; @@ -1281,6 +1283,7 @@ static void verboseconnect(struct connectdata *conn) /* Figure out the ip-number and display the first host name it shows: */ #ifdef ENABLE_IPV6 + (void)hostaddr; /* not used in the IPv6 enabled version */ { char hbuf[NI_MAXHOST]; #ifdef NI_WITHSCOPEID @@ -1305,7 +1308,7 @@ static void verboseconnect(struct connectdata *conn) { struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s) port %d\n", conn->hostaddr->h_name, + infof(data, "Connected to %s (%s) port %d\n", hostaddr->h_name, #if defined(HAVE_INET_NTOA_R) inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), #else @@ -1327,6 +1330,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata *conn_temp; char endbracket; int urllen; + Curl_addrinfo *hostaddr; #ifdef HAVE_ALARM unsigned int prev_alarm; #endif @@ -2178,27 +2182,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = conn->remote_port; /* it is the same port */ /* Resolve target host right on */ - if(!conn->hostaddr) { - /* it might already be set if reusing a connection */ - conn->hostaddr = Curl_resolv(data, conn->name, conn->port, - &conn->hostent_buf); - } - if(!conn->hostaddr) { + hostaddr = Curl_resolv(data, conn->name, conn->port); + + if(!hostaddr) { failf(data, "Couldn't resolve host '%s'", conn->name); result = CURLE_COULDNT_RESOLVE_HOST; /* don't return yet, we need to clean up the timeout first */ } } - else if(!conn->hostaddr) { - /* This is a proxy that hasn't been resolved yet. It may be resolved - if we're reusing an existing connection. */ + else { + /* This is a proxy that hasn't been resolved yet. */ /* resolve proxy */ - /* it might already be set if reusing a connection */ - conn->hostaddr = Curl_resolv(data, conn->proxyhost, conn->port, - &conn->hostent_buf); + hostaddr = Curl_resolv(data, conn->proxyhost, conn->port); - if(!conn->hostaddr) { + if(!hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); result = CURLE_COULDNT_RESOLVE_PROXY; /* don't return yet, we need to clean up the timeout first */ @@ -2282,14 +2280,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(-1 == conn->firstsocket) { /* Connect only if not already connected! */ - result = ConnectPlease(conn); + result = ConnectPlease(conn, hostaddr); Curl_pgrsTime(data, TIMER_CONNECT); /* connect done, good or bad */ if(CURLE_OK != result) return result; if(data->set.verbose) - verboseconnect(conn); + verboseconnect(conn, hostaddr); if(conn->curl_connect) { /* is there a protocol-specific connect() procedure? */ @@ -2308,7 +2306,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, else { Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ if(data->set.verbose) - verboseconnect(conn); + verboseconnect(conn, hostaddr); } conn->now = Curl_tvnow(); /* time this *after* the connect is done, we -- cgit v1.2.1 From 00e4f814467d42dabc6eef19289b6dcc8b34900e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 25 Apr 2002 19:18:19 +0000 Subject: prevent persistant connections to do name resolves --- lib/url.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 553c67e74..06fe51ca5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1308,7 +1308,8 @@ static void verboseconnect(struct connectdata *conn, { struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s) port %d\n", hostaddr->h_name, + infof(data, "Connected to %s (%s) port %d\n", + hostaddr?hostaddr->h_name:"[re-used]", #if defined(HAVE_INET_NTOA_R) inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), #else @@ -2176,7 +2177,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, /************************************************************* * Resolve the name of the server or proxy *************************************************************/ - if(!data->change.proxy) { + if(conn->bits.reuse) { + /* re-used connection, no resolving is necessary */ + hostaddr = NULL; + } + else 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 */ -- cgit v1.2.1 From f7ca561b06d34b230040bdaa3baa9c37596e7d84 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 May 2002 18:30:17 +0000 Subject: the code for case CURLOPT_DEBUGDATA code broke the CURLOPT_STDERR one! --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 06fe51ca5..e5721eaf6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -819,6 +819,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * defaults to CURLOPT_STDERR for normal operations. */ data->set.debugdata = va_arg(param, void *); + break; case CURLOPT_STDERR: /* * Set to a FILE * that should receive all error writes. This -- cgit v1.2.1 From 980a47b42b95d7b9ff3378dc7b0f2e1c453fb649 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 7 May 2002 09:58:13 +0000 Subject: support for ingoring session cookies added --- lib/url.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e5721eaf6..4b20c131a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -495,13 +495,33 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ssl.version = va_arg(param, long); break; + case CURLOPT_COOKIESESSION: + /* + * Set this option to TRUE to start a new "cookie session". It will + * prevent the forthcoming read-cookies-from-file actions to accept + * cookies that are marked as being session cookies, as they belong to a + * previous session. + * + * In the original Netscape cookie spec, "session cookies" are cookies + * with no expire date set. RFC2109 describes the same action if no + * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds + * a 'Discard' action that can enforce the discard even for cookies that + * have a Max-Age. + * + * We run mostly with the original cookie spec, as hardly anyone implements + * anything else. + */ + data->set.cookiesession = (bool)va_arg(param, long); + break; + case CURLOPT_COOKIEFILE: /* * Set cookie file to read and parse. Can be used multiple times. */ cookiefile = (char *)va_arg(param, void *); if(cookiefile) - data->cookies = Curl_cookie_init(cookiefile, data->cookies); + data->cookies = Curl_cookie_init(cookiefile, data->cookies, + data->set.cookiesession); break; case CURLOPT_COOKIEJAR: @@ -514,7 +534,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Activate the cookie parser. This may or may not already * have been made. */ - data->cookies = Curl_cookie_init(NULL, data->cookies); + data->cookies = Curl_cookie_init(NULL, data->cookies, + data->set.cookiesession); break; case CURLOPT_WRITEHEADER: /* -- cgit v1.2.1 From 105ec79b2b754f31ea75606f8246533e2d47a74e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 May 2002 22:17:19 +0000 Subject: James Cone's efforts to add another netrc parsing "mode" --- lib/url.c | 293 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 162 insertions(+), 131 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4b20c131a..8ea4b7c4f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -441,7 +441,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Parse the $HOME/.netrc file */ - data->set.use_netrc = va_arg(param, long)?TRUE:FALSE; + data->set.use_netrc = va_arg(param, long); break; case CURLOPT_FOLLOWLOCATION: /* @@ -1351,7 +1351,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, char resumerange[40]=""; struct connectdata *conn; struct connectdata *conn_temp; - char endbracket; int urllen; Curl_addrinfo *hostaddr; #ifdef HAVE_ALARM @@ -1406,7 +1405,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, connections, so we set this to force-close. Protocols that support this need to set this to FALSE in their "curl_do" functions. */ conn->bits.close = TRUE; - + /* inherite initial knowledge from the data struct */ conn->bits.user_passwd = data->set.userpwd?1:0; conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; @@ -1533,35 +1532,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, buf = data->state.buffer; /* this is our buffer */ - /************************************************************* - * Take care of user and password authentication stuff - *************************************************************/ - - if(conn->bits.user_passwd && !data->set.use_netrc) { - data->state.user[0] =0; - data->state.passwd[0]=0; - - if(*data->set.userpwd != ':') { - /* the name is given, get user+password */ - sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", - data->state.user, data->state.passwd); - } - else - /* no name given, get the password only */ - sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); - - /* check for password, if no ask for one */ - if( !data->state.passwd[0] ) { - if(!data->set.fpasswd || - data->set.fpasswd(data->set.passwd_client, - "password:", data->state.passwd, - sizeof(data->state.passwd))) - { - failf(data, "Bad password from password callback"); - return CURLE_BAD_PASSWORD_ENTERED; - } - } - } + /* + * So if the URL was A://B/C, + * conn->protostr is A + * conn->gname is B + * conn->path is /C + */ /************************************************************* * Take care of proxy authentication stuff @@ -1843,7 +1819,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if(type) { char command; - *type=0; + *type=0; /* it was in the middle of the hostname */ command = toupper(type[6]); switch(command) { case 'A': /* ASCII mode */ @@ -1911,86 +1887,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } - /************************************************************* - * .netrc scanning coming up - *************************************************************/ - 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); - } - else - conn->bits.user_passwd = 1; /* enable user+password */ - - /* weather we failed or not, we don't know which fields that were filled - in anyway */ - 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)) ) { - /* This is a FTP or HTTP URL, and we haven't got the user+password in - * the extra parameter, 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=NULL; /* assign to remove possible warnings */ - if((ptr=strchr(conn->name, '@'))) { - /* there's a user+password given here, to the left of the @ */ - - 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->state.user, data->state.passwd); - } - else - /* no name given, get the password only */ - sscanf(conn->name+1, "%127[^@]", data->state.passwd); - - 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 */ - free(newname); - } - - /* check for password, if no ask for one */ - if( !data->state.passwd[0] ) { - if(!data->set.fpasswd || - data->set.fpasswd(data->set.passwd_client, - "password:", data->state.passwd, - sizeof(data->state.passwd))) { - failf(data, "Bad password from password callback"); - return CURLE_BAD_PASSWORD_ENTERED; - } - } - else { - /* we have a password found in the URL, decode it! */ - char *newpasswd=curl_unescape(data->state.passwd, 0); - if(strlen(newpasswd) < sizeof(data->state.passwd)) { - strcpy(data->state.passwd, newpasswd); - } - free(newpasswd); - } - - conn->name = ++ptr; - conn->bits.user_passwd=TRUE; /* enable user+password */ - } - else { - strcpy(data->state.user, CURL_DEFAULT_USER); - strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); - } - } - /************************************************************* * Figure out the remote port number * @@ -1999,29 +1895,32 @@ 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. *************************************************************/ - if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && - (']' == endbracket)) { - /* This is a (IPv6-style) specified IP-address. We support _any_ - IP within brackets to be really generic. */ - conn->name++; /* pass the starting bracket */ + tmp = strrchr(conn->name, ':'); - tmp = strchr(conn->name, ']'); - *tmp = 0; /* zero terminate */ + if (tmp) { + char *rest; + unsigned long port; - tmp++; /* pass the ending bracket */ - if(':' != *tmp) - tmp = NULL; /* no port number available */ - } - else { - /* traditional IPv4-style port-extracting */ - tmp = strchr(conn->name, ':'); - } + port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ - if (tmp) { - *tmp++ = '\0'; /* cut off the name there */ - conn->remote_port = atoi(tmp); + if (rest != (tmp+1) && *rest == '\0') { + /* The colon really did have only digits after it, + * so it is either a port number or a mistake */ + + if (port > 0xffff) { /* Single unix standard says port numbers are + * 16 bits long */ + failf(data, "Port number too large: %lu", port); + return CURLE_URL_MALFORMAT; + } + + *tmp = '\0'; /* cut off the name there */ + conn->remote_port = port; + } } if(data->change.proxy) { @@ -2075,6 +1974,138 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(proxydup); /* free the duplicate pointer and not the modified */ } + /************************************************************* + * Take care of user and password authentication stuff + *************************************************************/ + + /* + * Inputs: data->set.userpwd (CURLOPT_USERPWD) + * data->set.fpasswd (CURLOPT_PASSWDFUNCTION) + * data->set.use_netrc (CURLOPT_NETRC) + * conn->hostname + * netrc file + * hard-coded defaults + * + * Outputs: (almost :- all currently undefined) + * conn->bits.user_passwd - non-zero if non-default passwords exist + * conn->state.user - non-zero length if defined + * conn->state.passwd - ditto + * conn->hostname - remove user name and password + */ + + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->hostname is at most + * [user[:password]]@]hostname + * + * We need somewhere to put the embedded details, so do that first. + */ + + data->state.user[0] =0; /* to make everything well-defined */ + data->state.passwd[0]=0; + + if (conn->protocol & (PROT_FTP|PROT_HTTP)) { + /* 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; + if(ptr != NULL) { + /* there's a user+password given here, to the left of the @ */ + + conn->name = conn->hostname = ++ptr; + + /* So the hostname is sane. Only bother interpreting the + * results if we could care. It could still be wasted + * work because it might be overtaken by the programmatically + * set user/passwd, but doing that first adds more cases here :-( + */ + + if (data->set.use_netrc != CURL_NETRC_REQUIRED) { + /* We could use the one in the URL */ + + conn->bits.user_passwd = 1; /* enable user+password */ + + if(*userpass != ':') { + /* the name is given, get user+password */ + sscanf(userpass, "%127[^:@]:%127[^@]", + data->state.user, data->state.passwd); + } + else + /* no name given, get the password only */ + sscanf(userpass, ":%127[^@]", data->state.passwd); + + 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 */ + free(newname); + } + if (data->state.passwd[0]) { + /* we have a password found in the URL, decode it! */ + char *newpasswd=curl_unescape(data->state.passwd, 0); + if(strlen(newpasswd) < sizeof(data->state.passwd)) { + strcpy(data->state.passwd, newpasswd); + } + free(newpasswd); + } + } + } + } + + /* Programmatically set password: + * - always applies, if available + * - takes precedence over the values we just set above + * so scribble it over the top. + * User-supplied passwords are assumed not to need unescaping. + * + * user_password is set in "inherite initial knowledge' above, + * so it doesn't have to be set in this block + */ + if (data->set.userpwd != NULL) { + if(*data->set.userpwd != ':') { + /* the name is given, get user+password */ + sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", + data->state.user, data->state.passwd); + } + else + /* no name given, get the password only */ + sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); + } + + if (data->set.use_netrc != CURL_NETRC_IGNORED && + data->state.passwd[0] == '\0' ) { /* need passwd */ + 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); + } else + conn->bits.user_passwd = 1; /* enable user+password */ + } + + /* if we have a user but no password, ask for one */ + if(conn->bits.user_passwd && + !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; + } + + /* So we could have a password but no user; that's just too bad. */ + + /* If our protocol needs a password and we have none, use the defaults */ + if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && + !conn->bits.user_passwd) { + strcpy(data->state.user, CURL_DEFAULT_USER); + strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); + /* This is the default password, so DON'T set conn->bits.user_passwd */ + } + /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a -- cgit v1.2.1 From ec585e8907ac8df8c1545f1cd7e2567edf284d08 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 May 2002 22:24:56 +0000 Subject: When re-using a connection, make sure that we use the current host name as we might actually re-use a connection to a different host, when using proxies! This was what bug report #558888 was all about. --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8ea4b7c4f..62e727e93 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2129,6 +2129,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(old_conn->proxyhost); conn = conn_temp; /* use this connection from now on */ + /* 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() */ + /* we need these pointers if we speak over a proxy */ conn->hostname = conn->gname; conn->name = &conn->gname[old_conn->name - old_conn->gname]; -- cgit v1.2.1 From 59c11b82d55b6e8110f2232f0fd47068e4072495 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 28 May 2002 09:21:29 +0000 Subject: Cris Bailiff's CAPATH support added --- lib/url.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 62e727e93..d008ba459 100644 --- a/lib/url.c +++ b/lib/url.c @@ -981,7 +981,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Set CA info for SSL connection. Specify file name of the CA certificate */ data->set.ssl.CAfile = va_arg(param, char *); - data->set.ssl.CApath = NULL; /*This does not work on windows.*/ + break; + case CURLOPT_CAPATH: + /* + * Set CA path info for SSL connection. Specify directory name of the CA certificates + * which have been prepared using openssl c_rehash utility. + */ + data->set.ssl.CApath = va_arg(param, char *); /*This does not work on windows.*/ break; case CURLOPT_TELNETOPTIONS: /* -- cgit v1.2.1 From 08ef208fb78fb2eabc5cec08c23e74e251eac898 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Jun 2002 11:13:01 +0000 Subject: added disable-[protocol] support, largely provided by Miklos Nemeth --- lib/url.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d008ba459..dd55d861d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -139,10 +139,16 @@ static unsigned int ConnectionStore(struct SessionHandle *data, #define RETSIGTYPE void #endif static +RETSIGTYPE sigintfunc(int signal) +{ + (void)signal; /* ignored */ + return; +} RETSIGTYPE alarmfunc(int signal) { /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ (void)signal; + kill(getpid(), SIGINT); return; } #endif @@ -182,11 +188,13 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->state.headerbuff) free(data->state.headerbuff); +#ifndef CURL_DISABLE_HTTP if(data->set.cookiejar) /* we have a "destination" for all the cookies to get dumped to */ Curl_cookie_output(data->cookies, data->set.cookiejar); Curl_cookie_cleanup(data->cookies); +#endif /* free the connection cache */ free(data->state.connects); @@ -514,6 +522,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.cookiesession = (bool)va_arg(param, long); break; +#ifndef CURL_DISABLE_HTTP case CURLOPT_COOKIEFILE: /* * Set cookie file to read and parse. Can be used multiple times. @@ -537,6 +546,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->cookies = Curl_cookie_init(NULL, data->cookies, data->set.cookiesession); break; +#endif + case CURLOPT_WRITEHEADER: /* * Custom pointer to pass the header write callback function @@ -1712,6 +1723,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } +#ifndef CURL_DISABLE_HTTP /************************************************************ * RESUME on a HTTP page is a tricky business. First, let's just check that * 'range' isn't used, then set the range parameter and leave the resume as @@ -1730,12 +1742,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.use_range = 1; /* switch on range usage */ } } - +#endif /************************************************************* * Setup internals depending on protocol *************************************************************/ if (strequal(conn->protostr, "HTTP")) { +#ifndef CURL_DISABLE_HTTP conn->port = (data->set.use_port && data->state.allow_port)? data->set.use_port:PORT_HTTP; conn->remote_port = PORT_HTTP; @@ -1743,9 +1756,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; +#else + failf(data, LIBCURL_NAME + " was built with HTTP disabled, http: not supported!"); + return CURLE_UNSUPPORTED_PROTOCOL; +#endif } else if (strequal(conn->protostr, "HTTPS")) { -#ifdef USE_SSLEAY +#if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP) conn->port = (data->set.use_port && data->state.allow_port)? data->set.use_port:PORT_HTTPS; @@ -1763,6 +1781,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif /* !USE_SSLEAY */ } else if (strequal(conn->protostr, "GOPHER")) { +#ifndef CURL_DISABLE_GOPHER conn->port = (data->set.use_port && data->state.allow_port)? data->set.use_port:PORT_GOPHER; conn->remote_port = PORT_GOPHER; @@ -1775,9 +1794,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_GOPHER; conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; +#else + failf(data, LIBCURL_NAME + " was built with GOPHER disabled, gopher: not supported!"); +#endif } else if(strequal(conn->protostr, "FTP") || strequal(conn->protostr, "FTPS")) { + +/* MN 06/07/02 */ +#ifndef CURL_DISABLE_FTP char *type; if(strequal(conn->protostr, "FTPS")) { @@ -1805,8 +1831,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, failf(data, "ftps does not work through http proxy!"); return CURLE_UNSUPPORTED_PROTOCOL; } +#ifndef CURL_DISABLE_HTTP conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; +#else + failf(data, "FTP over http proxy requires HTTP support built-in!"); + return CURLE_UNSUPPORTED_PROTOCOL; +#endif } else { conn->curl_do = Curl_ftp; @@ -1841,8 +1872,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, break; } } + +/* MN 06/07/02 */ +#else /* CURL_DISABLE_FTP */ + failf(data, LIBCURL_NAME + " was built with FTP disabled, ftp/ftps: not supported!"); + return CURLE_UNSUPPORTED_PROTOCOL; +#endif } else if(strequal(conn->protostr, "TELNET")) { +#ifndef CURL_DISABLE_TELNET /* telnet testing factory */ conn->protocol |= PROT_TELNET; @@ -1851,24 +1890,39 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_TELNET; conn->curl_do = Curl_telnet; conn->curl_done = Curl_telnet_done; +#else + failf(data, LIBCURL_NAME + " was built with TELNET disabled!"); +#endif } else if (strequal(conn->protostr, "DICT")) { +#ifndef CURL_DISABLE_DICT conn->protocol |= PROT_DICT; conn->port = (data->set.use_port && data->state.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 + failf(data, LIBCURL_NAME + " was built with DICT disabled!"); +#endif } else if (strequal(conn->protostr, "LDAP")) { +#ifndef CURL_DISABLE_LDAP conn->protocol |= PROT_LDAP; conn->port = (data->set.use_port && data->state.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 */ +#else + failf(data, LIBCURL_NAME + " was built with LDAP disabled!"); +#endif } else if (strequal(conn->protostr, "FILE")) { +#ifndef CURL_DISABLE_FILE conn->protocol |= PROT_FILE; conn->curl_do = Curl_file; @@ -1885,6 +1939,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, } return result; +#else + failf(data, LIBCURL_NAME + " was built with FILE disabled!"); +#endif } else { /* We fell through all checks and thus we don't support the specified @@ -2203,6 +2261,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_SIGACTION struct sigaction sigact; + sigaction(SIGINT, NULL, &sigact); + keep_sigact = sigact; + sigact.sa_handler = sigintfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; +#endif + /* now set the new struct */ + sigaction(SIGINT, &sigact, NULL); + sigaction(SIGALRM, NULL, &sigact); keep_sigact = sigact; keep_copysig = TRUE; /* yes, we have a copy */ -- cgit v1.2.1 From e9f1c12f0f4791978afdea358d67dbe3a096cd21 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Jun 2002 14:10:32 +0000 Subject: removed accidentally added debug-code! --- lib/url.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dd55d861d..fc4529c8e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -139,16 +139,10 @@ static unsigned int ConnectionStore(struct SessionHandle *data, #define RETSIGTYPE void #endif static -RETSIGTYPE sigintfunc(int signal) -{ - (void)signal; /* ignored */ - return; -} RETSIGTYPE alarmfunc(int signal) { /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ (void)signal; - kill(getpid(), SIGINT); return; } #endif @@ -2261,16 +2255,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_SIGACTION struct sigaction sigact; - sigaction(SIGINT, NULL, &sigact); - keep_sigact = sigact; - sigact.sa_handler = sigintfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - /* now set the new struct */ - sigaction(SIGINT, &sigact, NULL); - sigaction(SIGALRM, NULL, &sigact); keep_sigact = sigact; keep_copysig = TRUE; /* yes, we have a copy */ -- cgit v1.2.1 From 3c49b405de4fbf1fd7127f91908261268640e54f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Jun 2002 15:10:18 +0000 Subject: Now uses sigsetjmp() and siglongjmp() to bail out from slow name lookups in case a timeout is set. This seems to work. God knows if it is good enough or what kind of side-effects we introduce here and now. I'll close my eyes and cross my fingers. Hard. --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fc4529c8e..44c13ccb1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -72,6 +72,10 @@ #include #endif +#ifdef HAVE_SETJMP_H +#include +#endif + #ifndef HAVE_SELECT #error "We can't compile without select() support!" #endif @@ -120,6 +124,7 @@ #ifdef KRB4 #include "security.h" #endif + /* The last #include file should be: */ #ifdef MALLOCDEBUG #include "memdebug.h" @@ -143,6 +148,10 @@ RETSIGTYPE alarmfunc(int signal) { /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ (void)signal; +#ifdef HAVE_SIGSETJMP + extern sigjmp_buf curl_jmpenv; + siglongjmp(curl_jmpenv, 1); +#endif return; } #endif -- cgit v1.2.1 From 85e2e96fb69e34c65bff3230fb27178180fde73d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Jun 2002 15:44:27 +0000 Subject: corrected the signal handler --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 44c13ccb1..0c47b2e0f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -143,13 +143,13 @@ static unsigned int ConnectionStore(struct SessionHandle *data, #ifndef RETSIGTYPE #define RETSIGTYPE void #endif +extern sigjmp_buf curl_jmpenv; static RETSIGTYPE alarmfunc(int signal) { /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ (void)signal; #ifdef HAVE_SIGSETJMP - extern sigjmp_buf curl_jmpenv; siglongjmp(curl_jmpenv, 1); #endif return; -- cgit v1.2.1 From 38c994a7aec3280b42c26c626030ee6441554608 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Jun 2002 15:47:01 +0000 Subject: put #ifdefs around the sigjmp_buf declaration too, as it should be --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0c47b2e0f..dcd0065a4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -143,7 +143,9 @@ static unsigned int ConnectionStore(struct SessionHandle *data, #ifndef RETSIGTYPE #define RETSIGTYPE void #endif +#ifdef HAVE_SIGSETJMP extern sigjmp_buf curl_jmpenv; +#endif static RETSIGTYPE alarmfunc(int signal) { -- cgit v1.2.1 From 2b34d4e1f750c2b7db466e85abe582191f439109 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 14 Jun 2002 12:05:20 +0000 Subject: - Yarram Sunil found out that the SocketIsDead() function performed a lot faster on Windows when removing the 1 microsecond timeout. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dcd0065a4..6d0b55ef4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1101,7 +1101,7 @@ static bool SocketIsDead(int sock) FD_SET(sock,&check_set); to.tv_sec = 0; - to.tv_usec = 1; + to.tv_usec = 0; sval = select(sock + 1, &check_set, 0, 0, &to); if(sval == 0) -- cgit v1.2.1 From e54e0c78778f6844b067c8d6a4e5d57069e088ae Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 15 Jun 2002 21:00:54 +0000 Subject: CURLOPT_BUFFERSIZE allows an application to set a prefered buffer size for receiving data from the network. It is meant as a hint, not as a forced limit. --- lib/url.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6d0b55ef4..17cd79c9a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1011,6 +1011,19 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.telnet_options = va_arg(param, struct curl_slist *); break; + + case CURLOPT_BUFFERSIZE: + /* + * The application kindly asks for a differently sized receive buffer. + * If it seems reasonable, we'll use it. + */ + data->set.buffer_size = va_arg(param, long); + + if(data->set.buffer_size> (BUFSIZE -1 )) + data->set.buffer_size = 0; /* huge internal default */ + + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 264a9bc6ed650375243a5ab38d323fe385ea256e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 Jul 2002 22:45:50 +0000 Subject: Removed checks for if set.fpasswd is NULL, as we prevent users from setting it to NULL and then use the internal default instead. It will always be a function to call. --- lib/url.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 17cd79c9a..bbe28788d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1592,11 +1592,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* check for password, if no ask for one */ if( !data->state.proxypasswd[0] ) { - if(!data->set.fpasswd || - data->set.fpasswd( data->set.passwd_client, - "proxy password:", - data->state.proxypasswd, - sizeof(data->state.proxypasswd))) { + if(data->set.fpasswd( data->set.passwd_client, + "proxy password:", + data->state.proxypasswd, + sizeof(data->state.proxypasswd))) { failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; } @@ -2171,10 +2170,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* if we have a user but no password, ask for one */ if(conn->bits.user_passwd && !data->state.passwd[0] ) { - if(!data->set.fpasswd || - data->set.fpasswd(data->set.passwd_client, - "password:", data->state.passwd, - sizeof(data->state.passwd))) + if(data->set.fpasswd(data->set.passwd_client, + "password:", data->state.passwd, + sizeof(data->state.passwd))) return CURLE_BAD_PASSWORD_ENTERED; } -- cgit v1.2.1 From 215c44558311d7a670cba91a264eb28628f78a5d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Aug 2002 16:50:55 +0000 Subject: re-added the RFC2732-parser that was lost for some reason during the flow of time! --- lib/url.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bbe28788d..f11d5df17 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1391,6 +1391,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_ALARM unsigned int prev_alarm; #endif + char endbracket; #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ @@ -1980,8 +1981,19 @@ static CURLcode CreateConnection(struct SessionHandle *data, * The conn->name is currently [user:passwd@]host[:port] where host could * be a hostname, IPv4 address or IPv6 address. *************************************************************/ - - tmp = strrchr(conn->name, ':'); + if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && + (']' == endbracket)) { + /* this is a RFC2732-style specified IP-address */ + + conn->name++; /* pass the starting bracket */ + tmp = strchr(conn->name, ']'); + *tmp = 0; /* zero terminate */ + tmp++; /* pass the ending bracket */ + if(':' != *tmp) + tmp = NULL; /* no port number available */ + } + else + tmp = strrchr(conn->name, ':'); if (tmp) { char *rest; -- cgit v1.2.1 From 4cf953678d06346de07d3d64fe5bc650cbc01bf6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 8 Aug 2002 22:52:50 +0000 Subject: Markus F.X.J. Oberhumer's CURLOPT_NOSIGNAL patch --- lib/url.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f11d5df17..071ec07f7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1024,6 +1024,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; + case CURLOPT_NOSIGNAL: + /* + * The application asks not to set any signal() or alarm() handlers, + * even when using a timeout. + */ + data->set.no_signal = va_arg(param, long) ? TRUE : FALSE; + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ @@ -2281,7 +2289,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /************************************************************* * Set timeout if that is being used *************************************************************/ - if(data->set.timeout || data->set.connecttimeout) { + if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { /************************************************************* * Set signal handler to catch SIGALRM * Store the old value to be able to set it back later! @@ -2358,7 +2366,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } Curl_pgrsTime(data, TIMER_NAMELOOKUP); #ifdef HAVE_ALARM - if(data->set.timeout || data->set.connecttimeout) { + if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { #ifdef HAVE_SIGACTION if(keep_copysig) { /* we got a struct as it looked before, now put that one back nice -- cgit v1.2.1 From cb895ec3356822df72eb91171a1cc63ad1845d93 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Aug 2002 09:43:20 +0000 Subject: Initial fix to make the multi interface return control while waiting for the initial connect to "come through". This should work fine for connect and for FTP-PASV connects. Needs massive testing. --- lib/url.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 22 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 071ec07f7..ead5eb494 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1307,7 +1307,8 @@ ConnectionStore(struct SessionHandle *data, } static CURLcode ConnectPlease(struct connectdata *conn, - Curl_addrinfo *hostaddr) + Curl_addrinfo *hostaddr, + bool *connected) { CURLcode result; Curl_ipconnect *addr; @@ -1319,7 +1320,8 @@ static CURLcode ConnectPlease(struct connectdata *conn, hostaddr, conn->port, &conn->firstsocket, - &addr); + &addr, + connected); if(CURLE_OK == result) { /* All is cool, then we store the current information from the hostaddr struct to the serv_addr, as it might be needed later. The address @@ -1374,7 +1376,7 @@ static void verboseconnect(struct connectdata *conn, struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); infof(data, "Connected to %s (%s) port %d\n", - hostaddr?hostaddr->h_name:"[re-used]", + hostaddr?hostaddr->h_name:"", #if defined(HAVE_INET_NTOA_R) inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), #else @@ -1385,6 +1387,42 @@ static void verboseconnect(struct connectdata *conn, #endif } +/* + * We have discovered that the TCP connection has been successful, we can now + * proceed with some action. + * + * If we're using the multi interface, this host address pointer is most + * likely NULL at this point as we can't keep the resolved info around. This + * may call for some reworking, like a reference counter in the struct or + * something. The hostaddr is not used for very much though, we have the + * 'serv_addr' field in the connectdata struct for most of it. + */ +CURLcode Curl_protocol_connect(struct connectdata *conn, + Curl_addrinfo *hostaddr) +{ + struct SessionHandle *data = conn->data; + CURLcode result; + + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ + + if(data->set.verbose) + verboseconnect(conn, hostaddr); + + if(conn->curl_connect) { + /* is there a protocol-specific connect() procedure? */ + + /* set start time here for timeout purposes in the + * connect procedure, it is later set again for the + * progress meter purpose */ + conn->now = Curl_tvnow(); + + /* Call the protocol-specific connect function */ + result = conn->curl_connect(conn); + } + + return result; /* pass back status */ +} + static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata **in_connect) { @@ -1780,6 +1818,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; + conn->curl_do_more = NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; #else @@ -1797,6 +1836,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; conn->curl_do = Curl_http; + conn->curl_do_more = NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; @@ -1819,6 +1859,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } conn->protocol |= PROT_GOPHER; conn->curl_do = Curl_http; + conn->curl_do_more = NULL; conn->curl_done = Curl_http_done; #else failf(data, LIBCURL_NAME @@ -1867,6 +1908,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } else { conn->curl_do = Curl_ftp; + conn->curl_do_more = Curl_ftp_nextconnect; conn->curl_done = Curl_ftp_done; conn->curl_connect = Curl_ftp_connect; conn->curl_disconnect = Curl_ftp_disconnect; @@ -2441,29 +2483,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->headerbytecount = 0; if(-1 == conn->firstsocket) { + bool connected; + /* Connect only if not already connected! */ - result = ConnectPlease(conn, hostaddr); - Curl_pgrsTime(data, TIMER_CONNECT); /* connect done, good or bad */ + result = ConnectPlease(conn, hostaddr, &connected); + + if(connected) + result = Curl_protocol_connect(conn, hostaddr); if(CURLE_OK != result) return result; - - if(data->set.verbose) - verboseconnect(conn, hostaddr); - - if(conn->curl_connect) { - /* is there a protocol-specific connect() procedure? */ - - /* set start time here for timeout purposes in the - * connect procedure, it is later set again for the - * progress meter purpose */ - conn->now = Curl_tvnow(); - - /* Call the protocol-specific connect function */ - result = conn->curl_connect(conn); - if(result != CURLE_OK) - return result; /* pass back errors */ - } } else { Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ @@ -2558,6 +2587,8 @@ CURLcode Curl_do(struct connectdata **connp) struct connectdata *conn = *connp; struct SessionHandle *data=conn->data; + conn->do_more = FALSE; /* by default there's no curl_do_more() to use */ + if(conn->curl_do) { /* generic protocol-specific function pointer set in curl_connect() */ result = conn->curl_do(conn); @@ -2587,6 +2618,16 @@ CURLcode Curl_do(struct connectdata **connp) return result; } +CURLcode Curl_do_more(struct connectdata *conn) +{ + CURLcode result=CURLE_OK; + + if(conn->curl_do_more) + result = conn->curl_do_more(conn); + + return result; +} + /* * local variables: * eval: (load-file "../curl-mode.el") -- cgit v1.2.1 From 6dfe0ec31ed5ac5c9868b08bd8340a2101e8b667 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Aug 2002 14:20:47 +0000 Subject: Sterling Hughes brings the share interface --- lib/url.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ead5eb494..08180efa9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -178,6 +178,10 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_SSL_Close_All(data); #endif + /* No longer a dirty share, if it exists */ + if (data->share) + data->share->dirty--; + if(data->state.auth_host) free(data->state.auth_host); @@ -1032,6 +1036,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.no_signal = va_arg(param, long) ? TRUE : FALSE; break; + case CURLOPT_SHARE: + { + curl_share *set; + set = va_arg(param, curl_share *); + if(data->share) + data->share->dirty--; + + data->share = set; + data->share->dirty++; + } + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 982c5460f0eb521ce4f9526535e9d122fe8755bd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Aug 2002 17:20:29 +0000 Subject: Andrew Francis removed the need for/use of MSVC pragmas --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 08180efa9..4fa601f7c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1349,7 +1349,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, memcpy((char *)&(conn->serv_addr.sin_addr), (struct in_addr *)addr, sizeof(struct in_addr)); conn->serv_addr.sin_family = hostaddr->h_addrtype; - conn->serv_addr.sin_port = htons(conn->port); + conn->serv_addr.sin_port = htons((unsigned short)conn->port); #endif } @@ -2078,7 +2078,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } *tmp = '\0'; /* cut off the name there */ - conn->remote_port = port; + conn->remote_port = (unsigned short)port; } } -- cgit v1.2.1 From 27a2e590cd64cd6f31472681f0e61167b729e005 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Aug 2002 23:13:25 +0000 Subject: SSL_INSECURE support and usage added --- lib/url.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4fa601f7c..43a7e400b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1004,10 +1004,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; case CURLOPT_CAPATH: /* - * Set CA path info for SSL connection. Specify directory name of the CA certificates - * which have been prepared using openssl c_rehash utility. + * Set CA path info for SSL connection. Specify directory name of the CA + * certificates which have been prepared using openssl c_rehash utility. */ - data->set.ssl.CApath = va_arg(param, char *); /*This does not work on windows.*/ + /* This does not work on windows. */ + data->set.ssl.CApath = va_arg(param, char *); break; case CURLOPT_TELNETOPTIONS: /* @@ -1048,6 +1049,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } break; + case CURLOPT_SSL_INSECURE: + data->set.ssl.allow_insecure = va_arg(param, long)?TRUE:FALSE; + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ @@ -2035,6 +2040,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } + if(conn->protocol & PROT_SSL) { + /* If SSL is requested, require security level info */ + + if(!data->set.ssl.allow_insecure && + !(data->set.ssl.CAfile || data->set.ssl.CApath)) { + failf(data, "Insecure SSL connect attempted without explicit permission granted"); + return CURLE_SSL_INSECURE; + } + } + + /************************************************************* * Figure out the remote port number * -- cgit v1.2.1 From 8aa3f143035ad982acb6e596a8653ac41a7860cc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 30 Aug 2002 09:20:11 +0000 Subject: SOCKS5 support added (contributed by a still unnamed person). Not properly working for "IPv6 enabled" libcurls yet, but should be pretty easy for someone to adjust. --- lib/url.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 43a7e400b..c9aa3042a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -282,6 +282,8 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.proxyport = 1080; + data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ + /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ data->state.connects = (struct connectdata **) @@ -1053,6 +1055,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ssl.allow_insecure = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_PROXYTYPE: + /* + * Set proxy type. HTTP/SOCKS4/SOCKS5 + */ + data->set.proxytype = va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ @@ -1327,6 +1336,189 @@ ConnectionStore(struct SessionHandle *data, return i; } +/* + * This function logs in to a SOCKS5 proxy and sends the specifies the final + * desitination server. + */ +static int handleSock5Proxy( + const char *proxy_name, + const char *proxy_password, + struct connectdata *conn, + int sock) +{ + unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ + int actualread; + int written; + CURLcode result; + + Curl_nonblock(sock, FALSE); + + socksreq[0] = 5; /* version */ + socksreq[1] = (char)(proxy_name[0] ? 2 : 1); /* number of methods (below) */ + socksreq[2] = 0; /* no authentication */ + socksreq[3] = 2; /* username/password */ + + result = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), + &written); + if ((result != CURLE_OK) || (written != (2 + (int)socksreq[1]))) { + failf(conn->data, "Unable to send initial SOCKS5 request."); + return 1; + } + + result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); + if ((result != CURLE_OK) || (actualread != 2)) { + failf(conn->data, "Unable to receive initial SOCKS5 response."); + return 1; + } + + if (socksreq[0] != 5) { + failf(conn->data, "Received invalid version in initial SOCKS5 response."); + return 1; + } + if (socksreq[1] == 0) { + /* Nothing to do, no authentication needed */ + ; + } + else if (socksreq[1] == 2) { + /* Needs user name and password */ + int userlen, pwlen, len; + + userlen = strlen(proxy_name); + pwlen = strlen(proxy_password); + + /* username/password request looks like + * +----+------+----------+------+----------+ + * |VER | ULEN | UNAME | PLEN | PASSWD | + * +----+------+----------+------+----------+ + * | 1 | 1 | 1 to 255 | 1 | 1 to 255 | + * +----+------+----------+------+----------+ + */ + len = 0; + socksreq[len++] = 1; /* username/pw subnegotiation version */ + socksreq[len++] = (char) userlen; + memcpy(socksreq + len, proxy_name, (int) userlen); + len += userlen; + socksreq[len++] = (char) pwlen; + memcpy(socksreq + len, proxy_password, (int) pwlen); + len += pwlen; + + result = Curl_write(conn, sock, (char *)socksreq, len, &written); + if ((result != CURLE_OK) || (len != written)) { + failf(conn->data, "Failed to send SOCKS5 sub-negotiation request."); + return 1; + } + + result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); + if ((result != CURLE_OK) || (actualread != 2)) { + failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response."); + return 1; + } + + if ((socksreq[0] != 5) || /* version */ + (socksreq[1] != 0)) { /* status */ + failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", + socksreq[0], socksreq[1]); + return 1; + } + + /* Everything is good so far, user was authenticated! */ + } + else { + /* error */ + if (socksreq[1] == 1) { + failf(conn->data, + "SOCKS5 GSSAPI per-message authentication is not supported."); + return 1; + } + else if (socksreq[1] == 255) { + if (proxy_name[0] == 0) { + failf(conn->data, + "No authentication method was acceptable. (It is quite likely" + " that the SOCKS5 server wanted a username/password, since none" + " was supplied to the server on this connection.)"); + } + else { + failf(conn->data, "No authentication method was acceptable."); + } + return 1; + } + else { + failf(conn->data, + "Undocumented SOCKS5 mode attempted to be used by server."); + return 1; + } + } + + /* Authentication is complete, now specify destination to the proxy */ + socksreq[0] = 5; /* version (SOCKS5) */ + socksreq[1] = 1; /* connect */ + socksreq[2] = 0; /* must be zero */ + socksreq[3] = 1; /* IPv4 = 1 */ + + { + Curl_addrinfo *hp; + hp = Curl_resolv(conn->data, conn->hostname, conn->remote_port); + /* + * We cannot use 'hostent' as a struct that Curl_resolv() returns. It + * returns a Curl_addrinfo pointer that may not always look the same. + */ +#ifndef ENABLE_IPV6 + if (hp && hp->h_addr_list[0]) { + socksreq[4] = ((char*)hp->h_addr_list[0])[0]; + socksreq[5] = ((char*)hp->h_addr_list[0])[1]; + socksreq[6] = ((char*)hp->h_addr_list[0])[2]; + socksreq[7] = ((char*)hp->h_addr_list[0])[3]; + } + else { + failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", + conn->hostname); + return 1; + } +#else + failf(conn->data, + "%s:%d has an internal error an needs to be fixed to work", + __FILE__, __LINE__); + return 1; +#endif + } + + *((unsigned short*)&socksreq[8]) = htons(conn->remote_port); + + { + const int packetsize = 10; + + result = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); + if ((result != CURLE_OK) || (written != packetsize)) { + failf(conn->data, "Failed to send SOCKS5 connect request."); + return 1; + } + + result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); + if ((result != CURLE_OK) || (actualread != packetsize)) { + failf(conn->data, "Failed to receive SOCKS5 connect request ack."); + return 1; + } + + if (socksreq[0] != 5) { /* version */ + failf(conn->data, + "SOCKS5 reply has wrong version, version should be 5."); + return 1; + } + if (socksreq[1] != 0) { /* Anything besides 0 is an error */ + failf(conn->data, + "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), + socksreq[1]); + return 1; + } + } + + Curl_nonblock(sock, TRUE); + return 0; /* Proxy was successful! */ +} + static CURLcode ConnectPlease(struct connectdata *conn, Curl_addrinfo *hostaddr, bool *connected) @@ -1356,6 +1548,21 @@ static CURLcode ConnectPlease(struct connectdata *conn, conn->serv_addr.sin_family = hostaddr->h_addrtype; conn->serv_addr.sin_port = htons((unsigned short)conn->port); #endif + + if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { + return handleSock5Proxy(conn->data->state.proxyuser, + conn->data->state.proxypasswd, + conn, + conn->firstsocket) ? + CURLE_COULDNT_CONNECT : CURLE_OK; + } + else if (conn->data->set.proxytype == CURLPROXY_HTTP) { + /* do nothing here. handled later. */ + } + else { + failf(conn->data, "unknown proxytype option given"); + return CURLE_COULDNT_CONNECT; + } } return result; -- cgit v1.2.1 From 0e0caf7c063c282fb35b8ab87fde1d38fe32d489 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 30 Aug 2002 11:09:49 +0000 Subject: CURLE_SSL_INSECURE is removed again and so is CURLOPT_SSL_INSECURE, we proceed fine with the already existing options, just having a different internal library default for capath. --- lib/url.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c9aa3042a..f8d647491 100644 --- a/lib/url.c +++ b/lib/url.c @@ -111,6 +111,7 @@ #include "ldap.h" #include "url.h" #include "connect.h" +#include "ca-bundle.h" #include @@ -293,12 +294,23 @@ CURLcode Curl_open(struct SessionHandle **curl) free(data); return CURLE_OUT_OF_MEMORY; } - + + /* + * libcurl 7.10 introduces SSL verification *by default*! This needs to be + * switched off unless wanted. + */ + data->set.ssl.verifypeer = TRUE; + data->set.ssl.verifyhost = 2; +#ifdef CURL_CA_BUNDLE + /* This is our prefered CA cert bundle since install time */ + data->set.ssl.CAfile = CURL_CA_BUNDLE; +#endif + + memset(data->state.connects, 0, sizeof(struct connectdata *)*data->state.numconnects); *curl = data; - return CURLE_OK; } @@ -1051,10 +1063,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } break; - case CURLOPT_SSL_INSECURE: - data->set.ssl.allow_insecure = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_PROXYTYPE: /* * Set proxy type. HTTP/SOCKS4/SOCKS5 @@ -2247,17 +2255,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } - if(conn->protocol & PROT_SSL) { - /* If SSL is requested, require security level info */ - - if(!data->set.ssl.allow_insecure && - !(data->set.ssl.CAfile || data->set.ssl.CApath)) { - failf(data, "Insecure SSL connect attempted without explicit permission granted"); - return CURLE_SSL_INSECURE; - } - } - - /************************************************************* * Figure out the remote port number * -- cgit v1.2.1 From 64bbe9dfafc6693a96b742f3133c636385835a19 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Sep 2002 22:31:18 +0000 Subject: James Gallagher's Content-Encoding work --- lib/url.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f8d647491..26c5cb85f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -303,7 +303,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.verifyhost = 2; #ifdef CURL_CA_BUNDLE /* This is our prefered CA cert bundle since install time */ - data->set.ssl.CAfile = CURL_CA_BUNDLE; + data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; #endif @@ -781,6 +781,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.useragent = va_arg(param, char *); break; + case CURLOPT_ENCODING: + /* + * String to use at the value of Accept-Encoding header. 08/28/02 jhrg + */ + data->set.encoding = va_arg(param, char *); + break; + case CURLOPT_USERPWD: /* * user:password to use in the operation @@ -1127,6 +1134,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) free(conn->allocptr.uagent); if(conn->allocptr.userpwd) free(conn->allocptr.userpwd); + if(conn->allocptr.accept_encoding) + free(conn->allocptr.accept_encoding); if(conn->allocptr.rangeline) free(conn->allocptr.rangeline); if(conn->allocptr.ref) @@ -2715,6 +2724,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } + if(data->set.encoding) { + if(conn->allocptr.accept_encoding) + free(conn->allocptr.accept_encoding); + conn->allocptr.accept_encoding = + aprintf("Accept-Encoding: %s\015\012", data->set.encoding); + } conn->bytecount = 0; conn->headerbytecount = 0; -- cgit v1.2.1 From ba4e69bebc8f7f32f3bc7faa1e13e7580754075b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Sep 2002 11:52:59 +0000 Subject: updated source code boilerplate/header --- lib/url.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 26c5cb85f..264dd7df2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | @@ -7,19 +7,19 @@ * * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. * - * In order to be useful for every potential user, curl and libcurl are - * dual-licensed under the MPL and the MIT/X-derivate licenses. - * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the MPL or the MIT/X-derivate - * licenses. You may pick one of these licenses. + * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * $Id$ - *****************************************************************************/ + ***************************************************************************/ /* -- WIN32 approved -- */ -- cgit v1.2.1 From efca2943a05dac5a2fe3a919fe63c32ced9492d2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Sep 2002 11:23:34 +0000 Subject: minor indent change --- lib/url.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 264dd7df2..ee4c7729d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2724,12 +2724,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } - if(data->set.encoding) { - if(conn->allocptr.accept_encoding) - free(conn->allocptr.accept_encoding); - conn->allocptr.accept_encoding = - aprintf("Accept-Encoding: %s\015\012", data->set.encoding); - } + if(data->set.encoding) { + if(conn->allocptr.accept_encoding) + free(conn->allocptr.accept_encoding); + conn->allocptr.accept_encoding = + aprintf("Accept-Encoding: %s\015\012", data->set.encoding); + } + conn->bytecount = 0; conn->headerbytecount = 0; -- cgit v1.2.1 From cac5251a98165bf5b6069f5276fd9d1d7331a11a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Sep 2002 10:32:37 +0000 Subject: Lukasz Czekierda correctly pointed out that curl used a bad Host: header when talking to a IPv6-server using IPv6 IP address only. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ee4c7729d..394d3d0c9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2279,8 +2279,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, if((1 == sscanf(conn->name, "[%*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, ']'); *tmp = 0; /* zero terminate */ tmp++; /* pass the ending bracket */ -- cgit v1.2.1 From c0460660d5a0c8f2be98adf79d2f27b5fa8f707a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 25 Sep 2002 07:08:41 +0000 Subject: Wez Furlong's curl_version_info() function added, still needs some adjustments and possibly some improvments to feature all those things we could possibly want from this. --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 394d3d0c9..abca0b986 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1832,6 +1832,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, * is based on the first letters of the server name. */ + /* Note: if you add a new protocol, please update the list in + * lib/version.c too! */ + if(strnequal(conn->gname, "FTP", 3)) { strcpy(conn->protostr, "ftp"); } -- cgit v1.2.1 From ec9acbcda7cf29658e717522bb98cff65eddbccb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 25 Sep 2002 11:27:06 +0000 Subject: =?UTF-8?q?Andr=E9s=20Garc=EDa=20found=20out=20that=20Curl=5Fproto?= =?UTF-8?q?col=5Fconnect()=20could=20return=20an=20uninitialized=20variabl?= =?UTF-8?q?e.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index abca0b986..bbf9e4bbc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1646,7 +1646,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, Curl_addrinfo *hostaddr) { struct SessionHandle *data = conn->data; - CURLcode result; + CURLcode result=CURLE_OK; Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ -- cgit v1.2.1 From 0ff89b9c3c02a911e1e5ea9a4182c373a6e0f1c7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 27 Sep 2002 09:49:40 +0000 Subject: Allow a "" proxy explicitly set dont-use-proxy, i.e don't even check the environment variables or anything. Setting it to NULL disables proxy as well, but allows the environment variables to kick in and be used. --- lib/url.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bbf9e4bbc..744a0c4fb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -731,7 +731,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; case CURLOPT_PROXY: /* - * Set proxy server:port to use as HTTP proxy + * Set proxy server:port to use as HTTP proxy. + * + * If the proxy is set to "" we explicitly say that we don't want to use a + * proxy (even though there might be environment variables saying so). + * + * Setting it to NULL, means no proxy but allows the environment variables + * to decide for us. */ if(data->change.proxy_alloc) { /* @@ -2137,6 +2143,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_FTP; if(data->change.proxy && + *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 */ @@ -2316,7 +2323,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } - if(data->change.proxy) { + if(data->change.proxy && *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. */ @@ -2630,7 +2637,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* re-used connection, no resolving is necessary */ hostaddr = NULL; } - else if(!data->change.proxy) { + else if(!data->change.proxy || !*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 */ @@ -2720,7 +2727,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Send user-agent to HTTP proxies even if the target protocol * isn't HTTP. *************************************************************/ - if((conn->protocol&PROT_HTTP) || data->change.proxy) { + if((conn->protocol&PROT_HTTP) || + (data->change.proxy && *data->change.proxy)) { if(data->set.useragent) { if(conn->allocptr.uagent) free(conn->allocptr.uagent); -- cgit v1.2.1 From 701509d32237da51bd5b4e6c5bcbd145541259a1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 10 Oct 2002 08:00:49 +0000 Subject: Jeff Lawson fixed a few problems with connection re-use that remained when you set CURLOPT_PROXY to "". --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 744a0c4fb..c55ebdb19 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1729,9 +1729,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->firstsocket = -1; /* no file descriptor */ conn->secondarysocket = -1; /* no file descriptor */ conn->connectindex = -1; /* no index */ - conn->bits.httpproxy = data->change.proxy?TRUE:FALSE; /* proxy-or-not */ + conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && + (data->set.proxytype == CURLPROXY_HTTP))? + TRUE:FALSE; /* http 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->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 -- cgit v1.2.1 From 156aad198f4708f041fbe35ecfb18b875176317d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 17 Oct 2002 07:10:39 +0000 Subject: Make the COOKIESESSION work better by creating a list of cookie files files when given in the curl_easy_setopt() and then parse them all on the first curl_easy_perform() call instead. --- lib/url.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c55ebdb19..eb4003b22 100644 --- a/lib/url.c +++ b/lib/url.c @@ -183,6 +183,9 @@ CURLcode Curl_close(struct SessionHandle *data) if (data->share) data->share->dirty--; + if(data->change.cookielist) /* clean up list if any */ + curl_slist_free_all(data->change.cookielist); + if(data->state.auth_host) free(data->state.auth_host); @@ -552,8 +555,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ cookiefile = (char *)va_arg(param, void *); if(cookiefile) - data->cookies = Curl_cookie_init(cookiefile, data->cookies, - data->set.cookiesession); + /* append the cookie file name to the list of file names, and deal with + them later */ + data->change.cookielist = + curl_slist_append(data->change.cookielist, cookiefile); break; case CURLOPT_COOKIEJAR: -- cgit v1.2.1 From b8a6913e0965e5f492dfbe2b39b52ab5813bf08d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 28 Oct 2002 19:20:59 +0000 Subject: prevent compiler warnings --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index eb4003b22..edd2b3a39 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1691,13 +1691,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, int urllen; Curl_addrinfo *hostaddr; #ifdef HAVE_ALARM - unsigned int prev_alarm; + unsigned int prev_alarm=0; #endif char endbracket; #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ - bool keep_copysig; /* did copy it? */ + bool keep_copysig=FALSE; /* did copy it? */ #else #ifdef HAVE_SIGNAL void *keep_sigact; /* store the old handler here */ -- cgit v1.2.1 From 01387f42c582fdbebc12cee39ed91346bd42ec04 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 28 Oct 2002 21:52:00 +0000 Subject: kromJx@crosswinds.net's fix that now uses checkprefix() instead of strnequal() when the third argument was strlen(first argument) anyway. This makes it less prone to errors. (Slightly edited by me) --- lib/url.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index edd2b3a39..d64e9cb2c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1848,22 +1848,22 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Note: if you add a new protocol, please update the list in * lib/version.c too! */ - if(strnequal(conn->gname, "FTP", 3)) { + if(checkprefix("FTP", conn->gname)) { strcpy(conn->protostr, "ftp"); } - else if(strnequal(conn->gname, "GOPHER", 6)) + else if(checkprefix("GOPHER", conn->gname)) strcpy(conn->protostr, "gopher"); #ifdef USE_SSLEAY - else if(strnequal(conn->gname, "HTTPS", 5)) + else if(checkprefix("HTTPS", conn->gname)) strcpy(conn->protostr, "https"); - else if(strnequal(conn->gname, "FTPS", 4)) + else if(checkprefix("FTPS", conn->gname)) strcpy(conn->protostr, "ftps"); #endif /* USE_SSLEAY */ - else if(strnequal(conn->gname, "TELNET", 6)) + else if(checkprefix("TELNET", conn->gname)) strcpy(conn->protostr, "telnet"); - else if (strnequal(conn->gname, "DICT", sizeof("DICT")-1)) + else if (checkprefix("DICT", conn->gname)) strcpy(conn->protostr, "DICT"); - else if (strnequal(conn->gname, "LDAP", sizeof("LDAP")-1)) + else if (checkprefix("LDAP", conn->gname)) strcpy(conn->protostr, "LDAP"); else { strcpy(conn->protostr, "http"); @@ -1966,7 +1966,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(strlen(nope) <= namelen) { char *checkn= conn->name + namelen - strlen(nope); - if(strnequal(nope, checkn, strlen(nope))) { + if(checkprefix(nope, checkn)) { /* no proxy for this host! */ break; } -- cgit v1.2.1 From 2cff2518631fc538c127c1e94c47c743e2a64661 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Nov 2002 10:51:41 +0000 Subject: Curl_resolv() now returns a different struct, and it contains a reference counter so that the caller needs to decrease that counter when done with the returned data. If compiled with MALLOCDEBUG I've added some extra checking that the counter is decreased before a handle is closed etc. --- lib/url.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d64e9cb2c..45a79b16f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1484,18 +1484,23 @@ static int handleSock5Proxy( socksreq[3] = 1; /* IPv4 = 1 */ { - Curl_addrinfo *hp; - hp = Curl_resolv(conn->data, conn->hostname, conn->remote_port); +#ifndef ENABLE_IPV6 + struct Curl_dns_entry *dns; + Curl_addrinfo *hp=NULL; + dns = Curl_resolv(conn->data, conn->hostname, conn->remote_port); /* * We cannot use 'hostent' as a struct that Curl_resolv() returns. It * returns a Curl_addrinfo pointer that may not always look the same. */ -#ifndef ENABLE_IPV6 + if(dns) + hp=dns->addr; if (hp && hp->h_addr_list[0]) { socksreq[4] = ((char*)hp->h_addr_list[0])[0]; socksreq[5] = ((char*)hp->h_addr_list[0])[1]; socksreq[6] = ((char*)hp->h_addr_list[0])[2]; socksreq[7] = ((char*)hp->h_addr_list[0])[3]; + + dns->inuse--; /* not used anymore from now on */ } else { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", @@ -1548,7 +1553,7 @@ static int handleSock5Proxy( } static CURLcode ConnectPlease(struct connectdata *conn, - Curl_addrinfo *hostaddr, + struct Curl_dns_entry *hostaddr, bool *connected) { CURLcode result; @@ -1567,6 +1572,8 @@ static CURLcode ConnectPlease(struct connectdata *conn, /* All is cool, then we store the current information from the hostaddr struct to the serv_addr, as it might be needed later. The address returned from the function above is crucial here. */ + conn->connect_addr = hostaddr; + #ifdef ENABLE_IPV6 conn->serv_addr = addr; #else @@ -1597,7 +1604,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, } static void verboseconnect(struct connectdata *conn, - Curl_addrinfo *hostaddr) + struct Curl_dns_entry *dns) { #ifdef HAVE_INET_NTOA_R char ntoa_buf[64]; @@ -1606,7 +1613,7 @@ static void verboseconnect(struct connectdata *conn, /* Figure out the ip-number and display the first host name it shows: */ #ifdef ENABLE_IPV6 - (void)hostaddr; /* not used in the IPv6 enabled version */ + (void)dns; /* not used in the IPv6 enabled version */ { char hbuf[NI_MAXHOST]; #ifdef NI_WITHSCOPEID @@ -1629,6 +1636,7 @@ static void verboseconnect(struct connectdata *conn, } #else { + Curl_addrinfo *hostaddr=dns->addr; struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); infof(data, "Connected to %s (%s) port %d\n", @@ -1654,7 +1662,7 @@ static void verboseconnect(struct connectdata *conn, * 'serv_addr' field in the connectdata struct for most of it. */ CURLcode Curl_protocol_connect(struct connectdata *conn, - Curl_addrinfo *hostaddr) + struct Curl_dns_entry *hostaddr) { struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; @@ -1689,7 +1697,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata *conn; struct connectdata *conn_temp; int urllen; - Curl_addrinfo *hostaddr; + struct Curl_dns_entry *hostaddr; #ifdef HAVE_ALARM unsigned int prev_alarm=0; #endif @@ -2811,7 +2819,6 @@ CURLcode Curl_connect(struct SessionHandle *data, return code; } - CURLcode Curl_done(struct connectdata *conn) { struct SessionHandle *data=conn->data; @@ -2829,7 +2836,16 @@ CURLcode Curl_done(struct connectdata *conn) free(conn->newurl); conn->newurl = NULL; } - + + if(conn->connect_addr) + conn->connect_addr->inuse--; /* done with this */ + +#ifdef MALLOCDEBUG + /* scan for DNS cache entries still marked as in use */ + Curl_hash_apply(data->hostcache, + NULL, Curl_scan_cache_used); +#endif + /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) result = conn->curl_done(conn); -- cgit v1.2.1 From 0ff1ca30c3e9e36b553c354d18de5c5f80d1af69 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Nov 2002 11:07:49 +0000 Subject: ipv4-fixes for the new Curl_dns_entry struct and Curl_resolv() proto --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 45a79b16f..817bb6d56 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1580,7 +1580,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); memcpy((char *)&(conn->serv_addr.sin_addr), (struct in_addr *)addr, sizeof(struct in_addr)); - conn->serv_addr.sin_family = hostaddr->h_addrtype; + conn->serv_addr.sin_family = hostaddr->addr->h_addrtype; conn->serv_addr.sin_port = htons((unsigned short)conn->port); #endif -- cgit v1.2.1 From ef749fa9ce93830f9835c9951a223dea4f5782ff Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 7 Nov 2002 08:45:10 +0000 Subject: Bug report #634625 identified how curl returned timeout immediately when CURLOPT_CONNECTTIMEOUT was used and provided a fix. --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 817bb6d56..92c4dd926 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1764,6 +1764,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); + /* Set the start time temporary to this creation time to allow easier + timeout checks before the transfer has started for real. The start time + is later set "for real" using Curl_pgrsStartNow(). */ + conn->data->progress.start = conn->created; /*********************************************************** * We need to allocate memory to store the path in. We get the size of the -- cgit v1.2.1 From 03c22b4576e99abf6385f64f54e3fb85c782cf0f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Nov 2002 08:40:37 +0000 Subject: Now supports "Transfer-Encoding: chunked" for HTTP PUT operations where the size of the uploaded file is unknown. --- lib/url.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 92c4dd926..0274cb0f9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1769,6 +1769,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, is later set "for real" using Curl_pgrsStartNow(). */ conn->data->progress.start = conn->created; + conn->upload_chunky = + ((conn->protocol&PROT_HTTP) && + data->set.upload && + (data->set.infilesize == -1) && + (data->set.httpversion != CURL_HTTP_VERSION_1_0))? + /* HTTP, upload, unknown file size and not HTTP 1.0 */ + TRUE: + /* else, no chunky upload */ + FALSE; + /*********************************************************** * We need to allocate memory to store the path in. We get the size of the * full URL to be sure, and we need to make it at least 256 bytes since -- cgit v1.2.1 From 66eb98bb0a3d171b91c77f8a536011f6b25c1adc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Nov 2002 22:36:00 +0000 Subject: unlock dns cache entries with a function call instead of a variable fiddle --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0274cb0f9..2b2e98d70 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1500,7 +1500,7 @@ static int handleSock5Proxy( socksreq[6] = ((char*)hp->h_addr_list[0])[2]; socksreq[7] = ((char*)hp->h_addr_list[0])[3]; - dns->inuse--; /* not used anymore from now on */ + Curl_resolv_unlock(dns); /* not used anymore from now on */ } else { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", @@ -2852,7 +2852,7 @@ CURLcode Curl_done(struct connectdata *conn) } if(conn->connect_addr) - conn->connect_addr->inuse--; /* done with this */ + Curl_resolv_unlock(conn->connect_addr); /* done with this */ #ifdef MALLOCDEBUG /* scan for DNS cache entries still marked as in use */ -- cgit v1.2.1 From ca6e77083768858aa34207f8c5dce38b3c05336d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Nov 2002 22:51:09 +0000 Subject: The test for DNS cache entries left locked is now only built if AGGRESIVE_TEST is also defined, as an addition to MALLOCDEBUG. It doesn't work for multi interface usage and should only be used with careful consideration. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2b2e98d70..50f83532e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2854,7 +2854,7 @@ CURLcode Curl_done(struct connectdata *conn) if(conn->connect_addr) Curl_resolv_unlock(conn->connect_addr); /* done with this */ -#ifdef MALLOCDEBUG +#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, NULL, Curl_scan_cache_used); -- cgit v1.2.1 From 42acb00c815f2cca5bd1e3653c9f3a47e9256572 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Nov 2002 23:03:03 +0000 Subject: moved the bools in the connectdata struct into the substruct named ConnectBits where the other bools already are --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 50f83532e..7083490be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1769,7 +1769,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, is later set "for real" using Curl_pgrsStartNow(). */ conn->data->progress.start = conn->created; - conn->upload_chunky = + conn->bits.upload_chunky = ((conn->protocol&PROT_HTTP) && data->set.upload && (data->set.infilesize == -1) && @@ -2889,7 +2889,7 @@ CURLcode Curl_do(struct connectdata **connp) struct connectdata *conn = *connp; struct SessionHandle *data=conn->data; - conn->do_more = FALSE; /* by default there's no curl_do_more() to use */ + conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ if(conn->curl_do) { /* generic protocol-specific function pointer set in curl_connect() */ -- cgit v1.2.1 From 8bca5e05b8e96bbfaaef9cc8dcecc33ce7ef6a15 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Nov 2002 19:11:22 +0000 Subject: Kjetil Jacobsen's patch that introduces CURLOPT_PRIVATE and CURLINFO_PRIVATE for storage and retrieval of private data in the curl handle. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7083490be..c07c50861 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1088,6 +1088,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.proxytype = va_arg(param, long); break; + case CURLOPT_PRIVATE: + /* + * Set private data pointer. + */ + data->set.private = va_arg(param, char *); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From ce011b8a2d6fb3fd44baaff404750f6f57059edb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Nov 2002 16:59:40 +0000 Subject: =?UTF-8?q?bug=20fix=20for=20the=20problem=20Juan=20Ignacio=20Herv?= =?UTF-8?q?=E1s=20discovered=20today?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c07c50861..f67ef7bcb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1610,6 +1610,9 @@ static CURLcode ConnectPlease(struct connectdata *conn, return result; } +/* + * ALERT! The 'dns' pointer being passed in here might be NULL at times. + */ static void verboseconnect(struct connectdata *conn, struct Curl_dns_entry *dns) { @@ -1643,7 +1646,7 @@ static void verboseconnect(struct connectdata *conn, } #else { - Curl_addrinfo *hostaddr=dns->addr; + Curl_addrinfo *hostaddr=dns?dns->addr:NULL; struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); infof(data, "Connected to %s (%s) port %d\n", -- cgit v1.2.1 From 4bcc866c52d5d5eaae18bda4b2afad8014b23683 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Dec 2002 15:37:54 +0000 Subject: The fread() callback pointer and associated pointer is now stored in the connectdata struct instead, and is no longer modified within the 'set' struct as previously (which was a really BAAAD thing). --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f67ef7bcb..935507674 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1789,6 +1789,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* else, no chunky upload */ FALSE; + conn->fread = data->set.fread; + conn->fread_in = data->set.in; + /*********************************************************** * We need to allocate memory to store the path in. We get the size of the * full URL to be sure, and we need to make it at least 256 bytes since -- cgit v1.2.1 From b528bde470afc6d5a6e3e72f4823428f9ec78a9a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 13 Dec 2002 16:15:19 +0000 Subject: conn->bits.tcpconnect now keeps track of if this connection is connected or not --- lib/url.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 935507674..a639ebaa1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1677,6 +1677,12 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; + if(conn->bits.tcpconnect) + /* We already are connected, get back. This may happen when the connect + worked fine in the first call, like when we connect to a local server + or proxy. */ + return CURLE_OK; + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ if(data->set.verbose) @@ -2299,6 +2305,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Setup a "faked" transfer that'll do nothing */ if(CURLE_OK == result) { + conn->bits.tcpconnect = TRUE; /* we are "connected */ result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ -1, NULL); /* no upload */ } @@ -2795,14 +2802,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Connect only if not already connected! */ result = ConnectPlease(conn, hostaddr, &connected); - if(connected) + if(connected) { result = Curl_protocol_connect(conn, hostaddr); + if(CURLE_OK == result) + conn->bits.tcpconnect = TRUE; + } + else + conn->bits.tcpconnect = FALSE; + if(CURLE_OK != result) return result; } else { Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ + conn->bits.tcpconnect = TRUE; if(data->set.verbose) verboseconnect(conn, hostaddr); } -- cgit v1.2.1 From ec24efda749df7513aaf994a9ef0d2b3c72eaed7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 7 Jan 2003 16:15:53 +0000 Subject: Simon Liu's HTTP200ALIASES-patch! --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a639ebaa1..7f2aae8a5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1095,6 +1095,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.private = va_arg(param, char *); break; + case CURLOPT_HTTP200ALIASES: + /* + * Set a list of aliases for HTTP 200 in response header + */ + data->set.http200aliases = va_arg(param, struct curl_slist *); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 9a239edb5254fb684ec8095624d763ddeb49d063 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 8 Jan 2003 15:50:52 +0000 Subject: updated to use the modified share-types --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7f2aae8a5..d085f3ce4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -101,6 +101,7 @@ #include "strequal.h" #include "escape.h" #include "strtok.h" +#include "share.h" /* And now for the protocols */ #include "ftp.h" @@ -1071,8 +1072,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) case CURLOPT_SHARE: { - curl_share *set; - set = va_arg(param, curl_share *); + struct Curl_share *set; + set = va_arg(param, struct Curl_share *); if(data->share) data->share->dirty--; -- cgit v1.2.1 From 9a2de6e6eecac91b2cfbeb8617d5bbc2ffbfc50b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 9 Jan 2003 16:47:09 +0000 Subject: if userpwd is "username:", this now implies a blank password while only "username" will cause libcurl to prompt for password. Bryan Kemp noticed. test case 136 is added for this --- lib/url.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d085f3ce4..ad0acd3bb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2526,14 +2526,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* the name is given, get user+password */ sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", data->state.user, data->state.passwd); + if(strchr(data->set.userpwd, ':')) + /* a colon means the password was given, even if blank */ + data->state.passwdgiven = TRUE; } else - /* no name given, get the password only */ + /* no name given, starts with a colon, get the password only */ sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); } if (data->set.use_netrc != CURL_NETRC_IGNORED && - data->state.passwd[0] == '\0' ) { /* need passwd */ + !data->state.passwdgiven) { /* need passwd */ if(Curl_parsenetrc(conn->hostname, data->state.user, data->state.passwd)) { @@ -2544,8 +2547,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } /* if we have a user but no password, ask for one */ - if(conn->bits.user_passwd && - !data->state.passwd[0] ) { + if(conn->bits.user_passwd && !data->state.passwdgiven ) { if(data->set.fpasswd(data->set.passwd_client, "password:", data->state.passwd, sizeof(data->state.passwd))) @@ -2556,9 +2558,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* If our protocol needs a password and we have none, use the defaults */ if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && - !conn->bits.user_passwd) { + !conn->bits.user_passwd && + !data->state.passwdgiven) { + strcpy(data->state.user, CURL_DEFAULT_USER); strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); + /* This is the default password, so DON'T set conn->bits.user_passwd */ } -- cgit v1.2.1 From 3773d76dfdb7875148f0cab82fb205bbfe4b6992 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Jan 2003 16:19:32 +0000 Subject: Steve Oliphant pointed out that test case 105 did not work anymore and this was due to a missing fix for the password prompting --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ad0acd3bb..37140eb84 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2491,6 +2491,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* no name given, get the password only */ sscanf(userpass, ":%127[^@]", data->state.passwd); + /* we have set the password */ + data->state.passwdgiven = TRUE; + if(data->state.user[0]) { char *newname=curl_unescape(data->state.user, 0); if(strlen(newname) < sizeof(data->state.user)) { -- cgit v1.2.1 From 77c388c9280bc53da4be2f4e214afdf77098ca4e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 15 Jan 2003 11:43:03 +0000 Subject: removed a TAB --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 37140eb84..441eee8e1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -67,7 +67,7 @@ #include #endif -#ifdef VMS +#ifdef VMS #include #include #endif -- cgit v1.2.1 From f26a338a54e04d0a6907f5d2479d8b0fa9daf297 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Jan 2003 21:08:12 +0000 Subject: copyright year update in the source header --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 441eee8e1..f1f35cd6b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From b5276a9a69bd29502b5a8d6711f4c2d94f4c445e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 20 Jan 2003 12:00:46 +0000 Subject: given passwords in netrc must be respected accordingly --- lib/url.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f1f35cd6b..c743ed818 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2491,9 +2491,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* no name given, get the password only */ sscanf(userpass, ":%127[^@]", data->state.passwd); - /* we have set the password */ - data->state.passwdgiven = TRUE; - if(data->state.user[0]) { char *newname=curl_unescape(data->state.user, 0); if(strlen(newname) < sizeof(data->state.user)) { @@ -2510,6 +2507,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, strcpy(data->state.passwd, newpasswd); } free(newpasswd); + + /* we have set the password */ + data->state.passwdgiven = TRUE; } } } @@ -2538,15 +2538,18 @@ static CURLcode CreateConnection(struct SessionHandle *data, sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); } - if (data->set.use_netrc != CURL_NETRC_IGNORED && + if ((data->set.use_netrc != CURL_NETRC_IGNORED) && !data->state.passwdgiven) { /* need passwd */ 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); - } else + } + else { conn->bits.user_passwd = 1; /* enable user+password */ + data->state.passwdgiven = TRUE; + } } /* if we have a user but no password, ask for one */ -- cgit v1.2.1 From 5a83976c996a33283c3aca29de86d77a238429b9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 20 Jan 2003 12:52:34 +0000 Subject: Markus F.X.J. Oberhumer's patch that reduces memory usage quite a bit by only allocating the scratch memory buffer once it is needed and not always in the handle. --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c743ed818..de5217d53 100644 --- a/lib/url.c +++ b/lib/url.c @@ -190,6 +190,9 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->state.auth_host) free(data->state.auth_host); + if(data->state.scratch) + free(data->state.scratch); + if(data->change.proxy_alloc) free(data->change.proxy); -- cgit v1.2.1 From a7c72b7abf1213c471f3fd11e6b8e3a37d526f60 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Jan 2003 10:14:20 +0000 Subject: removed the local variables for emacs and vim, use the new sample.emacs way for emacs, and vim users should provide a similar non-polluting style --- lib/url.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index de5217d53..628f3b12a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2978,11 +2978,3 @@ CURLcode Curl_do_more(struct connectdata *conn) return result; } - -/* - * local variables: - * eval: (load-file "../curl-mode.el") - * end: - * vim600: fdm=marker - * vim: et sw=2 ts=2 sts=2 tw=78 - */ -- cgit v1.2.1 From beb13a1d3e832ae97221ba1d9ad7f9bc262de798 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Barette-LaPierre Date: Tue, 4 Feb 2003 23:48:46 +0000 Subject: added the sharing of DNS cache --- lib/url.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 628f3b12a..0836b24ab 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1078,10 +1078,33 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) struct Curl_share *set; set = va_arg(param, struct Curl_share *); if(data->share) + { + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + + /* checking the dns cache stuff */ + if(data->share->hostcache == data->hostcache) + { + data->hostcache = NULL; + } + data->share->dirty--; - + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } + data->share = set; + + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + data->share->dirty++; + + if( data->hostcache ) + { + Curl_hash_destroy(data->hostcache); + data->hostcache = data->share->hostcache; + } + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } break; @@ -1518,7 +1541,7 @@ static int handleSock5Proxy( socksreq[6] = ((char*)hp->h_addr_list[0])[2]; socksreq[7] = ((char*)hp->h_addr_list[0])[3]; - Curl_resolv_unlock(dns); /* not used anymore from now on */ + Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ } else { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", @@ -2901,7 +2924,7 @@ CURLcode Curl_done(struct connectdata *conn) } if(conn->connect_addr) - Curl_resolv_unlock(conn->connect_addr); /* done with this */ + Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */ #if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ -- cgit v1.2.1 From 30639ed72b2d0552435e22f17d1e2cebc86cc4ea Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 Feb 2003 14:50:20 +0000 Subject: Kjetil Jacobsen found out that setting CURLOPT_MAXCONNECTS to a value higher than 5 could cause a segfault. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0836b24ab..865c247d5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -378,12 +378,19 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) Curl_disconnect(data->state.connects[i]); } if(newconnects) { + int i; newptr= (struct connectdata **) 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; + + /* nullify the newly added pointers */ + for(i=data->state.numconnects; istate.connects = newptr; data->state.numconnects = newconnects; } -- cgit v1.2.1 From 29583004ce6d07c90148b03fbfae94f35378b6da Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 28 Feb 2003 15:50:05 +0000 Subject: include the engine stuff --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 865c247d5..192829ce9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -83,8 +83,12 @@ #error "We can't compile without socket() support!" #endif + #endif +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif #include "urldata.h" #include "netrc.h" -- cgit v1.2.1 From 853e240e1d5ca8e1fb9c550b7823ce9d55aef3a9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Mar 2003 18:58:21 +0000 Subject: Use ssize_t instead of 'int' to make the 64 bit sparc compiler happier. Fix by Richard Gorton. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 192829ce9..15391563a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1427,8 +1427,8 @@ static int handleSock5Proxy( int sock) { unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ - int actualread; - int written; + ssize_t actualread; + ssize_t written; CURLcode result; Curl_nonblock(sock, FALSE); -- cgit v1.2.1 From 56dd2da96217da1b2ab7dbef5d77e137ede06d7c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 21 Mar 2003 08:09:48 +0000 Subject: Hopefully this change addresses these two bug reports: 707003 and 706624. We need to make sure that when we init a 'connectdata' struct and then afterwards check for and re-use another one, we must be careful so that the newly set values are transmitted and used in the surviving connectdata struct. --- lib/url.c | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 15391563a..c10a18997 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1806,42 +1806,32 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && (data->set.proxytype == CURLPROXY_HTTP))? TRUE:FALSE; /* http 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 this need to set this to FALSE in their "curl_do" functions. */ conn->bits.close = TRUE; - /* inherite initial knowledge from the data struct */ - 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! */ /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); + 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 */ + /* Set the start time temporary to this creation time to allow easier timeout checks before the transfer has started for real. The start time is later set "for real" using Curl_pgrsStartNow(). */ conn->data->progress.start = conn->created; - conn->bits.upload_chunky = - ((conn->protocol&PROT_HTTP) && - data->set.upload && - (data->set.infilesize == -1) && - (data->set.httpversion != CURL_HTTP_VERSION_1_0))? - /* HTTP, upload, unknown file size and not HTTP 1.0 */ - TRUE: - /* else, no chunky upload */ - FALSE; + conn->bits.user_passwd = data->set.userpwd?1:0; + conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; - conn->fread = data->set.fread; - conn->fread_in = data->set.in; + /* This initing continues below, see the comment "Continue connectdata + * initialization here" */ /*********************************************************** * We need to allocate memory to store the path in. We get the size of the @@ -2631,8 +2621,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, char *ppath = old_conn->ppath; /* this is the modified path pointer */ if(old_conn->proxyhost) free(old_conn->proxyhost); + conn = conn_temp; /* use this connection from now on */ + /* get the user+password information from the old_conn struct since it may + * be new for this request even when we re-use an existing connection */ + conn->bits.user_passwd = old_conn->bits.user_passwd; + conn->bits.proxy_user_passwd = conn->bits.proxy_user_passwd; + /* 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() */ @@ -2690,6 +2686,23 @@ static CURLcode CreateConnection(struct SessionHandle *data, ConnectionStore(data, conn); } + /* Continue connectdata initialization here. + * + * Inherit the proper values from the urldata struct AFTER we have arranged + * the persistant conncetion stuff */ + conn->fread = data->set.fread; + conn->fread_in = data->set.in; + + conn->bits.upload_chunky = + ((conn->protocol&PROT_HTTP) && + data->set.upload && + (data->set.infilesize == -1) && + (data->set.httpversion != CURL_HTTP_VERSION_1_0))? + /* HTTP, upload, unknown file size and not HTTP 1.0 */ + TRUE: + /* else, no chunky upload */ + FALSE; + /************************************************************* * Set timeout if that is being used *************************************************************/ -- cgit v1.2.1 From 89721ff04af70f527baae1368f3b992777bf6526 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 Mar 2003 23:10:38 +0000 Subject: Richard Bramante's provided a fix for a handle re-use problem seen when you change options on an SSL-enabled connection between requests. --- lib/url.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c10a18997..563f8a548 100644 --- a/lib/url.c +++ b/lib/url.c @@ -143,7 +143,12 @@ static bool ConnectionExists(struct SessionHandle *data, struct connectdata **usethis); static unsigned int ConnectionStore(struct SessionHandle *data, struct connectdata *conn); - +static bool ssl_config_matches(struct ssl_config_data* data, + struct ssl_config_data* needle); +static bool init_ssl_config(struct SessionHandle* data, + struct connectdata* conn); +static bool safe_strequal(char* str1, char* str2); +static void free_ssl_config(struct ssl_config_data* sslc); #if !defined(WIN32)||defined(__CYGWIN32__) #ifndef RETSIGTYPE @@ -1211,6 +1216,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(conn->proxyhost) free(conn->proxyhost); + free_ssl_config(&conn->ssl_config); + free(conn); /* free all the connection oriented data */ return CURLE_OK; @@ -1277,7 +1284,14 @@ ConnectionExists(struct SessionHandle *data, if(strequal(needle->protostr, check->protostr) && strequal(needle->name, check->name) && (needle->remote_port == check->remote_port) ) { - if(strequal(needle->protostr, "FTP")) { + if(needle->protocol & PROT_SSL) { + /* This is SSL, verify that we're using the same + ssl options as well */ + if(!ssl_config_matches(&needle->ssl_config, &check->ssl_config)) { + continue; + } + } + if(needle->protocol & PROT_FTP) { /* This is FTP, verify that we're using the same name and password as well */ if(!strequal(needle->data->state.user, check->proto.ftp->user) || @@ -2686,6 +2700,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, ConnectionStore(data, conn); } + if(!init_ssl_config(data, conn)) + return CURLE_OUT_OF_MEMORY; + /* Continue connectdata initialization here. * * Inherit the proper values from the urldata struct AFTER we have arranged @@ -3025,3 +3042,87 @@ CURLcode Curl_do_more(struct connectdata *conn) return result; } + +static bool safe_strequal(char* str1, char* str2) +{ + if(str1 && str2) + /* both pointers point to something then compare them */ + return strequal(str1, str2); + else + /* if both pointers are NULL then treat them as equal */ + return (!str1 && !str2); +} + +static bool +ssl_config_matches(struct ssl_config_data* data, + struct ssl_config_data* needle) +{ + bool result = FALSE; + + if((data->version == needle->version) && + (data->verifypeer == needle->verifypeer) && + (data->verifyhost == needle->verifyhost) && + safe_strequal(data->CApath, needle->CApath) && + safe_strequal(data->CAfile, needle->CAfile) && + safe_strequal(data->random_file, needle->random_file) && + safe_strequal(data->egdsocket, needle->egdsocket) && + safe_strequal(data->cipher_list, needle->cipher_list)) + { + result = TRUE; + } + + return result; +} + +static bool +init_ssl_config(struct SessionHandle* data, struct connectdata* conn) +{ + conn->ssl_config.verifyhost = data->set.ssl.verifyhost; + conn->ssl_config.verifypeer = data->set.ssl.verifypeer; + conn->ssl_config.version = data->set.ssl.version; + + if(data->set.ssl.CAfile) { + conn->ssl_config.CAfile = strdup(data->set.ssl.CAfile); + if(!conn->ssl_config.CAfile) return FALSE; + } + + if(data->set.ssl.CApath) { + conn->ssl_config.CApath = strdup(data->set.ssl.CApath); + if(!conn->ssl_config.CApath) return FALSE; + } + + if(data->set.ssl.cipher_list) { + conn->ssl_config.cipher_list = strdup(data->set.ssl.cipher_list); + if(!conn->ssl_config.cipher_list) return FALSE; + } + + if(data->set.ssl.egdsocket) { + conn->ssl_config.egdsocket = strdup(data->set.ssl.egdsocket); + if(!conn->ssl_config.egdsocket) return FALSE; + } + + if(data->set.ssl.random_file) { + conn->ssl_config.random_file = strdup(data->set.ssl.random_file); + if(!conn->ssl_config.random_file) return FALSE; + } + + return TRUE; +} + +static void free_ssl_config(struct ssl_config_data* sslc) +{ + if(sslc->CAfile) + free(sslc->CAfile); + + if(sslc->CApath) + free(sslc->CApath); + + if(sslc->cipher_list) + free(sslc->cipher_list); + + if(sslc->egdsocket) + free(sslc->egdsocket); + + if(sslc->random_file) + free(sslc->random_file); +} -- cgit v1.2.1 From 803f43592afa476fb91d347e1dbbf67ac9086c5d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Mar 2003 14:23:12 +0000 Subject: white space and indent fix --- lib/url.c | 143 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 72 insertions(+), 71 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 563f8a548..2d8d9491c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1,8 +1,8 @@ /*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. @@ -10,7 +10,7 @@ * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. - * + * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. @@ -218,7 +218,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->set.cookiejar) /* we have a "destination" for all the cookies to get dumped to */ Curl_cookie_output(data->cookies, data->set.cookiejar); - + Curl_cookie_cleanup(data->cookies); #endif @@ -255,7 +255,7 @@ CURLcode Curl_open(struct SessionHandle **curl) if(!data) /* this is a very serious error */ return CURLE_OUT_OF_MEMORY; - + memset(data, 0, sizeof(struct SessionHandle)); /* We do some initial setup here, all those fields that can't be just 0 */ @@ -271,13 +271,13 @@ CURLcode Curl_open(struct SessionHandle **curl) 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->set.fwrite = (curl_write_callback)fwrite; /* use fread as default function to read input */ data->set.fread = (curl_read_callback)fread; - + /* set the default passwd function */ data->set.fpasswd = my_getpass; @@ -289,7 +289,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ - + /* make libcurl quiet by default: */ data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ data->progress.flags |= PGRS_HIDE; @@ -298,14 +298,14 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.numsessions = 5; data->set.proxyport = 1080; - + data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ data->state.connects = (struct connectdata **) malloc(sizeof(struct connectdata *) * data->state.numconnects); - + if(!data->state.connects) { free(data); return CURLE_OUT_OF_MEMORY; @@ -341,7 +341,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) case CURLOPT_DNS_CACHE_TIMEOUT: data->set.dns_cache_timeout = va_arg(param, int); break; - case CURLOPT_DNS_USE_GLOBAL_CACHE: + case CURLOPT_DNS_USE_GLOBAL_CACHE: { int use_cache = va_arg(param, int); if (use_cache) { @@ -827,7 +827,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; case CURLOPT_POSTQUOTE: /* - * List of RAW FTP commands to use after a transfer + * List of RAW FTP commands to use after a transfer */ data->set.postquote = va_arg(param, struct curl_slist *); break; @@ -839,7 +839,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; case CURLOPT_QUOTE: /* - * List of RAW FTP commands to use before a transfer + * List of RAW FTP commands to use before a transfer */ data->set.quote = va_arg(param, struct curl_slist *); break; @@ -1096,22 +1096,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) if(data->share) { Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - + /* checking the dns cache stuff */ if(data->share->hostcache == data->hostcache) { data->hostcache = NULL; } - + data->share->dirty--; - + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } - + data->share = set; Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - + data->share->dirty++; if( data->hostcache ) @@ -1119,7 +1119,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) Curl_hash_destroy(data->hostcache); data->hostcache = data->share->hostcache; } - + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } break; @@ -1144,7 +1144,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.http200aliases = va_arg(param, struct curl_slist *); break; - + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ @@ -1228,24 +1228,24 @@ CURLcode Curl_disconnect(struct connectdata *conn) * be dead. Most commonly this happens when the server has closed the * connection due to inactivity. */ -static bool SocketIsDead(int sock) -{ - int sval; - bool ret_val = TRUE; - fd_set check_set; - struct timeval to; +static bool SocketIsDead(int sock) +{ + int sval; + bool ret_val = TRUE; + fd_set check_set; + struct timeval to; - FD_ZERO(&check_set); - FD_SET(sock,&check_set); + FD_ZERO(&check_set); + FD_SET(sock,&check_set); - to.tv_sec = 0; - to.tv_usec = 0; + to.tv_sec = 0; + to.tv_usec = 0; sval = select(sock + 1, &check_set, 0, 0, &to); if(sval == 0) /* timeout */ ret_val = FALSE; - + return ret_val; } @@ -1354,7 +1354,7 @@ ConnectionKillOne(struct SessionHandle *data) for(i=0; i< data->state.numconnects; i++) { conn = data->state.connects[i]; - + if(!conn) continue; @@ -1531,7 +1531,7 @@ static int handleSock5Proxy( " that the SOCKS5 server wanted a username/password, since none" " was supplied to the server on this connection.)"); } - else { + else { failf(conn->data, "No authentication method was acceptable."); } return 1; @@ -1548,7 +1548,7 @@ static int handleSock5Proxy( socksreq[1] = 1; /* connect */ socksreq[2] = 0; /* must be zero */ socksreq[3] = 1; /* IPv4 = 1 */ - + { #ifndef ENABLE_IPV6 struct Curl_dns_entry *dns; @@ -1662,7 +1662,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, } else { failf(conn->data, "unknown proxytype option given"); - return CURLE_COULDNT_CONNECT; + return CURLE_COULDNT_CONNECT; } } @@ -1735,7 +1735,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, { struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; - + if(conn->bits.tcpconnect) /* We already are connected, get back. This may happen when the connect worked fine in the first call, like when we connect to a local server @@ -1839,7 +1839,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Set the start time temporary to this creation time to allow easier timeout checks before the transfer has started for real. The start time is later set "for real" using Curl_pgrsStartNow(). */ - conn->data->progress.start = conn->created; + conn->data->progress.start = conn->created; conn->bits.user_passwd = data->set.userpwd?1:0; conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; @@ -1856,7 +1856,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, urllen=strlen(data->change.url); if(urllen < LEAST_PATH_ALLOC) urllen=LEAST_PATH_ALLOC; - + conn->path=(char *)malloc(urllen); if(NULL == conn->path) return CURLE_OUT_OF_MEMORY; /* really bad error */ @@ -1883,14 +1883,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, char *ptr=strchr(conn->path, '/'); if(ptr) { /* there was a slash present - + RFC1738 (section 3.1, page 5) says: - + The rest of the locator consists of data specific to the scheme, and is known as the "url-path". It supplies the details of how the specified resource can be accessed. Note that the "/" between the host (or port) and the url-path is NOT part of the url-path. - + As most agents use file://localhost/foo to get '/foo' although the slash preceeding foo is a separator and not a slash for the path, a URL as file://localhost//foo must be valid as well, to refer to @@ -1900,8 +1900,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(ptr[1] && ('/' == ptr[1])) /* if there was two slashes, we skip the first one as that is then used truly as a separator */ - ptr++; - + ptr++; + strcpy(conn->path, ptr); } } @@ -1916,7 +1916,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (2 > sscanf(data->change.url, "%64[^\n:]://%512[^\n/]%[^\n]", conn->protostr, conn->gname, conn->path)) { - + /* * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. @@ -2002,7 +2002,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } /************************************************************* - * Set a few convenience pointers + * Set a few convenience pointers *************************************************************/ conn->name = conn->gname; conn->ppath = conn->path; @@ -2087,7 +2087,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * environment (cgi or php), this environment variable can * be controlled by the web server user by setting the * http header 'Proxy:' to some value. - * + * * This can cause 'internal' http/ftp requests to be * arbitrarily redirected by any external attacker. */ @@ -2389,7 +2389,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* this is a RFC2732-style specified IP-address */ conn->bits.ipv6_ip = TRUE; - conn->name++; /* pass the starting bracket */ + conn->name++; /* pass the starting bracket */ conn->hostname++; tmp = strchr(conn->name, ']'); *tmp = 0; /* zero terminate */ @@ -2500,7 +2500,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, data->state.user[0] =0; /* to make everything well-defined */ data->state.passwd[0]=0; - + if (conn->protocol & (PROT_FTP|PROT_HTTP)) { /* This is a FTP or HTTP URL, we will now try to extract the possible * user+password pair in a string like: @@ -2655,7 +2655,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* 'path' points to the allocated data, 'ppath' may have been advanced to point somewhere within the 'path' area. */ - conn->path = path; + conn->path = path; conn->ppath = ppath; /* re-use init */ @@ -2673,9 +2673,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, 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) + if (conn->bits.rangestringalloc == TRUE) free(conn->range); - + /* tell ourselves to fetch this range */ conn->range = strdup(resumerange); conn->bits.use_range = TRUE; /* enable range download */ @@ -2687,7 +2687,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ conn->bits.use_range = TRUE; /* enable range download */ } - + *in_connect = conn; /* return this instead! */ infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex); @@ -2704,7 +2704,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; /* Continue connectdata initialization here. - * + * * Inherit the proper values from the urldata struct AFTER we have arranged * the persistant conncetion stuff */ conn->fread = data->set.fread; @@ -2881,7 +2881,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bytecount = 0; conn->headerbytecount = 0; - + if(-1 == conn->firstsocket) { bool connected; @@ -2983,7 +2983,7 @@ CURLcode Curl_done(struct connectdata *conn) /* 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 */ @@ -3009,7 +3009,7 @@ CURLcode Curl_do(struct connectdata **connp) result = conn->curl_do(conn); /* This was formerly done in transfer.c, but we better do it here */ - + if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { /* This was a re-use of a connection and we got a write error in the * DO-phase. Then we DISCONNECT this connection and have another attempt @@ -3057,8 +3057,6 @@ static bool ssl_config_matches(struct ssl_config_data* data, struct ssl_config_data* needle) { - bool result = FALSE; - if((data->version == needle->version) && (data->verifypeer == needle->verifypeer) && (data->verifyhost == needle->verifyhost) && @@ -3067,15 +3065,13 @@ ssl_config_matches(struct ssl_config_data* data, safe_strequal(data->random_file, needle->random_file) && safe_strequal(data->egdsocket, needle->egdsocket) && safe_strequal(data->cipher_list, needle->cipher_list)) - { - result = TRUE; - } + return TRUE; - return result; + return FALSE; } static bool -init_ssl_config(struct SessionHandle* data, struct connectdata* conn) +init_ssl_config(struct SessionHandle* data, struct connectdata* conn) { conn->ssl_config.verifyhost = data->set.ssl.verifyhost; conn->ssl_config.verifypeer = data->set.ssl.verifypeer; @@ -3083,33 +3079,38 @@ init_ssl_config(struct SessionHandle* data, struct connectdata* conn) if(data->set.ssl.CAfile) { conn->ssl_config.CAfile = strdup(data->set.ssl.CAfile); - if(!conn->ssl_config.CAfile) return FALSE; + if(!conn->ssl_config.CAfile) + return FALSE; } if(data->set.ssl.CApath) { conn->ssl_config.CApath = strdup(data->set.ssl.CApath); - if(!conn->ssl_config.CApath) return FALSE; + if(!conn->ssl_config.CApath) + return FALSE; } if(data->set.ssl.cipher_list) { conn->ssl_config.cipher_list = strdup(data->set.ssl.cipher_list); - if(!conn->ssl_config.cipher_list) return FALSE; + if(!conn->ssl_config.cipher_list) + return FALSE; } if(data->set.ssl.egdsocket) { conn->ssl_config.egdsocket = strdup(data->set.ssl.egdsocket); - if(!conn->ssl_config.egdsocket) return FALSE; + if(!conn->ssl_config.egdsocket) + return FALSE; } if(data->set.ssl.random_file) { conn->ssl_config.random_file = strdup(data->set.ssl.random_file); - if(!conn->ssl_config.random_file) return FALSE; + if(!conn->ssl_config.random_file) + return FALSE; } return TRUE; } -static void free_ssl_config(struct ssl_config_data* sslc) +static void free_ssl_config(struct ssl_config_data* sslc) { if(sslc->CAfile) free(sslc->CAfile); -- cgit v1.2.1 From 4b3f800c030948525b72422413980d4538126e74 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Mar 2003 03:42:01 +0000 Subject: Frankie Fong filed bug report #708708 which identified a problem with ConnectionExists() when first doing a proxy connecto to a HTTPS site and then switching over to a HTTP connection to the same host. This fix corrects the problem. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2d8d9491c..8a61d05ae 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1272,6 +1272,11 @@ ConnectionExists(struct SessionHandle *data, if(!check) /* NULL pointer means not filled-in entry */ continue; + + if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) + /* don't do mixed SSL and non-SSL connections */ + continue; + if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) { /* The requested connection does not use a HTTP proxy or it uses SSL. */ -- cgit v1.2.1 From 25f611ca4279927d38327b3c8b4a9f81702cd127 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Mar 2003 04:41:05 +0000 Subject: Guillaume Cottenceau's patch that adds CURLOPT_UNRESTRICTED_AUTH that disables the host name check in the FOLLOWLOCATION code. With that option set, libcurl will send user+password to all hosts. --- lib/url.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8a61d05ae..43e92b961 100644 --- a/lib/url.c +++ b/lib/url.c @@ -503,6 +503,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_UNRESTRICTED_AUTH: + /* + * Send authentication (user+password) when following locations, even when + * hostname changed. + */ + data->set.http_disable_hostname_check_before_authentication = + va_arg(param, long)?TRUE:FALSE; + break; case CURLOPT_HTTP_VERSION: /* * This sets a requested HTTP version to be used. The value is one of -- cgit v1.2.1 From 9558f229db056404ebc3b573f44bdc80790c2cfd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Mar 2003 05:13:26 +0000 Subject: Fixup after talks with Richard Bramante. We should now make better comparisons before re-using SSL connections and re-using SSL connection IDs. --- lib/url.c | 61 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 32 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 43e92b961..a401f24cc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -143,12 +143,7 @@ static bool ConnectionExists(struct SessionHandle *data, struct connectdata **usethis); static unsigned int ConnectionStore(struct SessionHandle *data, struct connectdata *conn); -static bool ssl_config_matches(struct ssl_config_data* data, - struct ssl_config_data* needle); -static bool init_ssl_config(struct SessionHandle* data, - struct connectdata* conn); static bool safe_strequal(char* str1, char* str2); -static void free_ssl_config(struct ssl_config_data* sslc); #if !defined(WIN32)||defined(__CYGWIN32__) #ifndef RETSIGTYPE @@ -1224,7 +1219,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(conn->proxyhost) free(conn->proxyhost); - free_ssl_config(&conn->ssl_config); + Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ @@ -1300,7 +1295,8 @@ ConnectionExists(struct SessionHandle *data, if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same ssl options as well */ - if(!ssl_config_matches(&needle->ssl_config, &check->ssl_config)) { + if(!Curl_ssl_config_matches(&needle->ssl_config, + &check->ssl_config)) { continue; } } @@ -2713,7 +2709,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, ConnectionStore(data, conn); } - if(!init_ssl_config(data, conn)) + if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) return CURLE_OUT_OF_MEMORY; /* Continue connectdata initialization here. @@ -3066,9 +3062,9 @@ static bool safe_strequal(char* str1, char* str2) return (!str1 && !str2); } -static bool -ssl_config_matches(struct ssl_config_data* data, - struct ssl_config_data* needle) +bool +Curl_ssl_config_matches(struct ssl_config_data* data, + struct ssl_config_data* needle) { if((data->version == needle->version) && (data->verifypeer == needle->verifypeer) && @@ -3083,47 +3079,48 @@ ssl_config_matches(struct ssl_config_data* data, return FALSE; } -static bool -init_ssl_config(struct SessionHandle* data, struct connectdata* conn) +bool +Curl_clone_ssl_config(struct ssl_config_data *source, + struct ssl_config_data *dest) { - conn->ssl_config.verifyhost = data->set.ssl.verifyhost; - conn->ssl_config.verifypeer = data->set.ssl.verifypeer; - conn->ssl_config.version = data->set.ssl.version; + dest->verifyhost = source->verifyhost; + dest->verifypeer = source->verifypeer; + dest->version = source->version; - if(data->set.ssl.CAfile) { - conn->ssl_config.CAfile = strdup(data->set.ssl.CAfile); - if(!conn->ssl_config.CAfile) + if(source->CAfile) { + dest->CAfile = strdup(source->CAfile); + if(!dest->CAfile) return FALSE; } - if(data->set.ssl.CApath) { - conn->ssl_config.CApath = strdup(data->set.ssl.CApath); - if(!conn->ssl_config.CApath) + if(source->CApath) { + dest->CApath = strdup(source->CApath); + if(!dest->CApath) return FALSE; } - if(data->set.ssl.cipher_list) { - conn->ssl_config.cipher_list = strdup(data->set.ssl.cipher_list); - if(!conn->ssl_config.cipher_list) + if(source->cipher_list) { + dest->cipher_list = strdup(source->cipher_list); + if(!dest->cipher_list) return FALSE; } - if(data->set.ssl.egdsocket) { - conn->ssl_config.egdsocket = strdup(data->set.ssl.egdsocket); - if(!conn->ssl_config.egdsocket) + if(source->egdsocket) { + dest->egdsocket = strdup(source->egdsocket); + if(!dest->egdsocket) return FALSE; } - if(data->set.ssl.random_file) { - conn->ssl_config.random_file = strdup(data->set.ssl.random_file); - if(!conn->ssl_config.random_file) + if(source->random_file) { + dest->random_file = strdup(source->random_file); + if(!dest->random_file) return FALSE; } return TRUE; } -static void free_ssl_config(struct ssl_config_data* sslc) +void Curl_free_ssl_config(struct ssl_config_data* sslc) { if(sslc->CAfile) free(sslc->CAfile); -- cgit v1.2.1 From df00ec3c8200bfc34ab21490f962e84bcc40a736 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Mar 2003 21:43:05 +0000 Subject: move the ssl config clone call to before the connectionexists call and then also subsequently free the ssl struct if the connection struct is to be deleted --- lib/url.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a401f24cc..9d87dd731 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2629,6 +2629,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, * new one. *************************************************************/ + /* get a cloned copy of the SSL config situation stored in the + connection struct */ + if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) + return CURLE_OUT_OF_MEMORY; + /* reuse_fresh is set TRUE if we are told to use a fresh connection by force */ if(!data->set.reuse_fresh && @@ -2645,6 +2650,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(old_conn->proxyhost) free(old_conn->proxyhost); + /* free the SSL config struct from this connection struct as this was + allocated in vain and is targeted for destruction */ + Curl_free_ssl_config(&conn->ssl_config); + conn = conn_temp; /* use this connection from now on */ /* get the user+password information from the old_conn struct since it may @@ -2709,9 +2718,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, ConnectionStore(data, conn); } - if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) - return CURLE_OUT_OF_MEMORY; - /* Continue connectdata initialization here. * * Inherit the proper values from the urldata struct AFTER we have arranged -- cgit v1.2.1 From 89cfa762910a9b98cf1548672de819b46907b466 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 10 Apr 2003 09:44:39 +0000 Subject: Vlad Krupin's URL parsing patch to fix the URL parsing when the URL has no slash after the host name, but still a ? and following "parameters". --- lib/url.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9d87dd731..9f48db7fc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1775,7 +1775,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata **in_connect) { char *tmp; - char *buf; CURLcode result=CURLE_OK; char resumerange[40]=""; struct connectdata *conn; @@ -1921,9 +1920,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Set default host and default path */ strcpy(conn->gname, "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 + * http://example.com?param= (notice the missing '/'). Later we'll insert + * that missing slash at the beginning of the path. + */ if (2 > sscanf(data->change.url, - "%64[^\n:]://%512[^\n/]%[^\n]", + "%64[^\n:]://%512[^\n/?]%[^\n]", conn->protostr, conn->gname, conn->path)) { /* @@ -1972,7 +1975,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } - buf = data->state.buffer; /* this is our buffer */ + /* If the URL is malformatted (missing a '/' after hostname before path) we + * insert a slash here. The only letter except '/' we accept to start a path + * is '?'. + */ + if(conn->path[0] == '?') { + /* We need this function to deal with overlapping memory areas. We know + that the memory area 'path' points to is 'urllen' bytes big and that + is bigger than the path. */ + memmove(&conn->path[1], conn->path, strlen(conn->path)); + conn->path[0] = '/'; + } /* * So if the URL was A://B/C, -- cgit v1.2.1 From e0d8615eceacd52b2c619c503f133277fb371718 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Apr 2003 07:39:16 +0000 Subject: show a verbose warning message in case cookie-saving fails, after Ralph Mitchell's notification. --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9f48db7fc..5cb8fe4df 100644 --- a/lib/url.c +++ b/lib/url.c @@ -210,9 +210,11 @@ CURLcode Curl_close(struct SessionHandle *data) free(data->state.headerbuff); #ifndef CURL_DISABLE_HTTP - if(data->set.cookiejar) + if(data->set.cookiejar) { /* we have a "destination" for all the cookies to get dumped to */ - Curl_cookie_output(data->cookies, data->set.cookiejar); + if(Curl_cookie_output(data->cookies, data->set.cookiejar)) + infof(data, "WARNING: failed to save cookies in given jar\n"); + } Curl_cookie_cleanup(data->cookies); #endif -- cgit v1.2.1 From 5760f2a307c1992cfada5f81284d08558f811591 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Apr 2003 16:08:41 +0000 Subject: support ? as separator instead of / even if not protocol was given --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5cb8fe4df..1daa658be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1935,7 +1935,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * 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]", + if((1 > sscanf(data->change.url, "%512[^\n/?]%[^\n]", conn->gname, conn->path)) ) { /* * We couldn't even get this format. -- cgit v1.2.1 From 22d88fb28e9610f1d20228149004192976524741 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Apr 2003 16:23:06 +0000 Subject: ah, move the zero byte too or havoc will occur --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1daa658be..1cd493cbc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1984,8 +1984,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->path[0] == '?') { /* We need this function to deal with overlapping memory areas. We know that the memory area 'path' points to is 'urllen' bytes big and that - is bigger than the path. */ - memmove(&conn->path[1], conn->path, strlen(conn->path)); + is bigger than the path. Use +1 to move the zero byte too. */ + memmove(&conn->path[1], conn->path, strlen(conn->path)+1); conn->path[0] = '/'; } -- cgit v1.2.1 From bc77bf217f3a7dd21007e9dd1b62b90eb8d25070 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 Apr 2003 19:58:36 +0000 Subject: if there's a cookiehost allocated, free that too --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1cd493cbc..e01711413 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1217,6 +1217,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) free(conn->allocptr.cookie); if(conn->allocptr.host) free(conn->allocptr.host); + if(conn->allocptr.cookiehost) + free(conn->allocptr.cookiehost); if(conn->proxyhost) free(conn->proxyhost); -- cgit v1.2.1 From 94a157d0b0502a6cb64b5f0551ba440ddd45c56e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 9 May 2003 07:39:29 +0000 Subject: support for CURLOPT_FTP_USE_EPRT added --- lib/url.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e01711413..0cb690c0c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -284,6 +284,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ + data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ @@ -634,10 +635,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ftp_use_port = data->set.ftpport?1:0; break; + case CURLOPT_FTP_USE_EPRT: + data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE; + break; + case CURLOPT_FTP_USE_EPSV: data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; break; - + case CURLOPT_HTTPHEADER: /* * Set a list with HTTP headers to use (or replace internals with) -- cgit v1.2.1 From c0197f19cfcec0dd1ade0648d123b9399a6a1959 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 May 2003 12:45:14 +0000 Subject: Dan Fandrich changed CURLOPT_ENCODING to select all supported encodings if set to "". This frees the application from having to know which encodings the library supports. --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0cb690c0c..64d4c2a2d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -106,6 +106,7 @@ #include "escape.h" #include "strtok.h" #include "share.h" +#include "content_encoding.h" /* And now for the protocols */ #include "ftp.h" @@ -825,8 +826,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) case CURLOPT_ENCODING: /* * String to use at the value of Accept-Encoding header. 08/28/02 jhrg + * + * If the encoding is set to "" we use an Accept-Encoding header that + * encompasses all the encodings we support. + * If the encoding is set to NULL we don't send an Accept-Encoding header + * and ignore an received Content-Encoding header. + * */ data->set.encoding = va_arg(param, char *); + if(data->set.encoding && !*data->set.encoding) + data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; break; case CURLOPT_USERPWD: -- cgit v1.2.1 From d5043133e63290e0abedc34ddd1889bbd4bb953e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 21 May 2003 08:08:48 +0000 Subject: Gisle Vanem made curl build with djgpp on DOS. --- lib/url.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 64d4c2a2d..cc6b64748 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2149,6 +2149,33 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(proxy && *proxy) { /* we have a proxy here to set */ + char *ptr; + char user[MAX_CURL_USER_LENGTH]; + char passwd[MAX_CURL_PASSWORD_LENGTH]; + + /* skip the possible protocol piece */ + ptr=strstr(proxy, "://"); + if(ptr) + ptr += 3; + else + ptr = proxy; + + /* check for an @-letter */ + ptr = strchr(ptr, '@'); + if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", + user, passwd))) { + /* found user and password, rip them out */ + strcpy(data->state.proxyuser, user); + strcpy(data->state.proxypasswd, passwd); + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + + ptr = strdup(ptr+1); + free(proxy); /* free the former data */ + proxy = ptr; /* now use this instead */ + } + + data->change.proxy = proxy; data->change.proxy_alloc=TRUE; /* this needs to be freed later */ conn->bits.httpproxy = TRUE; -- cgit v1.2.1 From 9f69deec7d071fbad247574b2fec9263bc020954 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 22 May 2003 22:38:46 +0000 Subject: Added CURLOPT_HTTPDIGEST support SOCKS5 fix as suggested by Jis in bugreport #741841. --- lib/url.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cc6b64748..89f316530 100644 --- a/lib/url.c +++ b/lib/url.c @@ -226,6 +226,8 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->info.contenttype) free(data->info.contenttype); + Curl_digest_cleanup(data); + free(data); return CURLE_OK; } @@ -838,6 +840,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; break; + case CURLOPT_HTTPDIGEST: + /* + * Enable HTTP Digest Authentication + */ + data->set.httpdigest = va_arg(param, long); + break; case CURLOPT_USERPWD: /* * user:password to use in the operation @@ -1535,7 +1543,7 @@ static int handleSock5Proxy( return 1; } - if ((socksreq[0] != 5) || /* version */ + if ((socksreq[0] != 1) || /* version */ (socksreq[1] != 0)) { /* status */ failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); -- cgit v1.2.1 From 6b84ebe50147439f12033881032659e3a2b55ec3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 May 2003 06:44:24 +0000 Subject: include digest.h for proto --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 89f316530..ee13f08a6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -107,6 +107,7 @@ #include "strtok.h" #include "share.h" #include "content_encoding.h" +#include "http_digest.h" /* And now for the protocols */ #include "ftp.h" -- cgit v1.2.1 From e56ae1426cb7a0a4a427cf8d6099a821fdaae428 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Jun 2003 12:22:19 +0000 Subject: Daniel Kouril's patch that adds HTTP negotiation support to libcurl was added. --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ee13f08a6..0ac487e91 100644 --- a/lib/url.c +++ b/lib/url.c @@ -108,6 +108,9 @@ #include "share.h" #include "content_encoding.h" #include "http_digest.h" +#ifdef GSSAPI +#include "http_negotiate.h" +#endif /* And now for the protocols */ #include "ftp.h" @@ -847,6 +850,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.httpdigest = va_arg(param, long); break; +#ifdef GSSAPI + case CURLOPT_HTTPNEGOTIATE: + /* Enable HTTP Negotaiate authentication */ + data->set.httpnegotiate = va_arg(param, long); + break; +#endif case CURLOPT_USERPWD: /* * user:password to use in the operation -- cgit v1.2.1 From d0cc92a01a5b373c6730acd84009294da9c29e44 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Jun 2003 12:49:16 +0000 Subject: Set auth type differently, we use one CURLOPT_HTTPAUTH instead as we plan to add more method in the future. --- lib/url.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0ac487e91..c328e5ac4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -844,18 +844,38 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; break; - case CURLOPT_HTTPDIGEST: + case CURLOPT_HTTPAUTH: /* - * Enable HTTP Digest Authentication + * Set HTTP Authentication type. */ - data->set.httpdigest = va_arg(param, long); - break; + { + curl_httpauth auth = va_arg(param, long); + switch(auth) { + case CURLHTTP_BASIC: + /* default */ + data->set.httpdigest = FALSE; + data->set.httpnegotiate = FALSE; + break; + case CURLHTTP_DIGEST: + /* Enable HTTP Digest authentication */ + data->set.httpdigest = TRUE; + data->set.httpnegotiate = FALSE; + break; + case CURLHTTP_NEGOTIATE: #ifdef GSSAPI - case CURLOPT_HTTPNEGOTIATE: - /* Enable HTTP Negotaiate authentication */ - data->set.httpnegotiate = va_arg(param, long); - break; + /* Enable HTTP Negotaiate authentication */ + data->set.httpdigest = FALSE; + data->set.httpnegotiate = TRUE; + break; +#else + /* fall-through */ #endif + default: + return CURLE_FAILED_INIT; /* unsupported type */ + } + } + break; + case CURLOPT_USERPWD: /* * user:password to use in the operation -- cgit v1.2.1 From 73c5f24fa40460f41d6cd9114827383edc57e287 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Jun 2003 13:38:55 +0000 Subject: Initial take at NTLM authentication. It doesn't really work at this point but the infrastructure is there. --- lib/url.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c328e5ac4..f02eec0cc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -855,17 +855,32 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* default */ data->set.httpdigest = FALSE; data->set.httpnegotiate = FALSE; + data->set.httpntlm = FALSE; break; case CURLHTTP_DIGEST: /* Enable HTTP Digest authentication */ data->set.httpdigest = TRUE; data->set.httpnegotiate = FALSE; + data->set.httpntlm = FALSE; break; + case CURLHTTP_NTLM: + /* Enable HTTP NTLM authentication */ +#ifdef USE_SSLEAY + /* We can only support NTLM if OpenSSL is present, as we need their + crypto package for it */ + data->set.httpdigest = FALSE; + data->set.httpnegotiate = FALSE; + data->set.httpntlm = TRUE; + break; +#else + /* fall-through */ +#endif case CURLHTTP_NEGOTIATE: #ifdef GSSAPI /* Enable HTTP Negotaiate authentication */ data->set.httpdigest = FALSE; data->set.httpnegotiate = TRUE; + data->set.httpntlm = FALSE; break; #else /* fall-through */ -- cgit v1.2.1 From ecf32c964aa1f45285d26c91f2cad5513075aa45 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 12 Jun 2003 17:34:27 +0000 Subject: CURLHTTP* renamed to CURLAUTH* and NEGOTIATE is now GSSNEGOTIATE as there's a "plain" Negotiate as well. --- lib/url.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f02eec0cc..397d1d452 100644 --- a/lib/url.c +++ b/lib/url.c @@ -851,36 +851,24 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { curl_httpauth auth = va_arg(param, long); switch(auth) { - case CURLHTTP_BASIC: - /* default */ - data->set.httpdigest = FALSE; - data->set.httpnegotiate = FALSE; - data->set.httpntlm = FALSE; + case CURLAUTH_BASIC: + case CURLAUTH_DIGEST: + data->set.httpauth = auth; break; - case CURLHTTP_DIGEST: - /* Enable HTTP Digest authentication */ - data->set.httpdigest = TRUE; - data->set.httpnegotiate = FALSE; - data->set.httpntlm = FALSE; - break; - case CURLHTTP_NTLM: + case CURLAUTH_NTLM: /* Enable HTTP NTLM authentication */ #ifdef USE_SSLEAY /* We can only support NTLM if OpenSSL is present, as we need their crypto package for it */ - data->set.httpdigest = FALSE; - data->set.httpnegotiate = FALSE; - data->set.httpntlm = TRUE; + data->set.httpauth = auth; break; #else /* fall-through */ #endif - case CURLHTTP_NEGOTIATE: + case CURLAUTH_GSSNEGOTIATE: #ifdef GSSAPI /* Enable HTTP Negotaiate authentication */ - data->set.httpdigest = FALSE; - data->set.httpnegotiate = TRUE; - data->set.httpntlm = FALSE; + data->set.httpauth = auth; break; #else /* fall-through */ -- cgit v1.2.1 From c2faa39b62cb48f5b6857b516b8beb19a8aee0a3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 26 Jun 2003 11:30:59 +0000 Subject: added CURLOPT_HTTPAUTH support --- lib/url.c | 41 ++++++++++++----------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 397d1d452..9ec92dfab 100644 --- a/lib/url.c +++ b/lib/url.c @@ -108,9 +108,7 @@ #include "share.h" #include "content_encoding.h" #include "http_digest.h" -#ifdef GSSAPI #include "http_negotiate.h" -#endif /* And now for the protocols */ #include "ftp.h" @@ -137,7 +135,7 @@ #endif /* The last #include file should be: */ -#ifdef MALLOCDEBUG +#ifdef CURLDEBUG #include "memdebug.h" #endif @@ -846,36 +844,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) case CURLOPT_HTTPAUTH: /* - * Set HTTP Authentication type. + * Set HTTP Authentication type BITMASK. */ { - curl_httpauth auth = va_arg(param, long); - switch(auth) { - case CURLAUTH_BASIC: - case CURLAUTH_DIGEST: - data->set.httpauth = auth; - break; - case CURLAUTH_NTLM: - /* Enable HTTP NTLM authentication */ -#ifdef USE_SSLEAY - /* We can only support NTLM if OpenSSL is present, as we need their - crypto package for it */ - data->set.httpauth = auth; - break; -#else - /* fall-through */ + long auth = va_arg(param, long); + /* switch off bits we can't support */ +#ifndef USE_SSLEAY + auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif - case CURLAUTH_GSSNEGOTIATE: #ifdef GSSAPI - /* Enable HTTP Negotaiate authentication */ - data->set.httpauth = auth; - break; -#else - /* fall-through */ + auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ #endif - default: - return CURLE_FAILED_INIT; /* unsupported type */ - } + if(!auth) + return CURLE_FAILED_INIT; /* no supported types left! */ + + data->set.httpauth = auth; } break; @@ -3081,7 +3064,7 @@ CURLcode Curl_done(struct connectdata *conn) if(conn->connect_addr) Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */ -#if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST) +#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, NULL, Curl_scan_cache_used); -- cgit v1.2.1 From 45fc760985fa11ef98149418cbad02dadf748f31 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 4 Jul 2003 16:29:23 +0000 Subject: Peter Sylvester's patch was applied that introduces the following: CURLOPT_SSL_CTX_FUNCTION to set a callback that gets called with the OpenSSL's ssl_ctx pointer passed in and allow a callback to act on it. If anything but CURLE_OK is returned, that will also be returned by libcurl all the way back. If this function changes the CURLOPT_URL, libcurl will detect this and instead go use the new URL. CURLOPT_SSL_CTX_DATA is a pointer you set to get passed to the callback set with CURLOPT_SSL_CTX_FUNCTION. --- lib/url.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9ec92dfab..3b6a73b90 100644 --- a/lib/url.c +++ b/lib/url.c @@ -723,6 +723,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } data->set.set_url = va_arg(param, char *); data->change.url = data->set.set_url; + data->change.url_changed = TRUE; break; case CURLOPT_PORT: /* @@ -1091,6 +1092,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.ssl.verifyhost = va_arg(param, long); break; + case CURLOPT_SSL_CTX_FUNCTION: + /* + * Set a SSL_CTX callback + */ + data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); + break; + case CURLOPT_SSL_CTX_DATA: + /* + * Set a SSL_CTX callback parameter pointer + */ + data->set.ssl.fsslctxp = va_arg(param, void *); + break; case CURLOPT_CAINFO: /* * Set CA info for SSL connection. Specify file name of the CA certificate -- cgit v1.2.1 From 52b631fadecb5ff5f038badfd79055e7d4272927 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 19 Jul 2003 23:56:33 +0000 Subject: Access the user and passwd fields from the connectdata struct now instead of the sessionhandle struct, as that was not good. --- lib/url.c | 77 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 30 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3b6a73b90..5a91b8c03 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1252,6 +1252,11 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(-1 != conn->firstsocket) sclose(conn->firstsocket); + if(conn->user) + free(conn->user); + if(conn->passwd) + free(conn->passwd); + if(conn->allocptr.proxyuserpwd) free(conn->allocptr.proxyuserpwd); if(conn->allocptr.uagent) @@ -1358,8 +1363,8 @@ ConnectionExists(struct SessionHandle *data, if(needle->protocol & PROT_FTP) { /* This is FTP, verify that we're using the same name and password as well */ - if(!strequal(needle->data->state.user, check->proto.ftp->user) || - !strequal(needle->data->state.passwd, check->proto.ftp->passwd)) { + if(!strequal(needle->user, check->user) || + !strequal(needle->passwd, check->passwd)) { /* one of them was different */ continue; } @@ -1840,6 +1845,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, unsigned int prev_alarm=0; #endif char endbracket; + char user[MAX_CURL_USER_LENGTH]; + char passwd[MAX_CURL_PASSWORD_LENGTH]; + bool passwdgiven=FALSE; /* set TRUE if an application-provided password has + been set */ + #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ @@ -2590,8 +2600,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, * * Outputs: (almost :- all currently undefined) * conn->bits.user_passwd - non-zero if non-default passwords exist - * conn->state.user - non-zero length if defined - * conn->state.passwd - ditto + * conn->user - non-zero length if defined + * conn->passwd - ditto * conn->hostname - remove user name and password */ @@ -2602,8 +2612,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, * We need somewhere to put the embedded details, so do that first. */ - data->state.user[0] =0; /* to make everything well-defined */ - data->state.passwd[0]=0; + user[0] =0; /* to make everything well-defined */ + passwd[0]=0; if (conn->protocol & (PROT_FTP|PROT_HTTP)) { /* This is a FTP or HTTP URL, we will now try to extract the possible @@ -2630,31 +2640,31 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(*userpass != ':') { /* the name is given, get user+password */ sscanf(userpass, "%127[^:@]:%127[^@]", - data->state.user, data->state.passwd); + user, passwd); } else /* no name given, get the password only */ - sscanf(userpass, ":%127[^@]", data->state.passwd); + sscanf(userpass, ":%127[^@]", passwd); - 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(user[0]) { + char *newname=curl_unescape(user, 0); + if(strlen(newname) < sizeof(user)) { + strcpy(user, newname); } /* if the new name is longer than accepted, then just use the unconverted name, it'll be wrong but what the heck */ free(newname); } - if (data->state.passwd[0]) { + if (passwd[0]) { /* we have a password found in the URL, decode it! */ - char *newpasswd=curl_unescape(data->state.passwd, 0); - if(strlen(newpasswd) < sizeof(data->state.passwd)) { - strcpy(data->state.passwd, newpasswd); + char *newpasswd=curl_unescape(passwd, 0); + if(strlen(newpasswd) < sizeof(passwd)) { + strcpy(passwd, newpasswd); } free(newpasswd); /* we have set the password */ - data->state.passwdgiven = TRUE; + passwdgiven = TRUE; } } } @@ -2673,35 +2683,35 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(*data->set.userpwd != ':') { /* the name is given, get user+password */ sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", - data->state.user, data->state.passwd); + user, passwd); if(strchr(data->set.userpwd, ':')) /* a colon means the password was given, even if blank */ - data->state.passwdgiven = TRUE; + passwdgiven = TRUE; } else /* no name given, starts with a colon, get the password only */ - sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd); + sscanf(data->set.userpwd+1, "%127[^\n]", passwd); } if ((data->set.use_netrc != CURL_NETRC_IGNORED) && - !data->state.passwdgiven) { /* need passwd */ + !passwdgiven) { /* need passwd */ if(Curl_parsenetrc(conn->hostname, - data->state.user, - data->state.passwd)) { + user, + passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } else { conn->bits.user_passwd = 1; /* enable user+password */ - data->state.passwdgiven = TRUE; + passwdgiven = TRUE; } } /* if we have a user but no password, ask for one */ - if(conn->bits.user_passwd && !data->state.passwdgiven ) { + if(conn->bits.user_passwd && !passwdgiven ) { if(data->set.fpasswd(data->set.passwd_client, - "password:", data->state.passwd, - sizeof(data->state.passwd))) + "password:", passwd, + sizeof(passwd))) return CURLE_BAD_PASSWORD_ENTERED; } @@ -2710,14 +2720,18 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* If our protocol needs a password and we have none, use the defaults */ if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && !conn->bits.user_passwd && - !data->state.passwdgiven) { + !passwdgiven) { - strcpy(data->state.user, CURL_DEFAULT_USER); - strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD); + strcpy(user, CURL_DEFAULT_USER); + strcpy(passwd, CURL_DEFAULT_PASSWORD); /* This is the default password, so DON'T set conn->bits.user_passwd */ } + /* store user + password */ + conn->user = strdup(user); + conn->passwd = strdup(passwd); + /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a @@ -2777,6 +2791,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, otherwise */ conn->maxdownload = -1; /* might have been used previously! */ + free(old_conn->user); + free(old_conn->passwd); + free(old_conn); /* we don't need this anymore */ /* -- cgit v1.2.1 From 0049c09fc3890768bedf0a280889487d9828f9a0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 20 Jul 2003 00:02:47 +0000 Subject: If NTLM is requested, only re-use connections that have the exact same credentials. --- lib/url.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5a91b8c03..b44f630c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1360,9 +1360,11 @@ ConnectionExists(struct SessionHandle *data, continue; } } - if(needle->protocol & PROT_FTP) { - /* This is FTP, verify that we're using the same name and - password as well */ + if((needle->protocol & PROT_FTP) || + ((needle->protocol & PROT_HTTP) && + (needle->data->state.authwant==CURLAUTH_NTLM))) { + /* This is FTP or HTTP+NTLM, verify that we're using the same name + and password as well */ if(!strequal(needle->user, check->user) || !strequal(needle->passwd, check->passwd)) { /* one of them was different */ -- cgit v1.2.1 From 071c95128e2a43be1431c3c38202a1d54d97644a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 21 Jul 2003 13:16:30 +0000 Subject: moved the proxyuser and proxypasswd fields from the sessionhandle to the connectdata to work as expected --- lib/url.c | 113 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 57 insertions(+), 56 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b44f630c0..427e072e3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -167,6 +167,11 @@ RETSIGTYPE alarmfunc(int signal) } #endif +void Curl_safefree(void *ptr) +{ + if(ptr) + free(ptr); +} /* * This is the internal function curl_easy_cleanup() calls. This should @@ -194,11 +199,8 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->change.cookielist) /* clean up list if any */ curl_slist_free_all(data->change.cookielist); - if(data->state.auth_host) - free(data->state.auth_host); - - if(data->state.scratch) - free(data->state.scratch); + Curl_safefree(data->state.auth_host); + Curl_safefree(data->state.scratch); if(data->change.proxy_alloc) free(data->change.proxy); @@ -209,8 +211,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->change.url_alloc) free(data->change.url); - if(data->state.headerbuff) - free(data->state.headerbuff); + Curl_safefree(data->state.headerbuff); #ifndef CURL_DISABLE_HTTP if(data->set.cookiejar) { @@ -225,8 +226,7 @@ CURLcode Curl_close(struct SessionHandle *data) /* free the connection cache */ free(data->state.connects); - if(data->info.contenttype) - free(data->info.contenttype); + Curl_safefree(data->info.contenttype); Curl_digest_cleanup(data); @@ -1233,14 +1233,9 @@ CURLcode Curl_disconnect(struct connectdata *conn) /* This is set if protocol-specific cleanups should be made */ conn->curl_disconnect(conn); - if(conn->proto.generic) - free(conn->proto.generic); - - if(conn->newurl) - free(conn->newurl); - - if(conn->path) /* the URL path part */ - free(conn->path); + Curl_safefree(conn->proto.generic); + Curl_safefree(conn->newurl); + Curl_safefree(conn->path); /* the URL path part */ #ifdef USE_SSLEAY Curl_SSL_Close(conn); @@ -1252,32 +1247,20 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(-1 != conn->firstsocket) sclose(conn->firstsocket); - if(conn->user) - free(conn->user); - if(conn->passwd) - free(conn->passwd); - - 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.accept_encoding) - free(conn->allocptr.accept_encoding); - 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); - if(conn->allocptr.cookiehost) - free(conn->allocptr.cookiehost); - - if(conn->proxyhost) - free(conn->proxyhost); + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + Curl_safefree(conn->proxyuser); + Curl_safefree(conn->proxypasswd); + Curl_safefree(conn->allocptr.proxyuserpwd); + Curl_safefree(conn->allocptr.uagent); + Curl_safefree(conn->allocptr.userpwd); + Curl_safefree(conn->allocptr.accept_encoding); + Curl_safefree(conn->allocptr.rangeline); + Curl_safefree(conn->allocptr.ref); + Curl_safefree(conn->allocptr.cookie); + Curl_safefree(conn->allocptr.host); + Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->proxyhost); Curl_free_ssl_config(&conn->ssl_config); @@ -1722,8 +1705,8 @@ static CURLcode ConnectPlease(struct connectdata *conn, #endif if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { - return handleSock5Proxy(conn->data->state.proxyuser, - conn->data->state.proxypasswd, + return handleSock5Proxy(conn->proxyuser, + conn->proxypasswd, conn, conn->firstsocket) ? CURLE_COULDNT_CONNECT : CURLE_OK; @@ -2065,29 +2048,36 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Take care of proxy authentication stuff *************************************************************/ if(conn->bits.proxy_user_passwd) { - data->state.proxyuser[0] =0; - data->state.proxypasswd[0]=0; + char proxyuser[MAX_CURL_USER_LENGTH]=""; + char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; if(*data->set.proxyuserpwd != ':') { /* the name is given, get user+password */ sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]", - data->state.proxyuser, data->state.proxypasswd); + proxyuser, proxypasswd); } else /* no name given, get the password only */ - sscanf(data->set.proxyuserpwd+1, "%127[^\n]", data->state.proxypasswd); + sscanf(data->set.proxyuserpwd+1, "%127[^\n]", proxypasswd); /* check for password, if no ask for one */ - if( !data->state.proxypasswd[0] ) { + if( !proxypasswd[0] ) { if(data->set.fpasswd( data->set.passwd_client, "proxy password:", - data->state.proxypasswd, - sizeof(data->state.proxypasswd))) { + proxypasswd, + sizeof(proxypasswd))) { failf(data, "Bad password from password callback"); return CURLE_BAD_PASSWORD_ENTERED; } } + conn->proxyuser = strdup(proxyuser); + if(!conn->proxyuser) + return CURLE_OUT_OF_MEMORY; + + conn->proxypasswd = strdup(proxypasswd); + if(!conn->proxypasswd) + return CURLE_OUT_OF_MEMORY; } /************************************************************* @@ -2097,7 +2087,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->ppath = conn->path; conn->hostname = conn->name; - /************************************************************* * Detect what (if any) proxy to use *************************************************************/ @@ -2215,8 +2204,20 @@ static CURLcode CreateConnection(struct SessionHandle *data, "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", user, passwd))) { /* found user and password, rip them out */ - strcpy(data->state.proxyuser, user); - strcpy(data->state.proxypasswd, passwd); + if(conn->proxyuser) + free(conn->proxyuser); + conn->proxyuser = strdup(user); + + if(!conn->proxyuser) + return CURLE_OUT_OF_MEMORY; + + if(conn->proxypasswd) + free(conn->proxypasswd); + conn->proxypasswd = strdup(passwd); + + if(!conn->proxypasswd) + return CURLE_OUT_OF_MEMORY; + conn->bits.proxy_user_passwd = TRUE; /* enable it */ ptr = strdup(ptr+1); @@ -2976,7 +2977,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->bits.proxy_user_passwd) { char *authorization; snprintf(data->state.buffer, BUFSIZE, "%s:%s", - data->state.proxyuser, data->state.proxypasswd); + conn->proxyuser, conn->proxypasswd); if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer), &authorization) >= 0) { if(conn->allocptr.proxyuserpwd) -- cgit v1.2.1 From 981ffd9fce0f41843a6f8abc0bbc35978ec95f4c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 22 Jul 2003 11:15:46 +0000 Subject: reversed the check for GSSAPI when request that auth --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 427e072e3..13f944d1d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -853,7 +853,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) #ifndef USE_SSLEAY auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifdef GSSAPI +#ifndef GSSAPI auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ #endif if(!auth) -- cgit v1.2.1 From e9f63bf4e84dfdc22b6fb0469747b9067b90943b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 23 Jul 2003 17:06:21 +0000 Subject: When we re-use an existing connection we must make sure that we don't accidentally re-use the connect_addr field, as that might no longer be around. Fix verified by Tracy Boehrer who basicly debugged and tracked down this problem. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 13f944d1d..d230db180 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2901,6 +2901,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->bits.reuse) { /* re-used connection, no resolving is necessary */ hostaddr = NULL; + conn->connect_addr = NULL; /* we don't connect now so we don't have any + fresh connect_addr struct to point to */ } else if(!data->change.proxy || !*data->change.proxy) { /* If not connecting via a proxy, extract the port from the URL, if it is -- cgit v1.2.1 From f0278ca114b266bfc1edd399e463e89f653e1ec8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 25 Jul 2003 08:30:58 +0000 Subject: Removed #include , as pointed out by Henry Bland we don't need it. --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d230db180..3eceb3c9a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -45,7 +45,6 @@ #endif #include #include -#include #ifdef HAVE_UNISTD_H #include #endif -- cgit v1.2.1 From 41ae97e710f728495a1d6adba6476c21b94c4881 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 4 Aug 2003 15:02:42 +0000 Subject: Dirk Manske's patch that introduces cookie support to the share interface. --- lib/url.c | 60 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3eceb3c9a..f1095bcee 100644 --- a/lib/url.c +++ b/lib/url.c @@ -191,10 +191,6 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_SSL_Close_All(data); #endif - /* No longer a dirty share, if it exists */ - if (data->share) - data->share->dirty--; - if(data->change.cookielist) /* clean up list if any */ curl_slist_free_all(data->change.cookielist); @@ -213,13 +209,17 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.headerbuff); #ifndef CURL_DISABLE_HTTP + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); if(data->set.cookiejar) { /* we have a "destination" for all the cookies to get dumped to */ if(Curl_cookie_output(data->cookies, data->set.cookiejar)) infof(data, "WARNING: failed to save cookies in given jar\n"); } - Curl_cookie_cleanup(data->cookies); + if( !data->share || (data->cookies != data->share->cookies) ) { + Curl_cookie_cleanup(data->cookies); + } + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); #endif /* free the connection cache */ @@ -229,6 +229,10 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_digest_cleanup(data); + /* No longer a dirty share, if it exists */ + if (data->share) + data->share->dirty--; + free(data); return CURLE_OK; } @@ -1148,34 +1152,56 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { struct Curl_share *set; set = va_arg(param, struct Curl_share *); - if(data->share) - { + + /* disconnect from old share, if any */ + if(data->share) { Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - /* checking the dns cache stuff */ if(data->share->hostcache == data->hostcache) - { data->hostcache = NULL; - } + + if(data->share->cookies == data->cookies) + data->cookies = NULL; data->share->dirty--; Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + data->share = NULL; } + /* use new share if it set */ data->share = set; + if(data->share) { + + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + data->share->dirty++; - data->share->dirty++; + if(data->share->hostcache) { + /* use shared host cache, first free own one if any */ + if(data->hostcache) + Curl_hash_destroy(data->hostcache); - if( data->hostcache ) - { - Curl_hash_destroy(data->hostcache); - data->hostcache = data->share->hostcache; + data->hostcache = data->share->hostcache; + } + + if(data->share->cookies) { + /* use shared cookie list, first free own one if any */ + if (data->cookies) + Curl_cookie_cleanup(data->cookies); + data->cookies = data->share->cookies; + } + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + /* check cookie list is set */ + if(!data->cookies) + data->cookies = Curl_cookie_init( NULL, NULL, TRUE ); + + /* check for host cache not needed, + * it will be done by curl_easy_perform */ } break; -- cgit v1.2.1 From b73612392d7afbf9835a119446e2a58e72384b00 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Aug 2003 14:40:59 +0000 Subject: ares awareness/usage/support added. If configure --enable-ares is used, we build libcurl to use ares for asynch name resolves. --- lib/url.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 136 insertions(+), 30 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f1095bcee..84f3bbb0f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -147,7 +147,11 @@ static unsigned int ConnectionStore(struct SessionHandle *data, struct connectdata *conn); static bool safe_strequal(char* str1, char* str2); -#if !defined(WIN32)||defined(__CYGWIN32__) +#ifndef USE_ARES +/* not for Win32, unless it is cygwin + not for ares builds */ +#if !defined(WIN32) || defined(__CYGWIN32__) + #ifndef RETSIGTYPE #define RETSIGTYPE void #endif @@ -165,6 +169,7 @@ RETSIGTYPE alarmfunc(int signal) return; } #endif +#endif /* USE_ARES */ void Curl_safefree(void *ptr) { @@ -1286,7 +1291,11 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->proxyhost); - +#ifdef USE_ARES + /* possible left-overs from the async name resolve */ + Curl_safefree(conn->async.hostname); +#endif + Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ @@ -1632,7 +1641,15 @@ static int handleSock5Proxy( #ifndef ENABLE_IPV6 struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; - dns = Curl_resolv(conn->data, conn->hostname, conn->remote_port); + int rc = Curl_resolv(conn, conn->hostname, conn->remote_port, &dns); + + if(rc == -1) + return CURLE_COULDNT_RESOLVE_HOST; + + if(rc == 1) + /* this requires that we're in "wait for resolve" state */ + rc = Curl_wait_for_resolv(conn, &dns); + /* * We cannot use 'hostent' as a struct that Curl_resolv() returns. It * returns a Curl_addrinfo pointer that may not always look the same. @@ -1841,8 +1858,19 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, return result; /* pass back status */ } +/* + * CreateConnection() sets up a new connectdata struct, or re-uses an already + * existing one, and resolves host name. + * + * if this function returns CURLE_OK and *async is set to TRUE, the resolve + * response will be coming asynchronously. If *async is FALSE, the name is + * already resolved. + */ + static CURLcode CreateConnection(struct SessionHandle *data, - struct connectdata **in_connect) + struct connectdata **in_connect, + struct Curl_dns_entry **addr, + bool *async) { char *tmp; CURLcode result=CURLE_OK; @@ -1859,7 +1887,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, char passwd[MAX_CURL_PASSWORD_LENGTH]; bool passwdgiven=FALSE; /* set TRUE if an application-provided password has been set */ - + int rc; #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ @@ -1870,6 +1898,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif #endif + *addr = NULL; /* nothing yet */ + *async = FALSE; + /************************************************************* * Check input data *************************************************************/ @@ -2875,8 +2906,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* else, no chunky upload */ FALSE; +#ifndef USE_ARES /************************************************************* - * Set timeout if that is being used + * Set timeout if that is being used, and we're not using an asynchronous + * name resolve. *************************************************************/ if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { /************************************************************* @@ -2919,7 +2952,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, has been done since then until now. */ #endif } - +#endif + /************************************************************* * Resolve the name of the server or proxy *************************************************************/ @@ -2935,9 +2969,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = conn->remote_port; /* it is the same port */ /* Resolve target host right on */ - hostaddr = Curl_resolv(data, conn->name, conn->port); + rc = Curl_resolv(conn, conn->name, conn->port, &hostaddr); + if(rc == 1) + *async = TRUE; - if(!hostaddr) { + else if(!hostaddr) { failf(data, "Couldn't resolve host '%s'", conn->name); result = CURLE_COULDNT_RESOLVE_HOST; /* don't return yet, we need to clean up the timeout first */ @@ -2947,15 +2983,19 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* This is a proxy that hasn't been resolved yet. */ /* resolve proxy */ - hostaddr = Curl_resolv(data, conn->proxyhost, conn->port); + rc = Curl_resolv(conn, conn->proxyhost, conn->port, &hostaddr); + + if(rc == 1) + *async = TRUE; - if(!hostaddr) { + else if(!hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); result = CURLE_COULDNT_RESOLVE_PROXY; /* don't return yet, we need to clean up the timeout first */ } } - Curl_pgrsTime(data, TIMER_NAMELOOKUP); + *addr = hostaddr; + #ifdef HAVE_ALARM if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { #ifdef HAVE_SIGACTION @@ -2995,7 +3035,25 @@ static CURLcode CreateConnection(struct SessionHandle *data, alarm(0); /* just shut it off */ } #endif - if(result) + + return result; +} + +/* SetupConnection() should be called after the name resolve initiated in + * CreateConnection() is all done. + */ + +static CURLcode SetupConnection(struct connectdata *conn, + struct Curl_dns_entry *hostaddr) +{ + struct SessionHandle *data = conn->data; + CURLcode result=CURLE_OK; + + Curl_pgrsTime(data, TIMER_NAMELOOKUP); + + if(conn->protocol & PROT_FILE) + /* There's nothing in this function to setup if we're only doing + a file:// transfer */ return result; /************************************************************* @@ -3007,8 +3065,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->proxyuser, conn->proxypasswd); if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer), &authorization) >= 0) { - if(conn->allocptr.proxyuserpwd) - free(conn->allocptr.proxyuserpwd); + Curl_safefree(conn->allocptr.proxyuserpwd); conn->allocptr.proxyuserpwd = aprintf("Proxy-authorization: Basic %s\015\012", authorization); free(authorization); @@ -3022,16 +3079,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, if((conn->protocol&PROT_HTTP) || (data->change.proxy && *data->change.proxy)) { if(data->set.useragent) { - if(conn->allocptr.uagent) - free(conn->allocptr.uagent); + Curl_safefree(conn->allocptr.uagent); conn->allocptr.uagent = aprintf("User-Agent: %s\015\012", data->set.useragent); } } if(data->set.encoding) { - if(conn->allocptr.accept_encoding) - free(conn->allocptr.accept_encoding); + Curl_safefree(conn->allocptr.accept_encoding); conn->allocptr.accept_encoding = aprintf("Accept-Encoding: %s\015\012", data->set.encoding); } @@ -3083,26 +3138,60 @@ static CURLcode CreateConnection(struct SessionHandle *data, } CURLcode Curl_connect(struct SessionHandle *data, - struct connectdata **in_connect) + struct connectdata **in_connect, + bool *asyncp) { CURLcode code; - struct connectdata *conn; + struct Curl_dns_entry *dns; + *asyncp = FALSE; /* assume synchronous resolves by default */ + /* call the stuff that needs to be called */ - code = CreateConnection(data, in_connect); - + code = CreateConnection(data, in_connect, &dns, asyncp); + + if(CURLE_OK == code) { + /* no error */ + if(dns || !*asyncp) + /* If an address is available it means that we already have the name + resolved, OR it isn't async. + If so => continue connecting from here */ + code = SetupConnection(*in_connect, dns); + /* else + response will be received and treated async wise */ + } + if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ - conn = (struct connectdata *)*in_connect; - if(conn) { - Curl_disconnect(conn); /* close the connection */ - *in_connect = NULL; /* return a NULL */ + if(*in_connect) { + Curl_disconnect(*in_connect); /* close the connection */ + *in_connect = NULL; /* return a NULL */ } } + return code; } +/* Call this function after Curl_connect() has returned async=TRUE and + then a successful name resolve has been received */ +CURLcode Curl_async_resolved(struct connectdata *conn) +{ +#ifdef USE_ARES + CURLcode code = SetupConnection(conn, conn->async.dns); + + if(code) + /* We're not allowed to return failure with memory left allocated + in the connectdata struct, free those here */ + Curl_disconnect(conn); /* close the connection */ + + return code; +#else + (void)conn; + return CURLE_OK; +#endif +} + + CURLcode Curl_done(struct connectdata *conn) { struct SessionHandle *data=conn->data; @@ -3179,11 +3268,28 @@ CURLcode Curl_do(struct connectdata **connp) conn->bits.close = TRUE; /* enforce close of this connetion */ result = Curl_done(conn); /* we are so done with this */ if(CURLE_OK == result) { + bool async; /* Now, redo the connect and get a new connection */ - result = Curl_connect(data, connp); - if(CURLE_OK == result) + result = Curl_connect(data, connp, &async); + if(CURLE_OK == result) { + /* We have connected or sent away a name resolve query fine */ + + if(async) { + /* Now, if async is TRUE here, we need to wait for the name + to resolve */ + result = Curl_wait_for_resolv(conn, NULL); + if(result) + return result; + + /* Resolved, continue with the connection */ + result = Curl_async_resolved(conn); + if(result) + return result; + } + /* ... finally back to actually retry the DO phase */ - result = conn->curl_do(*connp); + result = conn->curl_do(conn); + } } } } -- cgit v1.2.1 From f9f1f0e31635a551f51d2b9e4a7afde4ad4027ca Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 8 Aug 2003 09:13:19 +0000 Subject: Early Ehlinger's CURLOPT_FTP_CREATE_MISSING_DIRS patch was applied --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 84f3bbb0f..4bd02705a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -489,6 +489,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.get_filetime = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_FTP_CREATE_MISSING_DIRS: + /* + * An FTP option that modifies an upload to create missing directories on + * the server. + */ + data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE; + break; case CURLOPT_FTPLISTONLY: /* * An FTP option that changes the command to one that asks for a list -- cgit v1.2.1 From 96e217b49628a7dd19ad4be66b1842dcf0940309 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Aug 2003 09:56:06 +0000 Subject: the new cookie functions that require 'data' passed in --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4bd02705a..03059d84a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -617,7 +617,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Activate the cookie parser. This may or may not already * have been made. */ - data->cookies = Curl_cookie_init(NULL, data->cookies, + data->cookies = Curl_cookie_init(data, NULL, data->cookies, data->set.cookiesession); break; #endif @@ -1210,7 +1210,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* check cookie list is set */ if(!data->cookies) - data->cookies = Curl_cookie_init( NULL, NULL, TRUE ); + data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE ); /* check for host cache not needed, * it will be done by curl_easy_perform */ -- cgit v1.2.1 From 7a19923afa17dbfa9b45d8620bac003398cf1ebd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Aug 2003 11:47:45 +0000 Subject: Serge Semashko added CURLOPT_PROXYAUTH support, and now NTLM for proxies work. --- lib/url.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 03059d84a..46245a5ce 100644 --- a/lib/url.c +++ b/lib/url.c @@ -312,6 +312,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ + data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic authentication */ + data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic authentication */ + /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ data->state.connects = (struct connectdata **) @@ -878,6 +881,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } break; + case CURLOPT_PROXYAUTH: + /* + * Set HTTP Authentication type BITMASK. + */ + { + long auth = va_arg(param, long); + /* switch off bits we can't support */ +#ifndef USE_SSLEAY + auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ +#endif +#ifndef GSSAPI + auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ +#endif + if(!auth) + return CURLE_FAILED_INIT; /* no supported types left! */ + + data->set.proxyauth = auth; + } + break; + case CURLOPT_USERPWD: /* * user:password to use in the operation @@ -3066,6 +3089,7 @@ static CURLcode SetupConnection(struct connectdata *conn, /************************************************************* * Proxy authentication *************************************************************/ +#if 0 /* This code is not needed anymore (moved to http.c) */ if(conn->bits.proxy_user_passwd) { char *authorization; snprintf(data->state.buffer, BUFSIZE, "%s:%s", @@ -3078,6 +3102,7 @@ static CURLcode SetupConnection(struct connectdata *conn, free(authorization); } } +#endif /************************************************************* * Send user-agent to HTTP proxies even if the target protocol -- cgit v1.2.1 From acfa131c8cc94930064c23561892a83295aaffd3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Aug 2003 12:25:30 +0000 Subject: memory leak fixed when re-using connections with proxy user+passwd --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 46245a5ce..9fd1ce576 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2882,6 +2882,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(old_conn->user); free(old_conn->passwd); + free(old_conn->proxyuser); + free(old_conn->proxypasswd); free(old_conn); /* we don't need this anymore */ -- cgit v1.2.1 From 84ed5e755ab1e16f0d7a9923e7f63b8337128960 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Aug 2003 12:30:21 +0000 Subject: use safefree instead --- lib/url.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9fd1ce576..76331aac9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2290,15 +2290,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", user, passwd))) { /* found user and password, rip them out */ - if(conn->proxyuser) - free(conn->proxyuser); + Curl_safefree(conn->proxyuser); conn->proxyuser = strdup(user); if(!conn->proxyuser) return CURLE_OUT_OF_MEMORY; - if(conn->proxypasswd) - free(conn->proxypasswd); + Curl_safefree(conn->proxypasswd); conn->proxypasswd = strdup(passwd); if(!conn->proxypasswd) @@ -2882,8 +2880,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(old_conn->user); free(old_conn->passwd); - free(old_conn->proxyuser); - free(old_conn->proxypasswd); + Curl_safefree(old_conn->proxyuser); + Curl_safefree(old_conn->proxypasswd); free(old_conn); /* we don't need this anymore */ -- cgit v1.2.1 From 3454319c17d817a0eba289158493d4066d57cdbb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Aug 2003 14:20:03 +0000 Subject: prevent memory leak when going out of memory --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 76331aac9..588391524 100644 --- a/lib/url.c +++ b/lib/url.c @@ -321,6 +321,7 @@ CURLcode Curl_open(struct SessionHandle **curl) malloc(sizeof(struct connectdata *) * data->state.numconnects); if(!data->state.connects) { + free(data->state.headerbuff); free(data); return CURLE_OUT_OF_MEMORY; } -- cgit v1.2.1 From 394faaeb9779d4639c845793eeec6d30e12baa3a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 Aug 2003 13:32:37 +0000 Subject: setting WRITEFUNCTION or READFUNCTION to NULL will now reset the callback pointers to the internal default functions --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 588391524..3c5240b78 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1016,12 +1016,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Set data write callback */ data->set.fwrite = va_arg(param, curl_write_callback); + if(!data->set.fwrite) + /* When set to NULL, reset to our internal default function */ + data->set.fwrite = (curl_write_callback)fwrite; break; case CURLOPT_READFUNCTION: /* * Read data callback */ data->set.fread = va_arg(param, curl_read_callback); + if(!data->set.fread) + /* When set to NULL, reset to our internal default function */ + data->set.fread = (curl_read_callback)fread; break; case CURLOPT_SSLCERT: /* -- cgit v1.2.1 From fa162e8febe054b04130355ef3a917201820c688 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Aug 2003 11:28:55 +0000 Subject: CURLOPT_BUFFERSIZE must not be smaller than 0 (zero) as that is impossible for us to deal with --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3c5240b78..2b8a09794 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1177,7 +1177,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.buffer_size = va_arg(param, long); - if(data->set.buffer_size> (BUFSIZE -1 )) + if((data->set.buffer_size> (BUFSIZE -1 )) || + (data->set.buffer_size < 1)) data->set.buffer_size = 0; /* huge internal default */ break; -- cgit v1.2.1 From cafcc242e63828cbb6fb299abbe5ec7391b0560e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Sep 2003 21:47:41 +0000 Subject: Joerg Mueller-Tolk's fix to better deal with user+passwords for proxies --- lib/url.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2b8a09794..40b718fee 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2144,18 +2144,24 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->bits.proxy_user_passwd) { char proxyuser[MAX_CURL_USER_LENGTH]=""; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; + passwdgiven = FALSE; if(*data->set.proxyuserpwd != ':') { /* the name is given, get user+password */ sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]", proxyuser, proxypasswd); - } - else + if(strchr(data->set.proxyuserpwd, ':')) + /* a colon means the password was given, even if blank */ + passwdgiven = TRUE; + } + else { /* no name given, get the password only */ sscanf(data->set.proxyuserpwd+1, "%127[^\n]", proxypasswd); + passwdgiven = TRUE; + } /* check for password, if no ask for one */ - if( !proxypasswd[0] ) { + if( !proxypasswd[0] && !passwdgiven) { if(data->set.fpasswd( data->set.passwd_client, "proxy password:", proxypasswd, @@ -2709,6 +2715,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, user[0] =0; /* to make everything well-defined */ passwd[0]=0; + passwdgiven = FALSE; /* none given so far */ if (conn->protocol & (PROT_FTP|PROT_HTTP)) { /* This is a FTP or HTTP URL, we will now try to extract the possible -- cgit v1.2.1 From f2d422235b0bf7dc6e7179143296a5e4abf8b9ed Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Sep 2003 22:02:40 +0000 Subject: Early Ehlinger's CURLOPT_FTP_RESPONSE_TIMEOUT patch applied. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 40b718fee..69c3677b1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -500,6 +500,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE; break; + case CURLOPT_FTP_RESPONSE_TIMEOUT: + /* + * An FTP option that specifies how quickly an FTP response must be + * obtained before it is considered failure. + */ + data->set.ftp_response_timeout = va_arg( param , long ); + break; case CURLOPT_FTPLISTONLY: /* * An FTP option that changes the command to one that asks for a list -- cgit v1.2.1 From 951e2a654582c6c05c28d69b049584d28e19b932 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 15 Sep 2003 22:33:18 +0000 Subject: If a connection is closed down and it had some kind of NTLM involved, we reset the authentication state to make it restart on the next connection. This of course because NTLM is connection-oriented, whilst all other authentication schemes are not. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 69c3677b1..a1f474d4d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1298,6 +1298,13 @@ CURLcode Curl_disconnect(struct connectdata *conn) conn->bits.rangestringalloc = FALSE; } + if((conn->ntlm.state != NTLMSTATE_NONE) || + (conn->proxyntlm.state != NTLMSTATE_NONE)) + /* Authentication data is a mix of connection-related and sessionhandle- + related stuff. NTLM is connection-related so when we close the shop + we shall forget. */ + conn->data->state.authstage = 0; + if(-1 != conn->connectindex) { /* unlink ourselves! */ infof(conn->data, "Closing connection #%d\n", conn->connectindex); -- cgit v1.2.1 From 09ccfcdcd422fc0b0421562bbdcf53f78a3f3e4b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Sep 2003 12:56:22 +0000 Subject: Markus Moeller's SPNEGO patch applied, with my edits, additions and minor cleanups. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a1f474d4d..12abbb2c5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -879,7 +879,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) #ifndef USE_SSLEAY auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef GSSAPI +#ifndef HAVE_GSSAPI auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ #endif if(!auth) @@ -899,7 +899,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) #ifndef USE_SSLEAY auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef GSSAPI +#ifndef HAVE_GSSAPI auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ #endif if(!auth) -- cgit v1.2.1 From d1a3c9944ee3215d78d644c47768e205fd043990 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 9 Oct 2003 20:04:47 +0000 Subject: Lachlan O'Dea fixed a resume problem: "If I set CURLOPT_RESUME_FROM, perform an HTTP download, then reset CURLOPT_RESUME_FROM to 0, the next download still has a Range header with a garbage value." bug report #820502 --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 12abbb2c5..435e6b3d1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2935,6 +2935,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ conn->bits.use_range = TRUE; /* enable range download */ } + else + conn->bits.use_range = FALSE; /* disable range download */ *in_connect = conn; /* return this instead! */ -- cgit v1.2.1 From 749f5387c19449209615b282ac738032f2a890e7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 14 Oct 2003 12:00:45 +0000 Subject: Gisle Vanem's IPv6-on-Windows patch applied! --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 435e6b3d1..c76ad9e7f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -36,7 +36,6 @@ #include #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include #include #include #else -- cgit v1.2.1 From 22adcb9cd1d99858f10e55dc140ceb19d382eee5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Oct 2003 14:08:59 +0000 Subject: password promting support removed from libcurl --- lib/url.c | 107 ++++++-------------------------------------------------------- 1 file changed, 9 insertions(+), 98 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c76ad9e7f..7271af1da 100644 --- a/lib/url.c +++ b/lib/url.c @@ -97,7 +97,6 @@ #include "if2ip.h" #include "transfer.h" #include "sendf.h" -#include "getpass.h" #include "progress.h" #include "cookie.h" #include "strequal.h" @@ -241,20 +240,6 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } -static -int my_getpass(void *clientp, const char *prompt, char* buffer, int buflen ) -{ - char *retbuf; - clientp=NULL; /* prevent compiler warning */ - - retbuf = getpass_r(prompt, buffer, buflen); - if(NULL == retbuf) - return 1; - else - return 0; /* success */ -} - - CURLcode Curl_open(struct SessionHandle **curl) { /* We don't yet support specifying the URL at this point */ @@ -287,9 +272,6 @@ CURLcode Curl_open(struct SessionHandle **curl) /* use fread as default function to read input */ data->set.fread = (curl_read_callback)fread; - /* set the default passwd function */ - data->set.fpasswd = my_getpass; - data->set.infilesize = -1; /* we don't know any size */ data->state.current_speed = -1; /* init to negative == impossible */ @@ -949,25 +931,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.progress_client = va_arg(param, void *); break; - case CURLOPT_PASSWDFUNCTION: - /* - * Password prompt callback - */ - data->set.fpasswd = va_arg(param, curl_passwd_callback); - /* - * if the callback provided is null, reset the default callback - */ - if(!data->set.fpasswd) - { - data->set.fpasswd = my_getpass; - } - break; - case CURLOPT_PASSWDDATA: - /* - * Custom client data to pass to the password callback - */ - data->set.passwd_client = va_arg(param, void *); - break; case CURLOPT_PROXYUSERPWD: /* * user:password needed to use the proxy @@ -1936,8 +1899,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, char endbracket; char user[MAX_CURL_USER_LENGTH]; char passwd[MAX_CURL_PASSWORD_LENGTH]; - bool passwdgiven=FALSE; /* set TRUE if an application-provided password has - been set */ int rc; #ifdef HAVE_SIGACTION @@ -2157,32 +2118,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->bits.proxy_user_passwd) { char proxyuser[MAX_CURL_USER_LENGTH]=""; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - passwdgiven = FALSE; - - if(*data->set.proxyuserpwd != ':') { - /* the name is given, get user+password */ - sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]", - proxyuser, proxypasswd); - if(strchr(data->set.proxyuserpwd, ':')) - /* a colon means the password was given, even if blank */ - passwdgiven = TRUE; - } - else { - /* no name given, get the password only */ - sscanf(data->set.proxyuserpwd+1, "%127[^\n]", proxypasswd); - passwdgiven = TRUE; - } - /* check for password, if no ask for one */ - if( !proxypasswd[0] && !passwdgiven) { - if(data->set.fpasswd( data->set.passwd_client, - "proxy password:", - proxypasswd, - sizeof(proxypasswd))) { - failf(data, "Bad password from password callback"); - return CURLE_BAD_PASSWORD_ENTERED; - } - } + sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]", + proxyuser, proxypasswd); conn->proxyuser = strdup(proxyuser); if(!conn->proxyuser) @@ -2728,7 +2666,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, user[0] =0; /* to make everything well-defined */ passwd[0]=0; - passwdgiven = FALSE; /* none given so far */ if (conn->protocol & (PROT_FTP|PROT_HTTP)) { /* This is a FTP or HTTP URL, we will now try to extract the possible @@ -2777,9 +2714,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, strcpy(passwd, newpasswd); } free(newpasswd); - - /* we have set the password */ - passwdgiven = TRUE; } } } @@ -2795,47 +2729,24 @@ static CURLcode CreateConnection(struct SessionHandle *data, * so it doesn't have to be set in this block */ if (data->set.userpwd != NULL) { - if(*data->set.userpwd != ':') { - /* the name is given, get user+password */ - sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", - user, passwd); - if(strchr(data->set.userpwd, ':')) - /* a colon means the password was given, even if blank */ - passwdgiven = TRUE; - } - else - /* no name given, starts with a colon, get the password only */ - sscanf(data->set.userpwd+1, "%127[^\n]", passwd); + /* the name is given, get user+password */ + sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", + user, passwd); } - if ((data->set.use_netrc != CURL_NETRC_IGNORED) && - !passwdgiven) { /* need passwd */ + if (data->set.use_netrc != CURL_NETRC_IGNORED) { if(Curl_parsenetrc(conn->hostname, - user, - passwd)) { + user, passwd)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } - else { + else conn->bits.user_passwd = 1; /* enable user+password */ - passwdgiven = TRUE; - } - } - - /* if we have a user but no password, ask for one */ - if(conn->bits.user_passwd && !passwdgiven ) { - if(data->set.fpasswd(data->set.passwd_client, - "password:", passwd, - sizeof(passwd))) - return CURLE_BAD_PASSWORD_ENTERED; } - /* So we could have a password but no user; that's just too bad. */ - /* If our protocol needs a password and we have none, use the defaults */ if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && - !conn->bits.user_passwd && - !passwdgiven) { + !conn->bits.user_passwd) { strcpy(user, CURL_DEFAULT_USER); strcpy(passwd, CURL_DEFAULT_PASSWORD); -- cgit v1.2.1 From 679654bd47b401a1463bbaefac097d1212ea2ba9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Oct 2003 09:28:00 +0000 Subject: o the name and password arrays are 256 bytes, so let's accept that lengthy input o have ->passwd and ->name be NULL if no name/passwd was given o only set default user+password for FTP if no userpwd was given --- lib/url.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7271af1da..b4cfc798e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2119,7 +2119,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, char proxyuser[MAX_CURL_USER_LENGTH]=""; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]", + sscanf(data->set.proxyuserpwd, + "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", proxyuser, proxypasswd); conn->proxyuser = strdup(proxyuser); @@ -2730,7 +2732,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ if (data->set.userpwd != NULL) { /* the name is given, get user+password */ - sscanf(data->set.userpwd, "%127[^:]:%127[^\n]", + sscanf(data->set.userpwd, + "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", user, passwd); } @@ -2745,18 +2749,19 @@ static CURLcode CreateConnection(struct SessionHandle *data, } /* If our protocol needs a password and we have none, use the defaults */ - if ( (conn->protocol & (PROT_FTP|PROT_HTTP)) && + if ( (conn->protocol & PROT_FTP) && !conn->bits.user_passwd) { - strcpy(user, CURL_DEFAULT_USER); - strcpy(passwd, CURL_DEFAULT_PASSWORD); + conn->user = strdup(CURL_DEFAULT_USER); + conn->passwd = strdup(CURL_DEFAULT_PASSWORD); /* This is the default password, so DON'T set conn->bits.user_passwd */ } - - /* store user + password */ - conn->user = strdup(user); - conn->passwd = strdup(passwd); + else { + /* store user + password */ + conn->user = user[0]?strdup(user):NULL; + conn->passwd = passwd[0]?strdup(passwd):NULL; + } /************************************************************* * Check the current list of connections to see if we can @@ -2817,8 +2822,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, otherwise */ conn->maxdownload = -1; /* might have been used previously! */ - free(old_conn->user); - free(old_conn->passwd); + Curl_safefree(old_conn->user); + Curl_safefree(old_conn->passwd); Curl_safefree(old_conn->proxyuser); Curl_safefree(old_conn->proxypasswd); -- cgit v1.2.1 From ce5db9a86ea1508b0caaeec38adc5397e390dc3e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Oct 2003 13:11:00 +0000 Subject: Dominick Meglio implemented CURLOPT_MAXFILESIZE and --max-filesize. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b4cfc798e..0d07e686d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1238,6 +1238,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.http200aliases = va_arg(param, struct curl_slist *); break; + case CURLOPT_MAXFILESIZE: + /* + * Set the maximum size of a file to download. + */ + data->set.max_filesize = va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 65dab79ca58cd95dc8741399a6ed7b8c21c606d3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 18 Oct 2003 20:14:33 +0000 Subject: gcc -Wshadow complaints fixed --- lib/url.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0d07e686d..e6451f242 100644 --- a/lib/url.c +++ b/lib/url.c @@ -157,10 +157,10 @@ static bool safe_strequal(char* str1, char* str2); extern sigjmp_buf curl_jmpenv; #endif static -RETSIGTYPE alarmfunc(int signal) +RETSIGTYPE alarmfunc(int sig) { /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ - (void)signal; + (void)sig; #ifdef HAVE_SIGSETJMP siglongjmp(curl_jmpenv, 1); #endif @@ -2248,8 +2248,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(proxy && *proxy) { /* we have a proxy here to set */ char *ptr; - char user[MAX_CURL_USER_LENGTH]; - char passwd[MAX_CURL_PASSWORD_LENGTH]; + char proxyuser[MAX_CURL_USER_LENGTH]; + char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; /* skip the possible protocol piece */ ptr=strstr(proxy, "://"); @@ -2262,16 +2262,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, ptr = strchr(ptr, '@'); if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - user, passwd))) { + proxyuser, proxypasswd))) { /* found user and password, rip them out */ Curl_safefree(conn->proxyuser); - conn->proxyuser = strdup(user); + conn->proxyuser = strdup(proxyuser); if(!conn->proxyuser) return CURLE_OUT_OF_MEMORY; Curl_safefree(conn->proxypasswd); - conn->proxypasswd = strdup(passwd); + conn->proxypasswd = strdup(proxypasswd); if(!conn->proxypasswd) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From d1c08e1d8526c200a300f3d20b49778aba3ff7dd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Oct 2003 06:34:15 +0000 Subject: conn->user and conn->passwd will now always be set to point to something. If not user or password is set, they will point to a "" string. --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e6451f242..62a4148c7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2765,9 +2765,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* This is the default password, so DON'T set conn->bits.user_passwd */ } else { - /* store user + password */ - conn->user = user[0]?strdup(user):NULL; - conn->passwd = passwd[0]?strdup(passwd):NULL; + /* store user + password, zero-length if not set */ + conn->user = strdup(user); + conn->passwd = strdup(passwd); } /************************************************************* -- cgit v1.2.1 From 1cdc66d927e6476f422ad3266c34ab766b1260ea Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 28 Oct 2003 09:17:15 +0000 Subject: overlapping memory chunks with strcpy(), detected by the friendly valgrind --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 62a4148c7..ac2b6be96 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2035,7 +2035,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, used truly as a separator */ ptr++; - strcpy(conn->path, ptr); + /* This cannot be made with strcpy, as the memory chunks overlap! */ + memmove(conn->path, ptr, strlen(ptr)+1); } } -- cgit v1.2.1 From e9c835ad06bdded6a720ad59054a7b058ace4d9c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Oct 2003 09:53:21 +0000 Subject: David Hull made the file: URL parser also accept the somewhat sloppy file syntax: file:/path. I added test case 203 to verify this. --- lib/url.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ac2b6be96..5da898c59 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2002,9 +2002,19 @@ static CURLcode CreateConnection(struct SessionHandle *data, * proxy -- and we don't know if we will need to use SSL until we parse the * url ... ************************************************************/ - if((2 == sscanf(data->change.url, "%64[^:]://%[^\n]", + if((2 == sscanf(data->change.url, "%64[^:]:%[^\n]", conn->protostr, conn->path)) && strequal(conn->protostr, "file")) { + if(conn->path[0] == '/' && conn->path[1] == '/') { + /* Allow omitted hostname (e.g. file:/). This is not strictly + * speaking a valid file: URL by RFC 1738, but treating file:/ as + * file://localhost/ is similar to how other schemes treat missing + * hostnames. See RFC 1808. */ + + /* This cannot be done with strcpy() in a portable manner, since the + memory areas overlap! */ + memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1); + } /* * we deal with file:/// differently since it supports no * hostname other than "localhost" and "127.0.0.1", which is unique among -- cgit v1.2.1 From ad77f760cf8223548cd214b361591dfde5443dea Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Nov 2003 14:30:43 +0000 Subject: Added CURLOPT_NETRC_FILE. --- lib/url.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5da898c59..6b0d19170 100644 --- a/lib/url.c +++ b/lib/url.c @@ -507,6 +507,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.use_netrc = va_arg(param, long); break; + case CURLOPT_NETRC_FILE: + /* + * Use this file instead of the $HOME/.netrc file + */ + data->set.netrc_file = va_arg(param, char *); + break; case CURLOPT_FOLLOWLOCATION: /* * Follow Location: header hints on a HTTP-server. @@ -2758,7 +2764,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (data->set.use_netrc != CURL_NETRC_IGNORED) { if(Curl_parsenetrc(conn->hostname, - user, passwd)) { + user, passwd, + data->set.netrc_file)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults", conn->hostname); } -- cgit v1.2.1 From 7bee4140e886773a370b76eec80a264c0e7f142d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 19 Nov 2003 14:35:40 +0000 Subject: respect bits.close even if an error already is set, but make sure that the existing error is the one returned back --- lib/url.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6b0d19170..2ee6c0722 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3236,9 +3236,15 @@ CURLcode Curl_done(struct connectdata *conn) 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->set.reuse_forbid || - ((CURLE_OK == result) && conn->bits.close)) - result = Curl_disconnect(conn); /* close the connection */ + if(data->set.reuse_forbid || conn->bits.close) { + CURLcode res2; + res2 = Curl_disconnect(conn); /* close the connection */ + + /* If we had an error already, make sure we return that one. But + if we got a new error, return that. */ + if(!result && res2) + result = res2; + } else infof(data, "Connection #%d left intact\n", conn->connectindex); -- cgit v1.2.1 From af9dc9f12808e92f089b2dff80469ce08c0a1274 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 Nov 2003 07:10:02 +0000 Subject: Gaz Iqbal fixed a range string memory leak! --- lib/url.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2ee6c0722..794cfab9f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2852,6 +2852,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, Curl_safefree(old_conn->proxyuser); Curl_safefree(old_conn->proxypasswd); + if(old_conn->bits.rangestringalloc) + free(old_conn->range); + free(old_conn); /* we don't need this anymore */ /* @@ -2860,14 +2863,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ 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) - free(conn->range); - - /* tell ourselves to fetch this range */ - conn->range = strdup(resumerange); - conn->bits.use_range = TRUE; /* enable range download */ - conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ + snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from); + if (conn->bits.rangestringalloc == TRUE) + free(conn->range); + + /* tell ourselves to fetch this range */ + conn->range = strdup(resumerange); + conn->bits.use_range = TRUE; /* enable range download */ + conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ } else if (data->set.set_range) { /* There is a range, but is not a resume, useful for random ftp access */ -- cgit v1.2.1 From 1e98727c552ced5f8c7587f64ab69c6eaab743dd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 Nov 2003 07:15:37 +0000 Subject: FTPS support added as RFC2228 and the murray-ftp-auth-ssl draft describe it --- lib/url.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 794cfab9f..69de6f8a0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1251,6 +1251,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.max_filesize = va_arg(param, long); break; + case CURLOPT_FTP_SSL: + /* + * Make FTP transfers attempt to use SSL/TLS. + */ + data->set.ftp_ssl = va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ @@ -1293,16 +1300,13 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->proto.generic); Curl_safefree(conn->newurl); Curl_safefree(conn->path); /* the URL path part */ - -#ifdef USE_SSLEAY Curl_SSL_Close(conn); -#endif /* USE_SSLEAY */ /* close possibly still open sockets */ - if(-1 != conn->secondarysocket) - sclose(conn->secondarysocket); - if(-1 != conn->firstsocket) - sclose(conn->firstsocket); + if(-1 != conn->sock[SECONDARYSOCKET]) + sclose(conn->sock[SECONDARYSOCKET]); + if(-1 != conn->sock[FIRSTSOCKET]) + sclose(conn->sock[FIRSTSOCKET]); Curl_safefree(conn->user); Curl_safefree(conn->passwd); @@ -1429,7 +1433,7 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - bool dead = SocketIsDead(check->firstsocket); + bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); if(dead) { /* */ @@ -1549,16 +1553,15 @@ ConnectionStore(struct SessionHandle *data, * This function logs in to a SOCKS5 proxy and sends the specifies the final * desitination server. */ -static int handleSock5Proxy( - const char *proxy_name, - const char *proxy_password, - struct connectdata *conn, - int sock) +static int handleSock5Proxy(const char *proxy_name, + const char *proxy_password, + struct connectdata *conn) { unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ ssize_t actualread; ssize_t written; CURLcode result; + int sock = conn->sock[FIRSTSOCKET]; Curl_nonblock(sock, FALSE); @@ -1754,7 +1757,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, result= Curl_connecthost(conn, hostaddr, conn->port, - &conn->firstsocket, + &conn->sock[FIRSTSOCKET], &addr, connected); if(CURLE_OK == result) { @@ -1776,8 +1779,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { return handleSock5Proxy(conn->proxyuser, conn->proxypasswd, - conn, - conn->firstsocket) ? + conn) ? CURLE_COULDNT_CONNECT : CURLE_OK; } else if (conn->data->set.proxytype == CURLPROXY_HTTP) { @@ -1953,8 +1955,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* and we setup a few fields in case we end up actually using this struct */ conn->data = data; /* remember our daddy */ - conn->firstsocket = -1; /* no file descriptor */ - conn->secondarysocket = -1; /* no file descriptor */ + conn->sock[FIRSTSOCKET] = -1; /* no file descriptor */ + conn->sock[SECONDARYSOCKET] = -1; /* no file descriptor */ conn->connectindex = -1; /* no index */ conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && (data->set.proxytype == CURLPROXY_HTTP))? @@ -2419,6 +2421,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(strequal(conn->protostr, "FTPS")) { #ifdef USE_SSLEAY conn->protocol |= PROT_FTPS|PROT_SSL; + conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */ #else failf(data, LIBCURL_NAME " was built with SSL disabled, ftps: not supported!"); @@ -3100,7 +3103,7 @@ static CURLcode SetupConnection(struct connectdata *conn, conn->bytecount = 0; conn->headerbytecount = 0; - if(-1 == conn->firstsocket) { + if(-1 == conn->sock[FIRSTSOCKET]) { bool connected; /* Connect only if not already connected! */ -- cgit v1.2.1 From d1d417664ec5983265eabcab128628632d5a4a43 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Dec 2003 06:25:41 +0000 Subject: Gisle Vanem fixed the check-order for FTPS and FTP. --- lib/url.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 69de6f8a0..b703d18f8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2094,10 +2094,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Note: if you add a new protocol, please update the list in * lib/version.c too! */ - if(checkprefix("FTP", conn->gname)) { - strcpy(conn->protostr, "ftp"); - } - else if(checkprefix("GOPHER", conn->gname)) + if(checkprefix("GOPHER", conn->gname)) strcpy(conn->protostr, "gopher"); #ifdef USE_SSLEAY else if(checkprefix("HTTPS", conn->gname)) @@ -2105,6 +2102,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, else if(checkprefix("FTPS", conn->gname)) strcpy(conn->protostr, "ftps"); #endif /* USE_SSLEAY */ + else if(checkprefix("FTP", conn->gname)) + strcpy(conn->protostr, "ftp"); else if(checkprefix("TELNET", conn->gname)) strcpy(conn->protostr, "telnet"); else if (checkprefix("DICT", conn->gname)) -- cgit v1.2.1 From 800052dc50ace9748f607afc8f451afac948736b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Dec 2003 13:27:29 +0000 Subject: use the HAVE_KRB4 define instead of just KRB4 --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b703d18f8..0dcc577af 100644 --- a/lib/url.c +++ b/lib/url.c @@ -127,7 +127,7 @@ #define _MPRINTF_REPLACE /* use our functions only */ #include -#ifdef KRB4 +#ifdef HAVE_KRB4 #include "security.h" #endif -- cgit v1.2.1 From 50e7545118dca4bb456d7c8120ac8f2f4c5bf6f5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 15 Dec 2003 14:48:37 +0000 Subject: Giuseppe Attardi fixed a really tricky bug --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0dcc577af..d21cab247 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3281,6 +3281,9 @@ CURLcode Curl_do(struct connectdata **connp) conn->bits.close = TRUE; /* enforce close of this connetion */ result = Curl_done(conn); /* we are so done with this */ + + /* conn is no longer a good pointer */ + if(CURLE_OK == result) { bool async; /* Now, redo the connect and get a new connection */ @@ -3288,6 +3291,7 @@ CURLcode Curl_do(struct connectdata **connp) if(CURLE_OK == result) { /* We have connected or sent away a name resolve query fine */ + conn = *connp; /* setup conn to again point to something nice */ if(async) { /* Now, if async is TRUE here, we need to wait for the name to resolve */ -- cgit v1.2.1 From 3788f25eacbf4fcf20b04f1e74ea735b8b9b1396 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 15 Dec 2003 17:33:49 +0000 Subject: added a library-wide interface for doing dns cache pruning, and no longer make the pruning at each name lookup, only in Curl_done(). --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d21cab247..417121cb3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3227,6 +3227,8 @@ CURLcode Curl_done(struct connectdata *conn) NULL, Curl_scan_cache_used); #endif + Curl_hostcache_prune(data); /* kill old DNS cache entries */ + /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) result = conn->curl_done(conn); -- cgit v1.2.1 From 8146d463861d229412a9c253fadb011a5852e8ce Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Dec 2003 08:03:15 +0000 Subject: Gisle Vanem's minor fixes --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 417121cb3..1584f9199 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2768,7 +2768,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(Curl_parsenetrc(conn->hostname, user, passwd, data->set.netrc_file)) { - infof(data, "Couldn't find host %s in the .netrc file, using defaults", + infof(data, "Couldn't find host %s in the .netrc file, using defaults\n", conn->hostname); } else @@ -3281,7 +3281,7 @@ CURLcode Curl_do(struct connectdata **connp) infof(data, "Re-used connection seems dead, get a new one\n"); - conn->bits.close = TRUE; /* enforce close of this connetion */ + conn->bits.close = TRUE; /* enforce close of this connection */ result = Curl_done(conn); /* we are so done with this */ /* conn is no longer a good pointer */ -- cgit v1.2.1 From 84b3c3b569b1ddf3c8d71b2dfa6660a5fd0fff5d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Dec 2003 08:10:09 +0000 Subject: Make setopt() support CURLOPT_IPRESOLVE... --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1584f9199..cd8ce5fdd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1258,6 +1258,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ftp_ssl = va_arg(param, long); break; + case CURLOPT_IPRESOLVE: + data->set.ip_version = va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From b60e0fa97ed7ddc66d0ad6d00dfd78319bb6ad36 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Jan 2004 22:29:29 +0000 Subject: David J Meyer's large file support. --- lib/url.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cd8ce5fdd..a01eab0b1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -711,6 +711,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.infilesize = va_arg(param, long); break; + case CURLOPT_INFILESIZE_LARGE: + /* + * If known, this should inform curl about the file size of the + * to-be-uploaded file. + */ + data->set.infilesize = va_arg(param, off_t); + break; case CURLOPT_LOW_SPEED_LIMIT: /* * The low speed limit that if transfers are below this for @@ -955,6 +962,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.set_resume_from = va_arg(param, long); break; + case CURLOPT_RESUME_FROM_LARGE: + /* + * Resume transfer at the give file position + */ + data->set.set_resume_from = va_arg(param, off_t); + break; case CURLOPT_DEBUGFUNCTION: /* * stderr write callback. @@ -1262,6 +1275,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ip_version = va_arg(param, long); break; + case CURLOPT_MAXFILESIZE_LARGE: + /* + * Set the maximum size of a file to download. + */ + data->set.max_filesize = va_arg(param, off_t); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ @@ -2348,7 +2368,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->resume_from) { if(!conn->bits.use_range) { /* if it already was in use, we just skip this */ - snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from); + snprintf(resumerange, sizeof(resumerange), "%Od-", + conn->resume_from); conn->range=strdup(resumerange); /* tell ourselves to fetch this range */ conn->bits.rangestringalloc = TRUE; /* mark as allocated */ conn->bits.use_range = 1; /* switch on range usage */ @@ -2869,7 +2890,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ conn->resume_from = data->set.set_resume_from; if (conn->resume_from) { - snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from); + snprintf(resumerange, sizeof(resumerange), "%Od-", + conn->resume_from); if (conn->bits.rangestringalloc == TRUE) free(conn->range); -- cgit v1.2.1 From 053f6c85efd0bf698f73343989474d672d0563a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Jan 2004 09:19:33 +0000 Subject: updated year in the copyright string --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a01eab0b1..aee9e16d2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From c8ac7a0d95178ce7852764005de1e1d350791ab0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 11 Jan 2004 22:56:36 +0000 Subject: Dominick Meglio pointed out FTPS should use default port 990 according to IANA. --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index aee9e16d2..4b71e070f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2441,11 +2441,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* MN 06/07/02 */ #ifndef CURL_DISABLE_FTP char *type; + int port = PORT_FTP; if(strequal(conn->protostr, "FTPS")) { #ifdef USE_SSLEAY conn->protocol |= PROT_FTPS|PROT_SSL; conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */ + port = PORT_FTPS; #else failf(data, LIBCURL_NAME " was built with SSL disabled, ftps: not supported!"); @@ -2454,8 +2456,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, } conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_FTP; - conn->remote_port = PORT_FTP; + data->set.use_port:port; + conn->remote_port = port; conn->protocol |= PROT_FTP; if(data->change.proxy && -- cgit v1.2.1 From e5cd0cc402c32e98a5180e66d6635da87bc55262 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 22 Jan 2004 11:54:00 +0000 Subject: use the proper type for formposts, not the deprecated one --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4b71e070f..8533297a4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -682,7 +682,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set to make us do HTTP POST */ - data->set.httppost = va_arg(param, struct HttpPost *); + data->set.httppost = va_arg(param, struct curl_httppost *); if(data->set.httppost) data->set.httpreq = HTTPREQ_POST_FORM; break; -- cgit v1.2.1 From b791e158f0e04a518dea19fdaf0bfbf71b343c64 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 22 Jan 2004 12:45:50 +0000 Subject: use curl_off_t instead of off_t! --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8533297a4..e85af3a1a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -716,7 +716,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * If known, this should inform curl about the file size of the * to-be-uploaded file. */ - data->set.infilesize = va_arg(param, off_t); + data->set.infilesize = va_arg(param, curl_off_t); break; case CURLOPT_LOW_SPEED_LIMIT: /* @@ -966,7 +966,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Resume transfer at the give file position */ - data->set.set_resume_from = va_arg(param, off_t); + data->set.set_resume_from = va_arg(param, curl_off_t); break; case CURLOPT_DEBUGFUNCTION: /* @@ -1279,7 +1279,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set the maximum size of a file to download. */ - data->set.max_filesize = va_arg(param, off_t); + data->set.max_filesize = va_arg(param, curl_off_t); break; default: -- cgit v1.2.1 From 4120b7b0c0f37f6227a1cfc1373ec550ef47f6b2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Jan 2004 08:29:56 +0000 Subject: check the arguments to the socks5 function, as the name and password might be NULL pointers, and if non-NULL if now support zero-length names/passwords --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e85af3a1a..d31417b0a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1590,7 +1590,7 @@ static int handleSock5Proxy(const char *proxy_name, Curl_nonblock(sock, FALSE); socksreq[0] = 5; /* version */ - socksreq[1] = (char)(proxy_name[0] ? 2 : 1); /* number of methods (below) */ + socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */ socksreq[2] = 0; /* no authentication */ socksreq[3] = 2; /* username/password */ @@ -1620,7 +1620,7 @@ static int handleSock5Proxy(const char *proxy_name, int userlen, pwlen, len; userlen = strlen(proxy_name); - pwlen = strlen(proxy_password); + pwlen = proxy_password?strlen(proxy_password):0; /* username/password request looks like * +----+------+----------+------+----------+ -- cgit v1.2.1 From 334c3df09d46dcd167df0d3046b45e4b47fb1328 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Jan 2004 08:36:03 +0000 Subject: Proxy username and password on persistant connections could easily get messed up. Vincent Bronner detected this. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d31417b0a..022c151c8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2853,7 +2853,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* get the user+password information from the old_conn struct since it may * be new for this request even when we re-use an existing connection */ conn->bits.user_passwd = old_conn->bits.user_passwd; - conn->bits.proxy_user_passwd = conn->bits.proxy_user_passwd; + conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; /* 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 */ -- cgit v1.2.1 From 2465ff991fb9c4291c30cb8a3dd61c14fd90d7c5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Jan 2004 16:16:44 +0000 Subject: when saving in a cookie jar fails, include the file name in the error message to make it easier to track down --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 022c151c8..fc7eb962d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -216,7 +216,8 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->set.cookiejar) { /* we have a "destination" for all the cookies to get dumped to */ if(Curl_cookie_output(data->cookies, data->set.cookiejar)) - infof(data, "WARNING: failed to save cookies in given jar\n"); + infof(data, "WARNING: failed to save cookies in %s\n", + data->set.cookiejar); } if( !data->share || (data->cookies != data->share->cookies) ) { -- cgit v1.2.1 From 580a2fe72bbeaa8de2cf8c25af7928636c347466 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Feb 2004 10:13:54 +0000 Subject: when including ca-bundle.h, don't look in the current dir first, simply use the search path since we want the build-version rather than the one in the source dir --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fc7eb962d..9d0b9e97d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -116,7 +116,7 @@ #include "ldap.h" #include "url.h" #include "connect.h" -#include "ca-bundle.h" +#include #include -- cgit v1.2.1 From f71139750d165dc2b60b7c3584bfd332af6b9231 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 Feb 2004 09:38:56 +0000 Subject: options we get as longs need to be typecasted when assigned to prevent picky compiler warnings --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9d0b9e97d..32333f6be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -506,7 +506,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Parse the $HOME/.netrc file */ - data->set.use_netrc = va_arg(param, long); + data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long); break; case CURLOPT_NETRC_FILE: /* @@ -557,7 +557,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Set HTTP time condition. This must be one of the defines in the * curl/curl.h header file. */ - data->set.timecondition = va_arg(param, long); + data->set.timecondition = (curl_TimeCond)va_arg(param, long); break; case CURLOPT_TIMEVALUE: /* @@ -1070,10 +1070,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } } } + break; #else return CURLE_SSL_ENGINE_NOTFOUND; #endif - break; case CURLOPT_SSLENGINE_DEFAULT: /* * flag to set engine as default. @@ -1241,7 +1241,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set proxy type. HTTP/SOCKS4/SOCKS5 */ - data->set.proxytype = va_arg(param, long); + data->set.proxytype = (curl_proxytype)va_arg(param, long); break; case CURLOPT_PRIVATE: @@ -1269,7 +1269,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Make FTP transfers attempt to use SSL/TLS. */ - data->set.ftp_ssl = va_arg(param, long); + data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long); break; case CURLOPT_IPRESOLVE: -- cgit v1.2.1 From 50efb8f33e379177e9d40ba05fa3d0d31b5249b7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Feb 2004 21:11:08 +0000 Subject: #if-check for SIGALRM before assuming it is present --- lib/url.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 32333f6be..bea5a3e0c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2952,6 +2952,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Store the old value to be able to set it back later! *************************************************************/ +#ifdef SIGALRM #ifdef HAVE_SIGACTION struct sigaction sigact; sigaction(SIGALRM, NULL, &sigact); @@ -2964,12 +2965,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif /* now set the new struct */ sigaction(SIGALRM, &sigact, NULL); -#else +#else /* HAVE_SIGACTION */ /* no sigaction(), revert to the much lamer signal() */ #ifdef HAVE_SIGNAL keep_sigact = signal(SIGALRM, alarmfunc); #endif -#endif +#endif /* HAVE_SIGACTION */ /* We set the timeout on the name resolving phase first, separately from * the download/upload part to allow a maximum time on everything. This is @@ -2986,8 +2987,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, recently set in the beginning of this function and nothing slow has been done since then until now. */ #endif +#endif /* SIGALRM */ } -#endif +#endif /* USE_ARES */ /************************************************************* * Resolve the name of the server or proxy @@ -3031,7 +3033,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } *addr = hostaddr; -#ifdef HAVE_ALARM +#if defined(HAVE_ALARM) && defined(SIGALRM) if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { #ifdef HAVE_SIGACTION if(keep_copysig) { @@ -3044,7 +3046,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* restore the previous SIGALRM handler */ signal(SIGALRM, keep_sigact); #endif -#endif +#endif /* HAVE_SIGACTION */ + /* switch back the alarm() to either zero or to what it was before minus the time we spent until now! */ if(prev_alarm) { @@ -3091,24 +3094,6 @@ static CURLcode SetupConnection(struct connectdata *conn, a file:// transfer */ return result; - /************************************************************* - * Proxy authentication - *************************************************************/ -#if 0 /* This code is not needed anymore (moved to http.c) */ - if(conn->bits.proxy_user_passwd) { - char *authorization; - snprintf(data->state.buffer, BUFSIZE, "%s:%s", - conn->proxyuser, conn->proxypasswd); - if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer), - &authorization) >= 0) { - Curl_safefree(conn->allocptr.proxyuserpwd); - conn->allocptr.proxyuserpwd = - aprintf("Proxy-authorization: Basic %s\015\012", authorization); - free(authorization); - } - } -#endif - /************************************************************* * Send user-agent to HTTP proxies even if the target protocol * isn't HTTP. -- cgit v1.2.1 From d57eed6f22f7eb202a942895d968f4af87b7cae0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 12 Feb 2004 09:48:27 +0000 Subject: No longer receive the return code in ConnectionKillOne() that wasn't dealt with anyway and thus caused picky compiler to warn. --- lib/url.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bea5a3e0c..c5379c985 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1491,7 +1491,6 @@ ConnectionKillOne(struct SessionHandle *data) int highscore=-1; int connindex=-1; int score; - CURLcode result; struct timeval now; now = Curl_tvnow(); @@ -1531,7 +1530,7 @@ ConnectionKillOne(struct SessionHandle *data) if(connindex >= 0) { /* the winner gets the honour of being disconnected */ - result = Curl_disconnect(data->state.connects[connindex]); + (void) Curl_disconnect(data->state.connects[connindex]); /* clean the array entry */ data->state.connects[connindex] = NULL; -- cgit v1.2.1 From 7abf2f44ec58eece7c200c54d7e5c76bf43354e2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 13 Feb 2004 12:42:37 +0000 Subject: in the socks code, make sure we receive Curl_read results in ints and Curl_write in CURLcode, to keep the picky compilers happy --- lib/url.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c5379c985..2f2b165b7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1584,7 +1584,8 @@ static int handleSock5Proxy(const char *proxy_name, unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ ssize_t actualread; ssize_t written; - CURLcode result; + int result; + CURLcode code; int sock = conn->sock[FIRSTSOCKET]; Curl_nonblock(sock, FALSE); @@ -1594,9 +1595,9 @@ static int handleSock5Proxy(const char *proxy_name, socksreq[2] = 0; /* no authentication */ socksreq[3] = 2; /* username/password */ - result = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), + code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), &written); - if ((result != CURLE_OK) || (written != (2 + (int)socksreq[1]))) { + if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) { failf(conn->data, "Unable to send initial SOCKS5 request."); return 1; } @@ -1638,8 +1639,8 @@ static int handleSock5Proxy(const char *proxy_name, memcpy(socksreq + len, proxy_password, (int) pwlen); len += pwlen; - result = Curl_write(conn, sock, (char *)socksreq, len, &written); - if ((result != CURLE_OK) || (len != written)) { + code = Curl_write(conn, sock, (char *)socksreq, len, &written); + if ((code != CURLE_OK) || (len != written)) { failf(conn->data, "Failed to send SOCKS5 sub-negotiation request."); return 1; } @@ -1698,7 +1699,7 @@ static int handleSock5Proxy(const char *proxy_name, int rc = Curl_resolv(conn, conn->hostname, conn->remote_port, &dns); if(rc == -1) - return CURLE_COULDNT_RESOLVE_HOST; + return 1; if(rc == 1) /* this requires that we're in "wait for resolve" state */ @@ -1736,8 +1737,8 @@ static int handleSock5Proxy(const char *proxy_name, { const int packetsize = 10; - result = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); - if ((result != CURLE_OK) || (written != packetsize)) { + code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); + if ((code != CURLE_OK) || (written != packetsize)) { failf(conn->data, "Failed to send SOCKS5 connect request."); return 1; } -- cgit v1.2.1 From e4916145ef9743b0f417fbec86888f29b5622276 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 16 Feb 2004 07:33:30 +0000 Subject: Jeff Lawson pointed out that we need to check for a '5' in the version field to properly work with SOCKS5 proxies. I also included some ascii art describing the SOCKS5 response, as RFC1928 describes. Jeff provided details in bug report #741841 and here: http://curl.haxx.se/mail/lib-2004-02/0181.html --- lib/url.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2f2b165b7..188263b61 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1581,6 +1581,23 @@ static int handleSock5Proxy(const char *proxy_name, const char *proxy_password, struct connectdata *conn) { + /* + According to the RFC1928, section "6. Replies". This is what a SOCK5 + replies: + + +----+-----+-------+------+----------+----------+ + |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | + +----+-----+-------+------+----------+----------+ + | 1 | 1 | X'00' | 1 | Variable | 2 | + +----+-----+-------+------+----------+----------+ + + Where: + + o VER protocol version: X'05' + o REP Reply field: + o X'00' succeeded + */ + unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ ssize_t actualread; ssize_t written; @@ -1651,7 +1668,7 @@ static int handleSock5Proxy(const char *proxy_name, return 1; } - if ((socksreq[0] != 1) || /* version */ + if ((socksreq[0] != 5) || /* version */ (socksreq[1] != 0)) { /* status */ failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); -- cgit v1.2.1 From 39926181ea02fa391c7c4b7c27a13de199ca8170 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 16 Feb 2004 13:14:55 +0000 Subject: Fix verbosconnect() when ipv6-enabled to not assume that conn->serv_addr is a valid pointer, but instead always depend on the passed-in dns pointer. This happens to be NULL when the connection is re-used... --- lib/url.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 188263b61..aa15ec009 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1849,26 +1849,36 @@ static void verboseconnect(struct connectdata *conn, /* Figure out the ip-number and display the first host name it shows: */ #ifdef ENABLE_IPV6 - (void)dns; /* not used in the IPv6 enabled version */ { char hbuf[NI_MAXHOST]; #ifdef NI_WITHSCOPEID - const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; +#define NIFLAGS NI_NUMERICHOST | NI_WITHSCOPEID #else - const int niflags = NI_NUMERICHOST; +#define NIFLAGS NI_NUMERICHOST #endif - struct addrinfo *ai = conn->serv_addr; - - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, - niflags)) { - snprintf(hbuf, sizeof(hbuf), "?"); + if(dns) { + struct addrinfo *ai = dns->addr; + + /* Lookup the name of the given address. This should probably be remade + to use the DNS cache instead, as the host name is most likely cached + already. */ + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, + NIFLAGS)) { + snprintf(hbuf, sizeof(hbuf), "unknown"); + } + else { + if (ai->ai_canonname) { + infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf, + conn->port); + return; + } + } } - if (ai->ai_canonname) { - infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf, - conn->port); - } else { - infof(data, "Connected to %s port %d\n", hbuf, conn->port); + else { + snprintf(hbuf, sizeof(hbuf), "same host"); } + + infof(data, "Connected to %s port %d\n", hbuf, conn->port); } #else { -- cgit v1.2.1 From ccdaa0b51f8f2343dd038b59dc054b086a72f345 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 16 Feb 2004 15:24:22 +0000 Subject: Make the 'areschannel' get created in the curl_easy_init() and re-use that same channel during the whole curl handle's life until curl_easy_cleanup(). --- lib/url.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index aa15ec009..f9181fe60 100644 --- a/lib/url.c +++ b/lib/url.c @@ -233,6 +233,11 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_digest_cleanup(data); +#ifdef USE_ARES + /* this destroys the channel and we cannot use it anymore after this */ + ares_destroy(data->state.areschannel); +#endif + /* No longer a dirty share, if it exists */ if (data->share) data->share->dirty--; @@ -253,6 +258,15 @@ CURLcode Curl_open(struct SessionHandle **curl) memset(data, 0, sizeof(struct SessionHandle)); +#ifdef USE_ARES + if(ARES_SUCCESS != ares_init(&data->state.areschannel)) { + free(data); + return CURLE_FAILED_INIT; + } + /* make sure that all other returns from this function should destroy the + ares channel before returning error! */ +#endif + /* We do some initial setup here, all those fields that can't be just 0 */ data->state.headerbuff=(char*)malloc(HEADERSIZE); @@ -319,7 +333,6 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; #endif - memset(data->state.connects, 0, sizeof(struct connectdata *)*data->state.numconnects); -- cgit v1.2.1 From 0ffec4272ad7da91ca6b3e97d60c82ba517c4614 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 22 Feb 2004 22:31:24 +0000 Subject: the missing part of Gisle Vanem's connect-timeout fix for win32 --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f9181fe60..78c25aebc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1360,9 +1360,10 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->proxyhost); -#ifdef USE_ARES +#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) /* possible left-overs from the async name resolve */ Curl_safefree(conn->async.hostname); + Curl_safefree(conn->async.os_specific); #endif Curl_free_ssl_config(&conn->ssl_config); @@ -3238,7 +3239,7 @@ CURLcode Curl_connect(struct SessionHandle *data, then a successful name resolve has been received */ CURLcode Curl_async_resolved(struct connectdata *conn) { -#ifdef USE_ARES +#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) CURLcode code = SetupConnection(conn, conn->async.dns); if(code) -- cgit v1.2.1 From 82bd583251251f59ada527f4d5197a021676685a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 1 Mar 2004 07:19:26 +0000 Subject: in Curl_disonnect(): call the protocol-specific disconnect function before we unlink the "current" connection struct from the connection cache. --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 78c25aebc..e9dc7a02b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1325,16 +1325,16 @@ CURLcode Curl_disconnect(struct connectdata *conn) we shall forget. */ conn->data->state.authstage = 0; + if(conn->curl_disconnect) + /* This is set if protocol-specific cleanups should be made */ + conn->curl_disconnect(conn); + if(-1 != conn->connectindex) { /* unlink ourselves! */ infof(conn->data, "Closing connection #%d\n", conn->connectindex); conn->data->state.connects[conn->connectindex] = NULL; } - if(conn->curl_disconnect) - /* This is set if protocol-specific cleanups should be made */ - conn->curl_disconnect(conn); - Curl_safefree(conn->proto.generic); Curl_safefree(conn->newurl); Curl_safefree(conn->path); /* the URL path part */ -- cgit v1.2.1 From 7d2e8728280f797bced37434d54e85ba95f02505 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 1 Mar 2004 09:43:42 +0000 Subject: Only consider the fresh-connection option on the first connection made, not on followed redirections etc. This should fix the bug #905365, which caused NTLM to fail with the option set. --- lib/url.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e9dc7a02b..8755da82e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1981,6 +1981,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, char user[MAX_CURL_USER_LENGTH]; char passwd[MAX_CURL_PASSWORD_LENGTH]; int rc; + bool reuse; #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ @@ -2870,10 +2871,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) return CURLE_OUT_OF_MEMORY; - /* reuse_fresh is set TRUE if we are told to use a fresh connection - by force */ - if(!data->set.reuse_fresh && - ConnectionExists(data, conn, &conn_temp)) { + /* reuse_fresh is TRUE if we are told to use a new connection by force, but + we only acknowledge this option if this is not a re-used connection + already (which happens due to follow-location or during a HTTP + authentication phase). */ + if(data->set.reuse_fresh && !conn->bits.reuse) + reuse = FALSE; + else + reuse = ConnectionExists(data, conn, &conn_temp); + + if(reuse) { /* * We already have a connection for this, we got the former connection * in the conn_temp variable and thus we need to cleanup the one we -- cgit v1.2.1 From cb72a80fe06d96c46e69a869cceb16b491fcb23b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 1 Mar 2004 16:28:00 +0000 Subject: Use CURL_FORMAT_OFF_T for printf()inf curl_off_t variables. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8755da82e..b0c12c44f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2411,7 +2411,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->resume_from) { if(!conn->bits.use_range) { /* if it already was in use, we just skip this */ - snprintf(resumerange, sizeof(resumerange), "%Od-", + snprintf(resumerange, sizeof(resumerange), CURL_FORMAT_OFF_T "-", conn->resume_from); conn->range=strdup(resumerange); /* tell ourselves to fetch this range */ conn->bits.rangestringalloc = TRUE; /* mark as allocated */ @@ -2941,7 +2941,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ conn->resume_from = data->set.set_resume_from; if (conn->resume_from) { - snprintf(resumerange, sizeof(resumerange), "%Od-", + snprintf(resumerange, sizeof(resumerange), CURL_FORMAT_OFF_T "-", conn->resume_from); if (conn->bits.rangestringalloc == TRUE) free(conn->range); -- cgit v1.2.1 From 7ab3b5b3bb4c02dc00621efe13b8d3b29b819250 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Mar 2004 07:25:39 +0000 Subject: use FORMAT_OFF_T instead of CURL_FORMAT_OFF_T to reduce the complexity of having to redef that name --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b0c12c44f..23bddc8df 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2411,7 +2411,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->resume_from) { if(!conn->bits.use_range) { /* if it already was in use, we just skip this */ - snprintf(resumerange, sizeof(resumerange), CURL_FORMAT_OFF_T "-", + snprintf(resumerange, sizeof(resumerange), FORMAT_OFF_T "-", conn->resume_from); conn->range=strdup(resumerange); /* tell ourselves to fetch this range */ conn->bits.rangestringalloc = TRUE; /* mark as allocated */ @@ -2941,7 +2941,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ conn->resume_from = data->set.set_resume_from; if (conn->resume_from) { - snprintf(resumerange, sizeof(resumerange), CURL_FORMAT_OFF_T "-", + snprintf(resumerange, sizeof(resumerange), FORMAT_OFF_T "-", conn->resume_from); if (conn->bits.rangestringalloc == TRUE) free(conn->range); -- cgit v1.2.1 From 353f7641193ddf3f6a42d49d53ea994e4ea4388b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Mar 2004 09:31:18 +0000 Subject: Yet another curl_off_t printf format attempt, we now exclude the %-letter from FORMAT_OFF_T to allow additional options to get specified, like with '"%5" FORMAT_OFF_T'. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 23bddc8df..7620988aa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2411,7 +2411,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->resume_from) { if(!conn->bits.use_range) { /* if it already was in use, we just skip this */ - snprintf(resumerange, sizeof(resumerange), FORMAT_OFF_T "-", + snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-", conn->resume_from); conn->range=strdup(resumerange); /* tell ourselves to fetch this range */ conn->bits.rangestringalloc = TRUE; /* mark as allocated */ @@ -2941,7 +2941,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ conn->resume_from = data->set.set_resume_from; if (conn->resume_from) { - snprintf(resumerange, sizeof(resumerange), FORMAT_OFF_T "-", + snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-", conn->resume_from); if (conn->bits.rangestringalloc == TRUE) free(conn->range); -- cgit v1.2.1 From 7c85be9435538b20eb4924e5ec69fe28bca9bc9e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Mar 2004 14:00:44 +0000 Subject: corrected the reuse_fresh condition --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7620988aa..91ed90460 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2875,7 +2875,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, we only acknowledge this option if this is not a re-used connection already (which happens due to follow-location or during a HTTP authentication phase). */ - if(data->set.reuse_fresh && !conn->bits.reuse) + if(data->set.reuse_fresh && !data->state.this_is_a_follow) reuse = FALSE; else reuse = ConnectionExists(data, conn, &conn_temp); -- cgit v1.2.1 From 59a30e6d9bb205d593ce0fe5bb585a13869636b2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 4 Mar 2004 12:57:12 +0000 Subject: prevent harmless compiler warning --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 91ed90460..e189de5d1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1856,9 +1856,6 @@ static CURLcode ConnectPlease(struct connectdata *conn, static void verboseconnect(struct connectdata *conn, struct Curl_dns_entry *dns) { -#ifdef HAVE_INET_NTOA_R - char ntoa_buf[64]; -#endif struct SessionHandle *data = conn->data; /* Figure out the ip-number and display the first host name it shows: */ @@ -1896,6 +1893,9 @@ static void verboseconnect(struct connectdata *conn, } #else { +#ifdef HAVE_INET_NTOA_R + char ntoa_buf[64]; +#endif Curl_addrinfo *hostaddr=dns?dns->addr:NULL; struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); -- cgit v1.2.1 From 7225b1400236c786add1516e38676d65a7bbd327 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 10 Mar 2004 16:01:47 +0000 Subject: curl_socket_t mistakes cleanup --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e189de5d1..0b06cf5ea 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1378,7 +1378,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) * be dead. Most commonly this happens when the server has closed the * connection due to inactivity. */ -static bool SocketIsDead(int sock) +static bool SocketIsDead(curl_socket_t sock) { int sval; bool ret_val = TRUE; @@ -1386,7 +1386,7 @@ static bool SocketIsDead(int sock) struct timeval to; FD_ZERO(&check_set); - FD_SET(sock,&check_set); + FD_SET(sock, &check_set); to.tv_sec = 0; to.tv_usec = 0; -- cgit v1.2.1 From e545e33d5fd4f021220f09cf8fb05c66db2a4bf4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 11 Mar 2004 13:13:35 +0000 Subject: Gisle Vanem's fixes to use CURL_SOCKET_BAD more instead of -1 for sockets. --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0b06cf5ea..2b215bdbf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1341,9 +1341,9 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_SSL_Close(conn); /* close possibly still open sockets */ - if(-1 != conn->sock[SECONDARYSOCKET]) + if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) sclose(conn->sock[SECONDARYSOCKET]); - if(-1 != conn->sock[FIRSTSOCKET]) + if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) sclose(conn->sock[FIRSTSOCKET]); Curl_safefree(conn->user); @@ -2022,8 +2022,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* and we setup a few fields in case we end up actually using this struct */ conn->data = data; /* remember our daddy */ - conn->sock[FIRSTSOCKET] = -1; /* no file descriptor */ - conn->sock[SECONDARYSOCKET] = -1; /* no file descriptor */ + conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->connectindex = -1; /* no index */ conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && (data->set.proxytype == CURLPROXY_HTTP))? @@ -3164,7 +3164,7 @@ static CURLcode SetupConnection(struct connectdata *conn, conn->bytecount = 0; conn->headerbytecount = 0; - if(-1 == conn->sock[FIRSTSOCKET]) { + if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { bool connected; /* Connect only if not already connected! */ -- cgit v1.2.1 From 1ebda8fa0eedf04a9759bd08b904199b2c02a0bf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Mar 2004 08:55:47 +0000 Subject: Added CURLOPT_POSTFIELDSIZE_LARGE to offer a large file version of the CURLOPT_POSTFIELDSIZE option to allow really big HTTP POSTs. --- lib/url.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2b215bdbf..f7b7cc378 100644 --- a/lib/url.c +++ b/lib/url.c @@ -782,11 +782,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; case CURLOPT_POSTFIELDSIZE: /* - * The size of the POSTFIELD data, if curl should now do a strlen - * to find out. Enables binary posts. + * The size of the POSTFIELD data to prevent libcurl to do strlen() to + * figure it out. Enables binary posts. */ data->set.postfieldsize = va_arg(param, long); break; + case CURLOPT_POSTFIELDSIZE_LARGE: + /* + * The size of the POSTFIELD data to prevent libcurl to do strlen() to + * figure it out. Enables binary posts. + */ + data->set.postfieldsize = va_arg(param, curl_off_t); + break; case CURLOPT_REFERER: /* * String to set in the HTTP Referer: field. -- cgit v1.2.1 From bb3d6e8552f428bd0c2624854403d36ab3cf163d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 25 Mar 2004 13:37:18 +0000 Subject: tcp-nodelay patch by Joe Halpin --- lib/url.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f7b7cc378..bebf51df1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1303,6 +1303,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.max_filesize = va_arg(param, curl_off_t); break; + case CURLOPT_TCP_NODELAY: + /* + * Enable or disable TCP_NODELAY, which will disable/enable the Nagle + * algorithm + */ + data->tcp_nodelay = va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From dd2add82ee5717446f365239eead0974e171d506 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 31 Mar 2004 10:46:06 +0000 Subject: Fixed how the user name is extracted from http_proxy environment variable when set. --- lib/url.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bebf51df1..ef2732b06 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2351,6 +2351,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, char proxyuser[MAX_CURL_USER_LENGTH]; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; + char *fineptr; + /* skip the possible protocol piece */ ptr=strstr(proxy, "://"); if(ptr) @@ -2358,9 +2360,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, else ptr = proxy; + fineptr = ptr; + /* check for an @-letter */ ptr = strchr(ptr, '@'); - if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" + if(ptr && (2 == sscanf(fineptr, + "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", proxyuser, proxypasswd))) { /* found user and password, rip them out */ @@ -2378,7 +2383,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.proxy_user_passwd = TRUE; /* enable it */ - ptr = strdup(ptr+1); + ptr = strdup(ptr+1); /* the right side of the @-letter */ free(proxy); /* free the former data */ proxy = ptr; /* now use this instead */ } -- cgit v1.2.1 From 5804c995e1f72ec7013ddb69b9f5a42d8db25141 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 31 Mar 2004 21:33:52 +0000 Subject: Use the new HAVE_NI_WITHSCOPEID define instead of merely checking for the existance of NI_WITHSCOPEID since some platforms have that define but still can't function with it set. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ef2732b06..805acd0e6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1877,7 +1877,7 @@ static void verboseconnect(struct connectdata *conn, #ifdef ENABLE_IPV6 { char hbuf[NI_MAXHOST]; -#ifdef NI_WITHSCOPEID +#ifdef HAVE_NI_WITHSCOPEID #define NIFLAGS NI_NUMERICHOST | NI_WITHSCOPEID #else #define NIFLAGS NI_NUMERICHOST -- cgit v1.2.1 From 8ed44e8dfbe2182696becc3ca8a9950888251503 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 6 Apr 2004 15:14:10 +0000 Subject: New authentication code added, particularly noticable when doing POST or PUT with Digest or NTLM. libcurl will now use HEAD to negotiate the authentication and when done perform the requested POST. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 805acd0e6..40794a93e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -463,7 +463,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Do not include the body part in the output data stream. */ - data->set.no_body = va_arg(param, long)?TRUE:FALSE; + data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_FAILONERROR: /* @@ -2066,6 +2066,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.user_passwd = data->set.userpwd?1:0; conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; + conn->bits.no_body = data->set.opt_no_body; /* This initing continues below, see the comment "Continue connectdata * initialization here" */ @@ -2924,6 +2925,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.user_passwd = old_conn->bits.user_passwd; conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; + /* 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() */ -- cgit v1.2.1 From 4e3aa250c4ab02a6daaebba3282faf34c89f9ba9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Apr 2004 07:16:26 +0000 Subject: Moved the 'tcp_nodelay' member to the proper 'UserDefined' struct within the sessionhandle to make the duphandle() function work as supposed. Also tried to start document functions the doxygen way (in the headers of the functions). Can't make it work though... --- lib/url.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 40794a93e..635a01924 100644 --- a/lib/url.c +++ b/lib/url.c @@ -246,6 +246,14 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } +/** + * Curl_open() + * + * @param curl is a pointer to a sessionhandle pointer that gets set by this + * function. + * @return CURLcode + */ + CURLcode Curl_open(struct SessionHandle **curl) { /* We don't yet support specifying the URL at this point */ @@ -1308,7 +1316,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Enable or disable TCP_NODELAY, which will disable/enable the Nagle * algorithm */ - data->tcp_nodelay = va_arg(param, long); + data->set.tcp_nodelay = va_arg(param, long); break; default: @@ -1968,13 +1976,20 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, return result; /* pass back status */ } -/* +/** * CreateConnection() sets up a new connectdata struct, or re-uses an already * existing one, and resolves host name. * * if this function returns CURLE_OK and *async is set to TRUE, the resolve * response will be coming asynchronously. If *async is FALSE, the name is * already resolved. + * + * @param data The sessionhandle pointer + * @param in_connect is set to the next connection data pointer + * @param addr is set to the new dns entry for this connection + * @param async is set TRUE/FALSE depending on the nature of this lookup + * @return CURLcode + * @see SetupConnection() */ static CURLcode CreateConnection(struct SessionHandle *data, -- cgit v1.2.1 From ee7d1d0701e8d7b87b5913c96f713b743196a2b0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Apr 2004 07:37:28 +0000 Subject: remove an long time #defined struct member and use the actual "real" name instead to make it easier to find/read --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 635a01924..d3ee36469 100644 --- a/lib/url.c +++ b/lib/url.c @@ -455,7 +455,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set to include the header in the general data output stream. */ - data->set.http_include_header = va_arg(param, long)?TRUE:FALSE; + data->set.include_header = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_NOPROGRESS: /* -- cgit v1.2.1 From b48bf7470db0a06918d86c1200c62bfe4e88b39c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 13 Apr 2004 10:42:32 +0000 Subject: proper typecast to prevent compiler warning --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d3ee36469..de31fd107 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1316,7 +1316,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Enable or disable TCP_NODELAY, which will disable/enable the Nagle * algorithm */ - data->set.tcp_nodelay = va_arg(param, long); + data->set.tcp_nodelay = (bool)va_arg(param, long); break; default: -- cgit v1.2.1 From b7a760046545fa9afc3feca68d12dc087fbe625c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Apr 2004 07:53:24 +0000 Subject: Cleaned up hostname/name/gname and path/ppath confusion. Removed the fixed- length limit of the hostname part of the URL. --- lib/url.c | 116 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 54 insertions(+), 62 deletions(-) (limited to 'lib/url.c') 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() */ - - /* 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 */ + free(conn->namebuffer); /* free the newly allocated name buffer */ + conn->namebuffer = old_conn->namebuffer; /* use the old one */ + conn->hostname = old_conn->hostname; - /* '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 */ } -- cgit v1.2.1 From 9ba010c6291b7834898103621e8d8efb95b89da5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 21 Apr 2004 11:15:02 +0000 Subject: typecast tolower/toupper arguments to int to make picky compilers complain less --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 078b74c47..87d1685f2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2326,7 +2326,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Now, build _proxy and check for such a one to use */ while(*protop) - *envp++ = tolower(*protop++); + *envp++ = tolower((int)*protop++); /* append _proxy */ strcpy(envp, "_proxy"); @@ -2349,7 +2349,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(!prox && !strequal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ for(envp = proxy_env; *envp; envp++) - *envp = toupper(*envp); + *envp = toupper((int)*envp); prox=curl_getenv(proxy_env); } @@ -2578,7 +2578,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(type) { char command; *type=0; /* it was in the middle of the hostname */ - command = toupper(type[6]); + command = toupper((int)type[6]); switch(command) { case 'A': /* ASCII mode */ data->set.ftp_ascii = 1; -- cgit v1.2.1 From 648e82f05d8bce097f9f81b78d9df40f647f6170 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Apr 2004 07:20:11 +0000 Subject: Major hostip.c cleanup and split into multiple files and easier #ifdef usage. --- lib/url.c | 130 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 70 insertions(+), 60 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 87d1685f2..7bdea96ef 100644 --- a/lib/url.c +++ b/lib/url.c @@ -84,6 +84,11 @@ #endif +#ifdef USE_LIBIDN +#include +#include +#endif + #ifdef HAVE_OPENSSL_ENGINE_H #include #endif @@ -116,6 +121,7 @@ #include "ldap.h" #include "url.h" #include "connect.h" +#include "inet_ntop.h" #include #include @@ -145,6 +151,11 @@ static unsigned int ConnectionStore(struct SessionHandle *data, struct connectdata *conn); static bool safe_strequal(char* str1, char* str2); +#ifdef USE_LIBIDN +static bool is_ASCII_name (const char *hostname); +static bool is_ACE_name (const char *hostname); +#endif + #ifndef USE_ARES /* not for Win32, unless it is cygwin not for ares builds */ @@ -1384,7 +1395,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->proxyhost); -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) +#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ + defined(USE_THREADING_GETADDRINFO) /* possible left-overs from the async name resolve */ Curl_safefree(conn->async.hostname); Curl_safefree(conn->async.os_specific); @@ -1875,64 +1887,26 @@ static CURLcode ConnectPlease(struct connectdata *conn, } /* - * ALERT! The 'dns' pointer being passed in here might be NULL at times. + * verboseconnect() displays verbose information after a connect */ -static void verboseconnect(struct connectdata *conn, - struct Curl_dns_entry *dns) +static void verboseconnect(struct connectdata *conn) { struct SessionHandle *data = conn->data; + const char *host=NULL; + char addrbuf[NI_MAXHOST]; - /* Figure out the ip-number and display the first host name it shows: */ + /* Get a printable version of the network address. */ #ifdef ENABLE_IPV6 - { - char hbuf[NI_MAXHOST]; -#ifdef HAVE_NI_WITHSCOPEID -#define NIFLAGS NI_NUMERICHOST | NI_WITHSCOPEID -#else -#define NIFLAGS NI_NUMERICHOST -#endif - if(dns) { - struct addrinfo *ai = dns->addr; - - /* Lookup the name of the given address. This should probably be remade - to use the DNS cache instead, as the host name is most likely cached - already. */ - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, - NIFLAGS)) { - snprintf(hbuf, sizeof(hbuf), "unknown"); - } - else { - if (ai->ai_canonname) { - infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf, - conn->port); - return; - } - } - } - else { - snprintf(hbuf, sizeof(hbuf), "same host"); - } - - infof(data, "Connected to %s port %d\n", hbuf, conn->port); - } + struct addrinfo *ai = conn->serv_addr; + host = Curl_printable_address(ai->ai_family, ai->ai_addr, + addrbuf, sizeof(addrbuf)); #else - { -#ifdef HAVE_INET_NTOA_R - char ntoa_buf[64]; -#endif - Curl_addrinfo *hostaddr=dns?dns->addr:NULL; - struct in_addr in; - (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s) port %d\n", - hostaddr?hostaddr->h_name:"", -#if defined(HAVE_INET_NTOA_R) - inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), -#else - inet_ntoa(in), -#endif - conn->port); - } + struct in_addr in; + (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); + host = Curl_inet_ntop(AF_INET, &in, addrbuf, sizeof(addrbuf)); #endif + infof(data, "Connected to %s (%s) port %d\n", + conn->hostname, host?host:"", conn->port); } /* @@ -1942,11 +1916,9 @@ static void verboseconnect(struct connectdata *conn, * If we're using the multi interface, this host address pointer is most * likely NULL at this point as we can't keep the resolved info around. This * may call for some reworking, like a reference counter in the struct or - * something. The hostaddr is not used for very much though, we have the - * 'serv_addr' field in the connectdata struct for most of it. + * something. */ -CURLcode Curl_protocol_connect(struct connectdata *conn, - struct Curl_dns_entry *hostaddr) +CURLcode Curl_protocol_connect(struct connectdata *conn) { struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; @@ -1960,7 +1932,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ if(data->set.verbose) - verboseconnect(conn, hostaddr); + verboseconnect(conn); if(conn->curl_connect) { /* is there a protocol-specific connect() procedure? */ @@ -3173,6 +3145,26 @@ static CURLcode SetupConnection(struct connectdata *conn, a file:// transfer */ return result; +#ifdef USE_LIBIDN + /************************************************************* + * Check name for non-ASCII and convert hostname to ACE form. + *************************************************************/ + + if(!conn->bits.reuse && conn->remote_port) { + const char *host = conn->hostname; + char *ace_hostname; + + if (!is_ASCII_name(host) && !is_ACE_name(host)) { + int rc = idna_to_ascii_lz (host, &ace_hostname, 0); + + if (rc == IDNA_SUCCESS) + conn->ace_hostname = ace_hostname; + else + infof(data, "Failed to convert %s to ACE; IDNA error %d\n", host, rc); + } + } +#endif + /************************************************************* * Send user-agent to HTTP proxies even if the target protocol * isn't HTTP. @@ -3202,7 +3194,7 @@ static CURLcode SetupConnection(struct connectdata *conn, result = ConnectPlease(conn, hostaddr, &connected); if(connected) { - result = Curl_protocol_connect(conn, hostaddr); + result = Curl_protocol_connect(conn); if(CURLE_OK == result) conn->bits.tcpconnect = TRUE; } @@ -3217,7 +3209,7 @@ static CURLcode SetupConnection(struct connectdata *conn, Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ conn->bits.tcpconnect = TRUE; if(data->set.verbose) - verboseconnect(conn, hostaddr); + verboseconnect(conn); } conn->now = Curl_tvnow(); /* time this *after* the connect is done, we @@ -3277,7 +3269,8 @@ CURLcode Curl_connect(struct SessionHandle *data, then a successful name resolve has been received */ CURLcode Curl_async_resolved(struct connectdata *conn) { -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) +#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ + defined(USE_THREADING_GETADDRINFO) CURLcode code = SetupConnection(conn, conn->async.dns); if(code) @@ -3504,3 +3497,20 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc) if(sslc->random_file) free(sslc->random_file); } + +/* + * Helpers for IDNA convertions. To do. + */ +#ifdef USE_LIBIDN +static bool is_ASCII_name (const char *hostname) +{ + (void) hostname; + return (TRUE); +} + +static bool is_ACE_name (const char *hostname) +{ + (void) hostname; + return (FALSE); +} +#endif -- cgit v1.2.1 From f5042cce34d0680ddfb8132d8d36521f10e5e3fe Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Apr 2004 14:03:25 +0000 Subject: IDN adjustments and host cleanups by Gisle --- lib/url.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7bdea96ef..6657b1832 100644 --- a/lib/url.c +++ b/lib/url.c @@ -124,8 +124,6 @@ #include "inet_ntop.h" #include -#include - #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) #include "inet_ntoa_r.h" #endif @@ -152,8 +150,7 @@ static unsigned int ConnectionStore(struct SessionHandle *data, static bool safe_strequal(char* str1, char* str2); #ifdef USE_LIBIDN -static bool is_ASCII_name (const char *hostname); -static bool is_ACE_name (const char *hostname); +static bool is_ASCII_name(const char *hostname); #endif #ifndef USE_ARES @@ -1373,6 +1370,9 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->newurl); Curl_safefree(conn->pathbuffer); /* the URL path buffer */ Curl_safefree(conn->namebuffer); /* the URL host name buffer */ +#ifdef USE_LIBIDN + Curl_safefree(conn->ace_hostname); +#endif Curl_SSL_Close(conn); /* close possibly still open sockets */ @@ -1473,7 +1473,7 @@ ConnectionExists(struct SessionHandle *data, continue; if(strequal(needle->protostr, check->protostr) && - strequal(needle->hostname, check->hostname) && + strequal(TRUE_HOSTNAME(needle), TRUE_HOSTNAME(check)) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same @@ -1763,7 +1763,7 @@ static int handleSock5Proxy(const char *proxy_name, #ifndef ENABLE_IPV6 struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; - int rc = Curl_resolv(conn, conn->hostname, conn->remote_port, &dns); + int rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->remote_port, &dns); if(rc == -1) return 1; @@ -2917,6 +2917,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(conn->namebuffer); /* free the newly allocated name buffer */ conn->namebuffer = old_conn->namebuffer; /* use the old one */ conn->hostname = old_conn->hostname; +#ifdef USE_LIBIDN + Curl_safefree(conn->ace_hostname); + conn->ace_hostname = old_conn->ace_hostname; +#endif free(conn->pathbuffer); /* free the newly allocated path pointer */ conn->pathbuffer = old_conn->pathbuffer; /* use the old one */ @@ -3057,7 +3061,7 @@ 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->hostname, conn->port, &hostaddr); + rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->port, &hostaddr); if(rc == 1) *async = TRUE; @@ -3154,13 +3158,12 @@ static CURLcode SetupConnection(struct connectdata *conn, const char *host = conn->hostname; char *ace_hostname; - if (!is_ASCII_name(host) && !is_ACE_name(host)) { - int rc = idna_to_ascii_lz (host, &ace_hostname, 0); - - if (rc == IDNA_SUCCESS) - conn->ace_hostname = ace_hostname; - else - infof(data, "Failed to convert %s to ACE; IDNA error %d\n", host, rc); + if (!is_ASCII_name(host)) { + int rc = idna_to_ascii_lz (host, &ace_hostname, 0); + if (rc == IDNA_SUCCESS) + conn->ace_hostname = ace_hostname; + else + infof(data, "Failed to convert %s to ACE; IDNA error %d\n", host, rc); } } #endif @@ -3499,18 +3502,17 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc) } /* - * Helpers for IDNA convertions. To do. + * Helpers for IDNA convertions. */ #ifdef USE_LIBIDN static bool is_ASCII_name (const char *hostname) { - (void) hostname; - return (TRUE); -} + const unsigned char *ch = (const unsigned char*)hostname; -static bool is_ACE_name (const char *hostname) -{ - (void) hostname; - return (FALSE); + while (*ch) { + if (*ch++ > 0x80) + return FALSE; + } + return TRUE; } #endif -- cgit v1.2.1 From 245e3122df4ec12fee41552a909be75714a268a2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Apr 2004 14:18:00 +0000 Subject: Made defines instead of plain numbers for the Curl_resolv() return code to make the code easier to read --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6657b1832..33048c8b5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1765,10 +1765,10 @@ static int handleSock5Proxy(const char *proxy_name, Curl_addrinfo *hp=NULL; int rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->remote_port, &dns); - if(rc == -1) + if(rc == CURLRESOLV_ERROR) return 1; - if(rc == 1) + if(rc == CURLRESOLV_PENDING) /* this requires that we're in "wait for resolve" state */ rc = Curl_wait_for_resolv(conn, &dns); @@ -3062,7 +3062,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Resolve target host right on */ rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->port, &hostaddr); - if(rc == 1) + if(rc == CURLRESOLV_PENDING) *async = TRUE; else if(!hostaddr) { @@ -3077,7 +3077,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* resolve proxy */ rc = Curl_resolv(conn, conn->proxyhost, conn->port, &hostaddr); - if(rc == 1) + if(rc == CURLRESOLV_PENDING) *async = TRUE; else if(!hostaddr) { -- cgit v1.2.1 From a9f2274bd8e027465386b227b47156468e477146 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Apr 2004 15:14:19 +0000 Subject: NI_MAXHOST is not generally available, we use plain 256 bytes for the hostname instead, its only for debug verbose output anyway --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 33048c8b5..fec12c22a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1893,7 +1893,7 @@ static void verboseconnect(struct connectdata *conn) { struct SessionHandle *data = conn->data; const char *host=NULL; - char addrbuf[NI_MAXHOST]; + char addrbuf[256]; /* Get a printable version of the network address. */ #ifdef ENABLE_IPV6 -- cgit v1.2.1 From e218811ca39bb9f81f2dab45f66e1d50ff7f88ec Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Apr 2004 15:19:55 +0000 Subject: made the verbose connect use the proper host name string even when using a proxy --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fec12c22a..695d374bf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1906,7 +1906,8 @@ static void verboseconnect(struct connectdata *conn) host = Curl_inet_ntop(AF_INET, &in, addrbuf, sizeof(addrbuf)); #endif infof(data, "Connected to %s (%s) port %d\n", - conn->hostname, host?host:"", conn->port); + conn->bits.httpproxy?conn->proxyhost:conn->hostname, + host?host:"", conn->port); } /* -- cgit v1.2.1 From 4b9f8e766d0c4d989b0188a6dfd3c667e49a93a9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 27 Apr 2004 13:56:23 +0000 Subject: Made host name and proxy name get stored in a 'struct hostname' and set all things up to work with encoded host names internally, as well as keeping 'display names' to show in debug messages. IDN resolves work for me now using ipv6, ipv4 and ares resolving. Even cookies on IDN sites seem to do right. --- lib/url.c | 251 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 137 insertions(+), 114 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 695d374bf..38beb89a2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -149,10 +149,6 @@ static unsigned int ConnectionStore(struct SessionHandle *data, struct connectdata *conn); static bool safe_strequal(char* str1, char* str2); -#ifdef USE_LIBIDN -static bool is_ASCII_name(const char *hostname); -#endif - #ifndef USE_ARES /* not for Win32, unless it is cygwin not for ares builds */ @@ -1369,10 +1365,17 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->proto.generic); Curl_safefree(conn->newurl); Curl_safefree(conn->pathbuffer); /* the URL path buffer */ - Curl_safefree(conn->namebuffer); /* the URL host name buffer */ -#ifdef USE_LIBIDN - Curl_safefree(conn->ace_hostname); -#endif + + Curl_safefree(conn->host.rawalloc); /* host name buffer */ + Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ + if(conn->host.encalloc) + (free)(conn->host.encalloc); /* encoded host name buffer, must be freed + with free() since this was allocated by + libidn */ + if(conn->proxy.encalloc) + (free)(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed + with free() since this was allocated by + libidn */ Curl_SSL_Close(conn); /* close possibly still open sockets */ @@ -1394,7 +1397,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.cookie); Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); - Curl_safefree(conn->proxyhost); + #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ defined(USE_THREADING_GETADDRINFO) /* possible left-overs from the async name resolve */ @@ -1473,7 +1476,7 @@ ConnectionExists(struct SessionHandle *data, continue; if(strequal(needle->protostr, check->protostr) && - strequal(TRUE_HOSTNAME(needle), TRUE_HOSTNAME(check)) && + strequal(needle->host.name, check->host.name) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same @@ -1500,7 +1503,7 @@ ConnectionExists(struct SessionHandle *data, else { /* The requested needle connection is using a proxy, is the checked one using the same? */ if(check->bits.httpproxy && - strequal(needle->proxyhost, check->proxyhost) && + strequal(needle->proxy.name, check->proxy.name) && needle->port == check->port) { /* This is the same proxy connection, use it! */ match = TRUE; @@ -1763,7 +1766,7 @@ static int handleSock5Proxy(const char *proxy_name, #ifndef ENABLE_IPV6 struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; - int rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->remote_port, &dns); + int rc = Curl_resolv(conn, conn->host.name, conn->remote_port, &dns); if(rc == CURLRESOLV_ERROR) return 1; @@ -1788,7 +1791,7 @@ static int handleSock5Proxy(const char *proxy_name, } else { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", - conn->hostname); + conn->host.name); return 1; } #else @@ -1906,7 +1909,7 @@ static void verboseconnect(struct connectdata *conn) host = Curl_inet_ntop(AF_INET, &in, addrbuf, sizeof(addrbuf)); #endif infof(data, "Connected to %s (%s) port %d\n", - conn->bits.httpproxy?conn->proxyhost:conn->hostname, + conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname, host?host:"", conn->port); } @@ -1950,6 +1953,50 @@ CURLcode Curl_protocol_connect(struct connectdata *conn) return result; /* pass back status */ } +/* + * Helpers for IDNA convertions. + */ +#ifdef USE_LIBIDN +static bool is_ASCII_name (const char *hostname) +{ + const unsigned char *ch = (const unsigned char*)hostname; + + while (*ch) { + if (*ch++ & 0x80) + return FALSE; + } + return TRUE; +} +#endif + +static void fix_hostname(struct connectdata *conn, struct hostname *host) +{ + /* set the name we use to display the host name */ + conn->host.dispname = conn->host.name; + +#ifdef USE_LIBIDN + /************************************************************* + * Check name for non-ASCII and convert hostname to ACE form. + *************************************************************/ + if (!is_ASCII_name(host->name)) { + char *ace_hostname = NULL; + struct SessionHandle *data = conn->data; + int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); + infof (data, "Input domain encoded as `%s'\n", + stringprep_locale_charset ()); + if (rc != IDNA_SUCCESS) + infof(data, "Failed to convert %s to ACE; IDNA error %d\n", + host->name, rc); + else { + host->encalloc = ace_hostname; + /* change the name pointer to point to the encoded hostname */ + host->name = host->encalloc; + } + } +#endif +} + + /** * CreateConnection() sets up a new connectdata struct, or re-uses an already * existing one, and resolves host name. @@ -2075,10 +2122,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; /* really bad error */ conn->path = conn->pathbuffer; - conn->namebuffer=(char *)malloc(urllen); - if(NULL == conn->namebuffer) + conn->host.rawalloc=(char *)malloc(urllen); + if(NULL == conn->host.rawalloc) return CURLE_OUT_OF_MEMORY; - conn->hostname = conn->namebuffer; + conn->host.name = conn->host.rawalloc; /************************************************************* * Parse the URL. @@ -2139,9 +2186,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, strcpy(conn->protostr, "file"); /* store protocol string lowercase */ } else { - /* Set default host and default path */ - strcpy(conn->namebuffer, "curl.haxx.se"); + /* Set default path */ 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 * http://example.com?param= (notice the missing '/'). Later we'll insert @@ -2150,14 +2197,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (2 > sscanf(data->change.url, "%64[^\n:]://%[^\n/?]%[^\n]", conn->protostr, - conn->namebuffer, conn->path)) { + conn->host.name, conn->path)) { /* * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ if((1 > sscanf(data->change.url, "%[^\n/?]%[^\n]", - conn->namebuffer, conn->path)) ) { + conn->host.name, conn->path)) ) { /* * We couldn't even get this format. */ @@ -2173,21 +2220,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->namebuffer)) + if(checkprefix("GOPHER", conn->host.name)) strcpy(conn->protostr, "gopher"); #ifdef USE_SSLEAY - else if(checkprefix("HTTPS", conn->namebuffer)) + else if(checkprefix("HTTPS", conn->host.name)) strcpy(conn->protostr, "https"); - else if(checkprefix("FTPS", conn->namebuffer)) + else if(checkprefix("FTPS", conn->host.name)) strcpy(conn->protostr, "ftps"); #endif /* USE_SSLEAY */ - else if(checkprefix("FTP", conn->namebuffer)) + else if(checkprefix("FTP", conn->host.name)) strcpy(conn->protostr, "ftp"); - else if(checkprefix("TELNET", conn->namebuffer)) + else if(checkprefix("TELNET", conn->host.name)) strcpy(conn->protostr, "telnet"); - else if (checkprefix("DICT", conn->namebuffer)) + else if (checkprefix("DICT", conn->host.name)) strcpy(conn->protostr, "DICT"); - else if (checkprefix("LDAP", conn->namebuffer)) + else if (checkprefix("LDAP", conn->host.name)) strcpy(conn->protostr, "LDAP"); else { strcpy(conn->protostr, "http"); @@ -2212,7 +2259,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* * So if the URL was A://B/C, * conn->protostr is A - * conn->namebuffer is B + * conn->host.name is B * conn->path is /C */ @@ -2275,15 +2322,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->hostname, ':'); + char *endptr = strchr(conn->host.name, ':'); if(endptr) - namelen=endptr-conn->hostname; + namelen=endptr-conn->host.name; else - namelen=strlen(conn->hostname); + namelen=strlen(conn->host.name); if(strlen(nope) <= namelen) { char *checkn= - conn->hostname + namelen - strlen(nope); + conn->host.name + namelen - strlen(nope); if(checkprefix(nope, checkn)) { /* no proxy for this host! */ break; @@ -2546,7 +2593,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * we'll try to get now! */ type=strstr(conn->path, ";type="); if(!type) { - type=strstr(conn->namebuffer, ";type="); + type=strstr(conn->host.rawalloc, ";type="); } if(type) { char command; @@ -2655,23 +2702,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->hostname is currently [user:passwd@]host[:port] where host + * The conn->host.name is currently [user:passwd@]host[:port] where host * could be a hostname, IPv4 address or IPv6 address. *************************************************************/ - if((1 == sscanf(conn->hostname, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && + if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && (']' == endbracket)) { /* this is a RFC2732-style specified IP-address */ conn->bits.ipv6_ip = TRUE; - conn->hostname++; /* pass the starting bracket */ - tmp = strchr(conn->hostname, ']'); + conn->host.name++; /* pass the starting bracket */ + tmp = strchr(conn->host.name, ']'); *tmp = 0; /* zero terminate */ tmp++; /* pass the ending bracket */ if(':' != *tmp) tmp = NULL; /* no port number available */ } else - tmp = strrchr(conn->hostname, ':'); + tmp = strrchr(conn->host.name, ':'); if (tmp) { char *rest; @@ -2740,7 +2787,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, } /* now, clone the cleaned proxy host name */ - conn->proxyhost = strdup(proxyptr); + conn->proxy.rawalloc = strdup(proxyptr); + conn->proxy.name = conn->proxy.rawalloc; free(proxydup); /* free the duplicate pointer and not the modified */ } @@ -2753,7 +2801,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Inputs: data->set.userpwd (CURLOPT_USERPWD) * data->set.fpasswd (CURLOPT_PASSWDFUNCTION) * data->set.use_netrc (CURLOPT_NETRC) - * conn->hostname + * conn->host.name * netrc file * hard-coded defaults * @@ -2761,11 +2809,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, * conn->bits.user_passwd - non-zero if non-default passwords exist * conn->user - non-zero length if defined * conn->passwd - ditto - * conn->hostname - remove user name and password + * conn->host.name - remove user name and password */ /* At this point, we're hoping all the other special cases have - * been taken care of, so conn->hostname is at most + * been taken care of, so conn->host.name is at most * [user[:password]]@]hostname * * We need somewhere to put the embedded details, so do that first. @@ -2778,12 +2826,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->hostname, '@'); - char *userpass = conn->hostname; + char *ptr=strchr(conn->host.name, '@'); + char *userpass = conn->host.name; if(ptr != NULL) { /* there's a user+password given here, to the left of the @ */ - conn->hostname = ++ptr; + conn->host.name = ++ptr; /* So the hostname is sane. Only bother interpreting the * results if we could care. It could still be wasted @@ -2844,11 +2892,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if (data->set.use_netrc != CURL_NETRC_IGNORED) { - if(Curl_parsenetrc(conn->hostname, + if(Curl_parsenetrc(conn->host.name, user, passwd, data->set.netrc_file)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults\n", - conn->hostname); + conn->host.name); } else conn->bits.user_passwd = 1; /* enable user+password */ @@ -2898,8 +2946,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ struct connectdata *old_conn = conn; - if(old_conn->proxyhost) - free(old_conn->proxyhost); + if(old_conn->proxy.rawalloc) + free(old_conn->proxy.rawalloc); /* free the SSL config struct from this connection struct as this was allocated in vain and is targeted for destruction */ @@ -2915,13 +2963,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* get the newly set value, not the old one */ conn->bits.no_body = old_conn->bits.no_body; - free(conn->namebuffer); /* free the newly allocated name buffer */ - conn->namebuffer = old_conn->namebuffer; /* use the old one */ - conn->hostname = old_conn->hostname; -#ifdef USE_LIBIDN - Curl_safefree(conn->ace_hostname); - conn->ace_hostname = old_conn->ace_hostname; -#endif + free(conn->host.rawalloc); /* free the newly allocated name buffer */ + conn->host.rawalloc = old_conn->host.rawalloc; /* use the old one */ + conn->host.name = old_conn->host.name; + + conn->host.encalloc = old_conn->host.encalloc; /* use the old one */ + conn->host.dispname = old_conn->host.dispname; free(conn->pathbuffer); /* free the newly allocated path pointer */ conn->pathbuffer = old_conn->pathbuffer; /* use the old one */ @@ -3056,35 +3103,45 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->connect_addr = NULL; /* we don't connect now so we don't have any fresh connect_addr struct to point to */ } - else if(!data->change.proxy || !*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 */ + else { + /* this is a fresh connect */ - /* Resolve target host right on */ - rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->port, &hostaddr); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; + /* set a pointer to the hostname we display */ + fix_hostname(conn, &conn->host); + + if(!data->change.proxy || !*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 */ + + /* Resolve target host right on */ + rc = Curl_resolv(conn, conn->host.name, conn->port, &hostaddr); + if(rc == CURLRESOLV_PENDING) + *async = TRUE; - else if(!hostaddr) { - 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 */ + else if(!hostaddr) { + failf(data, "Couldn't resolve host '%s'", conn->host.dispname); + result = CURLE_COULDNT_RESOLVE_HOST; + /* don't return yet, we need to clean up the timeout first */ + } } - } - else { - /* This is a proxy that hasn't been resolved yet. */ + else { + /* This is a proxy that hasn't been resolved yet. */ - /* resolve proxy */ - rc = Curl_resolv(conn, conn->proxyhost, conn->port, &hostaddr); + /* IDN check */ + fix_hostname(conn, &conn->proxy); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; + /* resolve proxy */ + rc = Curl_resolv(conn, conn->proxy.name, conn->port, &hostaddr); - else if(!hostaddr) { - failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); - result = CURLE_COULDNT_RESOLVE_PROXY; - /* don't return yet, we need to clean up the timeout first */ + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + + else if(!hostaddr) { + failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); + result = CURLE_COULDNT_RESOLVE_PROXY; + /* don't return yet, we need to clean up the timeout first */ + } } } *addr = hostaddr; @@ -3150,25 +3207,6 @@ static CURLcode SetupConnection(struct connectdata *conn, a file:// transfer */ return result; -#ifdef USE_LIBIDN - /************************************************************* - * Check name for non-ASCII and convert hostname to ACE form. - *************************************************************/ - - if(!conn->bits.reuse && conn->remote_port) { - const char *host = conn->hostname; - char *ace_hostname; - - if (!is_ASCII_name(host)) { - int rc = idna_to_ascii_lz (host, &ace_hostname, 0); - if (rc == IDNA_SUCCESS) - conn->ace_hostname = ace_hostname; - else - infof(data, "Failed to convert %s to ACE; IDNA error %d\n", host, rc); - } - } -#endif - /************************************************************* * Send user-agent to HTTP proxies even if the target protocol * isn't HTTP. @@ -3502,18 +3540,3 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc) free(sslc->random_file); } -/* - * Helpers for IDNA convertions. - */ -#ifdef USE_LIBIDN -static bool is_ASCII_name (const char *hostname) -{ - const unsigned char *ch = (const unsigned char*)hostname; - - while (*ch) { - if (*ch++ > 0x80) - return FALSE; - } - return TRUE; -} -#endif -- cgit v1.2.1 From 8ca37dd1c7f45ee1e29978e7eb26bec951ccff3b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Apr 2004 11:57:52 +0000 Subject: encode the correct name --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 38beb89a2..9c27b1cba 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1972,7 +1972,7 @@ static bool is_ASCII_name (const char *hostname) static void fix_hostname(struct connectdata *conn, struct hostname *host) { /* set the name we use to display the host name */ - conn->host.dispname = conn->host.name; + host->dispname = host->name; #ifdef USE_LIBIDN /************************************************************* @@ -3128,7 +3128,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, else { /* This is a proxy that hasn't been resolved yet. */ - /* IDN check */ + /* IDN-fix the proxy name */ fix_hostname(conn, &conn->proxy); /* resolve proxy */ -- cgit v1.2.1 From 59907ebc0e4031e2447b57684d530da22a5d32c7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Apr 2004 13:41:48 +0000 Subject: fixed the host/proxy name issue when re-using a connection and made IDN names work when using proxy by converting the IDN-name to the ACE-encoded version before the request-URL is passed to the proxy. --- lib/url.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9c27b1cba..7962d264e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2963,12 +2963,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* get the newly set value, not the old one */ conn->bits.no_body = old_conn->bits.no_body; - free(conn->host.rawalloc); /* free the newly allocated name buffer */ - conn->host.rawalloc = old_conn->host.rawalloc; /* use the old one */ - conn->host.name = old_conn->host.name; - - conn->host.encalloc = old_conn->host.encalloc; /* use the old one */ - conn->host.dispname = old_conn->host.dispname; + free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ free(conn->pathbuffer); /* free the newly allocated path pointer */ conn->pathbuffer = old_conn->pathbuffer; /* use the old one */ @@ -3017,7 +3012,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, *in_connect = conn; /* return this instead! */ - infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex); + infof(data, "Re-using existing connection! (#%d) with host %s\n", + conn->connectindex, conn->host.dispname); } else { /* @@ -3381,7 +3377,8 @@ CURLcode Curl_done(struct connectdata *conn) result = res2; } else - infof(data, "Connection #%d left intact\n", conn->connectindex); + infof(data, "Connection #%d to host %s left intact\n", + conn->connectindex, conn->host.dispname); return result; } -- cgit v1.2.1 From fc6eff13b5414caf6edf22d73a3239e074a04216 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 May 2004 07:52:53 +0000 Subject: General HTTP authentication cleanup and fixes --- lib/url.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7962d264e..df07f538a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1332,9 +1332,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) CURLcode Curl_disconnect(struct connectdata *conn) { + struct SessionHandle *data; if(!conn) return CURLE_OK; /* this is closed and fine already */ + data = conn->data; + /* * The range string is usually freed in curl_done(), but we might * get here *instead* if we fail prematurely. Thus we need to be able @@ -1346,11 +1349,20 @@ CURLcode Curl_disconnect(struct connectdata *conn) } if((conn->ntlm.state != NTLMSTATE_NONE) || - (conn->proxyntlm.state != NTLMSTATE_NONE)) + (conn->proxyntlm.state != NTLMSTATE_NONE)) { /* Authentication data is a mix of connection-related and sessionhandle- related stuff. NTLM is connection-related so when we close the shop we shall forget. */ - conn->data->state.authstage = 0; + data->state.authhost.done = FALSE; + data->state.authhost.picked = + data->state.authhost.want; + + data->state.authproxy.done = FALSE; + data->state.authproxy.picked = + data->state.authhost.want; + + data->state.authproblem = FALSE; + } if(conn->curl_disconnect) /* This is set if protocol-specific cleanups should be made */ @@ -1358,8 +1370,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(-1 != conn->connectindex) { /* unlink ourselves! */ - infof(conn->data, "Closing connection #%d\n", conn->connectindex); - conn->data->state.connects[conn->connectindex] = NULL; + infof(data, "Closing connection #%d\n", conn->connectindex); + data->state.connects[conn->connectindex] = NULL; } Curl_safefree(conn->proto.generic); @@ -1488,7 +1500,7 @@ ConnectionExists(struct SessionHandle *data, } if((needle->protocol & PROT_FTP) || ((needle->protocol & PROT_HTTP) && - (needle->data->state.authwant==CURLAUTH_NTLM))) { + (needle->data->state.authhost.want==CURLAUTH_NTLM))) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ if(!strequal(needle->user, check->user) || -- cgit v1.2.1 From 4d9517f0b4092b62dc791125823d6ce581d0c26c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 5 May 2004 06:57:26 +0000 Subject: prevent warnings when using the gcc option -Wunreachable-code --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index df07f538a..fdc43789b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1810,7 +1810,6 @@ static int handleSock5Proxy(const char *proxy_name, failf(conn->data, "%s:%d has an internal error an needs to be fixed to work", __FILE__, __LINE__); - return 1; #endif } -- cgit v1.2.1 From 35ab93f48462cf6e5dc06c58b21342cb6870cbef Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 5 May 2004 07:08:31 +0000 Subject: fix_hostname() now (void)s the conn argument to prevent warnings on non-idn enabled builds --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fdc43789b..215a1bbd3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2004,6 +2004,8 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) host->name = host->encalloc; } } +#else + (void)conn; /* never used */ #endif } -- cgit v1.2.1 From 7591e07b7c3715d92cc6b4fce664883b3f50898f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 5 May 2004 07:17:37 +0000 Subject: do the alarm time-left math using unsigned longs since that is what alarm() returns and uses as input and converting to signed generates warnings and actually risks loss of accuracy --- lib/url.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 215a1bbd3..398815384 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3174,14 +3174,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, the time we spent until now! */ if(prev_alarm) { /* there was an alarm() set before us, now put it back */ - long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); - long alarm_set; + unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); + unsigned long alarm_set; /* the alarm period is counted in even number of seconds */ alarm_set = prev_alarm - elapsed_ms/1000; - - if(alarm_set<=0) { - /* if it turned negative, we should fire off a SIGALRM here, but we + + if(!alarm_set || + ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { + /* if the alarm time-left reached zero or turned "negative" (counted + with unsigned values), we should fire off a SIGALRM here, but we won't, and zero would be to switch it off so we never set it to less than 1! */ alarm(1); -- cgit v1.2.1 From 91c8be362833e0fd2ee36b904a4295c57cfbab10 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 6 May 2004 15:17:10 +0000 Subject: removed two odd comments --- lib/url.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 398815384..830ab9d30 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2551,7 +2551,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, else if(strequal(conn->protostr, "FTP") || strequal(conn->protostr, "FTPS")) { -/* MN 06/07/02 */ #ifndef CURL_DISABLE_FTP char *type; int port = PORT_FTP; @@ -2626,8 +2625,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, break; } } - -/* MN 06/07/02 */ #else /* CURL_DISABLE_FTP */ failf(data, LIBCURL_NAME " was built with FTP disabled, ftp/ftps: not supported!"); -- cgit v1.2.1 From 3394c01826aef99a645db398c1fb6bce4693bd35 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 May 2004 18:46:28 +0000 Subject: We don't support any long protocol names so we can use a smaller buffer. Also, make sure we have room for the trailing zero, only scan to size-1. Gisle Vanem reported. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 830ab9d30..fc7a9d4e0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2148,7 +2148,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * proxy -- and we don't know if we will need to use SSL until we parse the * url ... ************************************************************/ - if((2 == sscanf(data->change.url, "%64[^:]:%[^\n]", + if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", conn->protostr, conn->path)) && strequal(conn->protostr, "file")) { if(conn->path[0] == '/' && conn->path[1] == '/') { @@ -2208,7 +2208,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * that missing slash at the beginning of the path. */ if (2 > sscanf(data->change.url, - "%64[^\n:]://%[^\n/?]%[^\n]", + "%15[^\n:]://%[^\n/?]%[^\n]", conn->protostr, conn->host.name, conn->path)) { -- cgit v1.2.1 From bbafb2eb27954c34967f91c705e74cc0c186970d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 May 2004 11:30:23 +0000 Subject: curl_global_init_mem() allows the memory functions to be replaced. memory.h is included everywhere for this. --- lib/url.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fc7a9d4e0..66012ef32 100644 --- a/lib/url.c +++ b/lib/url.c @@ -134,11 +134,10 @@ #ifdef HAVE_KRB4 #include "security.h" #endif +#include "memory.h" /* The last #include file should be: */ -#ifdef CURLDEBUG #include "memdebug.h" -#endif /* Local static prototypes */ static int ConnectionKillOne(struct SessionHandle *data); -- cgit v1.2.1 From 98f968f2eef9adc29f1702c09bd7d6306e338a55 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 May 2004 21:17:03 +0000 Subject: fixed Curl_open() to not leak anything if one malloc() fails, fix by James Bursa only modified by me. --- lib/url.c | 104 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 54 insertions(+), 50 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 66012ef32..4b13c3634 100644 --- a/lib/url.c +++ b/lib/url.c @@ -259,7 +259,7 @@ CURLcode Curl_close(struct SessionHandle *data) CURLcode Curl_open(struct SessionHandle **curl) { - /* We don't yet support specifying the URL at this point */ + CURLcode res = CURLE_OK; struct SessionHandle *data; /* Very simple start-up: alloc the struct, init it with zeroes and return */ data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle)); @@ -281,71 +281,75 @@ CURLcode Curl_open(struct SessionHandle **curl) /* We do some initial setup here, all those fields that can't be just 0 */ data->state.headerbuff=(char*)malloc(HEADERSIZE); - if(!data->state.headerbuff) { - free(data); /* free the memory again */ - return CURLE_OUT_OF_MEMORY; - } - - data->state.headersize=HEADERSIZE; - - 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->set.fwrite = (curl_write_callback)fwrite; + if(!data->state.headerbuff) + res = CURLE_OUT_OF_MEMORY; + else { + data->state.headersize=HEADERSIZE; - /* use fread as default function to read input */ - data->set.fread = (curl_read_callback)fread; + data->set.out = stdout; /* default output to stdout */ + data->set.in = stdin; /* default input from stdin */ + data->set.err = stderr; /* default stderr to stderr */ - data->set.infilesize = -1; /* we don't know any size */ + /* use fwrite as default function to store output */ + data->set.fwrite = (curl_write_callback)fwrite; - data->state.current_speed = -1; /* init to negative == impossible */ + /* use fread as default function to read input */ + data->set.fread = (curl_read_callback)fread; - data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ - data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ - data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + data->set.infilesize = -1; /* we don't know any size */ - data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + data->state.current_speed = -1; /* init to negative == impossible */ - /* make libcurl quiet by default: */ - data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ - data->progress.flags |= PGRS_HIDE; + data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ + data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ + data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ - /* Set the default size of the SSL session ID cache */ - data->set.ssl.numsessions = 5; + data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ - data->set.proxyport = 1080; + /* make libcurl quiet by default: */ + data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ + data->progress.flags |= PGRS_HIDE; - data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ + /* Set the default size of the SSL session ID cache */ + data->set.ssl.numsessions = 5; - data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic authentication */ - data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic authentication */ + data->set.proxyport = 1080; + data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ + data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */ + data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */ - /* create an array with connection data struct pointers */ - data->state.numconnects = 5; /* hard-coded right now */ - data->state.connects = (struct connectdata **) - malloc(sizeof(struct connectdata *) * data->state.numconnects); + /* create an array with connection data struct pointers */ + data->state.numconnects = 5; /* hard-coded right now */ + data->state.connects = (struct connectdata **) + malloc(sizeof(struct connectdata *) * data->state.numconnects); - if(!data->state.connects) { - free(data->state.headerbuff); - free(data); - return CURLE_OUT_OF_MEMORY; - } + if(!data->state.connects) + res = CURLE_OUT_OF_MEMORY; + else + memset(data->state.connects, 0, + sizeof(struct connectdata *)*data->state.numconnects); - /* - * libcurl 7.10 introduces SSL verification *by default*! This needs to be - * switched off unless wanted. - */ - data->set.ssl.verifypeer = TRUE; - data->set.ssl.verifyhost = 2; + /* + * libcurl 7.10 introduced SSL verification *by default*! This needs to be + * switched off unless wanted. + */ + data->set.ssl.verifypeer = TRUE; + data->set.ssl.verifyhost = 2; #ifdef CURL_CA_BUNDLE - /* This is our prefered CA cert bundle since install time */ - data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; + /* This is our prefered CA cert bundle since install time */ + data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; #endif + } - memset(data->state.connects, 0, - sizeof(struct connectdata *)*data->state.numconnects); + if(res) { +#ifdef USE_ARES + ares_destroy(data->state.areschannel); +#endif + if(data->state.headerbuff) + free(data->state.headerbuff); + free(data); + data = NULL; + } *curl = data; return CURLE_OK; -- cgit v1.2.1 From 2f60e91a9b2db5d6f1b930be69b78865eee87af4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 May 2004 07:56:01 +0000 Subject: removed another jhrg-reference in a comment --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4b13c3634..99e239aa8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -886,7 +886,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; case CURLOPT_ENCODING: /* - * String to use at the value of Accept-Encoding header. 08/28/02 jhrg + * String to use at the value of Accept-Encoding header. * * If the encoding is set to "" we use an Accept-Encoding header that * encompasses all the encodings we support. -- cgit v1.2.1 From d301d69fbf0342b9510751dcf478487b2e710684 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 May 2004 08:26:56 +0000 Subject: bail out if we can't allocate the new range string, and make use of aprintf() instead of using snprintf() + strdup(). --- lib/url.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 99e239aa8..2d10998ab 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2036,7 +2036,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, { char *tmp; CURLcode result=CURLE_OK; - char resumerange[40]=""; struct connectdata *conn; struct connectdata *conn_temp; int urllen; @@ -2484,9 +2483,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->resume_from) { if(!conn->bits.use_range) { /* if it already was in use, we just skip this */ - snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-", - conn->resume_from); - conn->range=strdup(resumerange); /* tell ourselves to fetch this range */ + conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from); + if(!conn->range) + return CURLE_OUT_OF_MEMORY; conn->bits.rangestringalloc = TRUE; /* mark as allocated */ conn->bits.use_range = 1; /* switch on range usage */ } @@ -3004,19 +3003,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ conn->resume_from = data->set.set_resume_from; if (conn->resume_from) { - snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-", - conn->resume_from); if (conn->bits.rangestringalloc == TRUE) free(conn->range); + conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from); + if(!conn->range) + return CURLE_OUT_OF_MEMORY; /* tell ourselves to fetch this range */ - conn->range = strdup(resumerange); conn->bits.use_range = TRUE; /* enable range download */ conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ } 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.set_range); + if(!conn->range) + return CURLE_OUT_OF_MEMORY; conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ conn->bits.use_range = TRUE; /* enable range download */ } -- cgit v1.2.1 From d60c22572b49cde9b839a59510580df079d2d5e2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 May 2004 12:06:39 +0000 Subject: Curl_done() and the protocol-specific conn->curl_done() functions now all take a CURLcode as a second argument, that is non-zero when Curl_done() is called after an error was returned from Curl_do() (or similar). --- lib/url.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2d10998ab..96b02f45a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3229,6 +3229,8 @@ static CURLcode SetupConnection(struct connectdata *conn, Curl_safefree(conn->allocptr.uagent); conn->allocptr.uagent = aprintf("User-Agent: %s\015\012", data->set.useragent); + if(!conn->allocptr.uagent) + return CURLE_OUT_OF_MEMORY; } } @@ -3236,6 +3238,8 @@ static CURLcode SetupConnection(struct connectdata *conn, Curl_safefree(conn->allocptr.accept_encoding); conn->allocptr.accept_encoding = aprintf("Accept-Encoding: %s\015\012", data->set.encoding); + if(!conn->allocptr.accept_encoding) + return CURLE_OUT_OF_MEMORY; } conn->bytecount = 0; @@ -3340,7 +3344,9 @@ CURLcode Curl_async_resolved(struct connectdata *conn) } -CURLcode Curl_done(struct connectdata *conn) +CURLcode Curl_done(struct connectdata *conn, + CURLcode status) /* an error if this is called after an + error was detected */ { struct SessionHandle *data=conn->data; CURLcode result; @@ -3371,7 +3377,7 @@ CURLcode Curl_done(struct connectdata *conn) /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) - result = conn->curl_done(conn); + result = conn->curl_done(conn, status); else result = CURLE_OK; @@ -3423,7 +3429,7 @@ CURLcode Curl_do(struct connectdata **connp) infof(data, "Re-used connection seems dead, get a new one\n"); conn->bits.close = TRUE; /* enforce close of this connection */ - result = Curl_done(conn); /* we are so done with this */ + result = Curl_done(conn, result); /* we are so done with this */ /* conn is no longer a good pointer */ -- cgit v1.2.1 From aa3ae01878b3178e593af6f9206ef3874de7b91c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 May 2004 13:05:01 +0000 Subject: clean up and return better on out of memory --- lib/url.c | 53 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 96b02f45a..e3a292cbc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -627,11 +627,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Set cookie file to read and parse. Can be used multiple times. */ cookiefile = (char *)va_arg(param, void *); - if(cookiefile) + if(cookiefile) { + struct curl_slist *cl; /* append the cookie file name to the list of file names, and deal with them later */ - data->change.cookielist = - curl_slist_append(data->change.cookielist, cookiefile); + cl = curl_slist_append(data->change.cookielist, cookiefile); + + if(!cl) + return CURLE_OUT_OF_MEMORY; + + data->change.cookielist = cl; + } break; case CURLOPT_COOKIEJAR: @@ -2420,27 +2426,40 @@ static CURLcode CreateConnection(struct SessionHandle *data, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", proxyuser, proxypasswd))) { + CURLcode res = CURLE_OK; + /* found user and password, rip them out */ Curl_safefree(conn->proxyuser); conn->proxyuser = strdup(proxyuser); if(!conn->proxyuser) - return CURLE_OUT_OF_MEMORY; - - Curl_safefree(conn->proxypasswd); - conn->proxypasswd = strdup(proxypasswd); - - if(!conn->proxypasswd) - return CURLE_OUT_OF_MEMORY; - - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - - ptr = strdup(ptr+1); /* the right side of the @-letter */ - free(proxy); /* free the former data */ - proxy = ptr; /* now use this instead */ + res = CURLE_OUT_OF_MEMORY; + else { + Curl_safefree(conn->proxypasswd); + conn->proxypasswd = strdup(proxypasswd); + + if(!conn->proxypasswd) + res = CURLE_OUT_OF_MEMORY; + } + + if(CURLE_OK == res) { + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + ptr = strdup(ptr+1); /* the right side of the @-letter */ + + if(ptr) { + free(proxy); /* free the former proxy string */ + proxy = ptr; /* now use this instead */ + } + else + res = CURLE_OUT_OF_MEMORY; + } + + if(res) { + free(proxy); /* free the allocated proxy string */ + return res; + } } - data->change.proxy = proxy; data->change.proxy_alloc=TRUE; /* this needs to be freed later */ conn->bits.httpproxy = TRUE; -- cgit v1.2.1 From b121e41ec3ae3f5fe355d3802f4c3ddf0f50e190 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 13 May 2004 14:12:49 +0000 Subject: bail out when no memory occurs --- lib/url.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e3a292cbc..9c4769dfa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2886,9 +2886,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(user[0]) { char *newname=curl_unescape(user, 0); - if(strlen(newname) < sizeof(user)) { + if(!newname) + return CURLE_OUT_OF_MEMORY; + if(strlen(newname) < sizeof(user)) strcpy(user, newname); - } + /* if the new name is longer than accepted, then just use the unconverted name, it'll be wrong but what the heck */ free(newname); @@ -2896,9 +2898,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (passwd[0]) { /* we have a password found in the URL, decode it! */ char *newpasswd=curl_unescape(passwd, 0); - if(strlen(newpasswd) < sizeof(passwd)) { + if(!newpasswd) + return CURLE_OUT_OF_MEMORY; + if(strlen(newpasswd) < sizeof(passwd)) strcpy(passwd, newpasswd); - } + free(newpasswd); } } -- cgit v1.2.1 From 8001921112f726c10caa09d0725f90230636dea6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 17 May 2004 08:05:46 +0000 Subject: I made Curl_done() take a pointer-pointer in the first argument instead, and if the connection is killed it blanks the pointer it points to, to make it easier to detect usage problems whereever Curl_done() is used. --- lib/url.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9c4769dfa..53d37baa6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3367,12 +3367,13 @@ CURLcode Curl_async_resolved(struct connectdata *conn) } -CURLcode Curl_done(struct connectdata *conn, +CURLcode Curl_done(struct connectdata **connp, CURLcode status) /* an error if this is called after an error was detected */ { - struct SessionHandle *data=conn->data; CURLcode result; + struct connectdata *conn = *connp; + struct SessionHandle *data=conn->data; /* cleanups done even if the connection is re-used */ @@ -3416,6 +3417,9 @@ CURLcode Curl_done(struct connectdata *conn, CURLcode res2; res2 = Curl_disconnect(conn); /* close the connection */ + *connp = NULL; /* to make the caller of this function better detect that + this was actually killed here */ + /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ if(!result && res2) @@ -3452,9 +3456,9 @@ CURLcode Curl_do(struct connectdata **connp) infof(data, "Re-used connection seems dead, get a new one\n"); conn->bits.close = TRUE; /* enforce close of this connection */ - result = Curl_done(conn, result); /* we are so done with this */ + result = Curl_done(&conn, result); /* we are so done with this */ - /* conn is no longer a good pointer */ + /* conn may no longer be a good pointer */ if(CURLE_OK == result) { bool async; -- cgit v1.2.1 From cdd70596df3c85b07c54ea48f0e6a31127bdedba Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 19 May 2004 09:25:00 +0000 Subject: killed trailing whitespace --- lib/url.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 53d37baa6..f8c8caf85 100644 --- a/lib/url.c +++ b/lib/url.c @@ -325,7 +325,7 @@ CURLcode Curl_open(struct SessionHandle **curl) if(!data->state.connects) res = CURLE_OUT_OF_MEMORY; - else + else memset(data->state.connects, 0, sizeof(struct connectdata *)*data->state.numconnects); @@ -507,12 +507,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * An FTP option that modifies an upload to create missing directories on * the server. - */ + */ data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE; break; case CURLOPT_FTP_RESPONSE_TIMEOUT: /* - * An FTP option that specifies how quickly an FTP response must be + * An FTP option that specifies how quickly an FTP response must be * obtained before it is considered failure. */ data->set.ftp_response_timeout = va_arg( param , long ); @@ -695,7 +695,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) case CURLOPT_FTP_USE_EPSV: data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; break; - + case CURLOPT_HTTPHEADER: /* * Set a list with HTTP headers to use (or replace internals with) @@ -924,7 +924,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.httpauth = auth; } break; - + case CURLOPT_PROXYAUTH: /* * Set HTTP Authentication type BITMASK. @@ -1257,7 +1257,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->hostcache = data->share->hostcache; } - + if(data->share->cookies) { /* use shared cookie list, first free own one if any */ if (data->cookies) @@ -1266,15 +1266,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - + } /* check cookie list is set */ if(!data->cookies) data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE ); - + /* check for host cache not needed, - * it will be done by curl_easy_perform */ + * it will be done by curl_easy_perform */ } break; @@ -1363,11 +1363,11 @@ CURLcode Curl_disconnect(struct connectdata *conn) related stuff. NTLM is connection-related so when we close the shop we shall forget. */ data->state.authhost.done = FALSE; - data->state.authhost.picked = + data->state.authhost.picked = data->state.authhost.want; data->state.authproxy.done = FALSE; - data->state.authproxy.picked = + data->state.authproxy.picked = data->state.authhost.want; data->state.authproblem = FALSE; @@ -1425,7 +1425,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->async.hostname); Curl_safefree(conn->async.os_specific); #endif - + Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ @@ -1788,14 +1788,14 @@ static int handleSock5Proxy(const char *proxy_name, struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; int rc = Curl_resolv(conn, conn->host.name, conn->remote_port, &dns); - + if(rc == CURLRESOLV_ERROR) return 1; if(rc == CURLRESOLV_PENDING) /* this requires that we're in "wait for resolve" state */ rc = Curl_wait_for_resolv(conn, &dns); - + /* * We cannot use 'hostent' as a struct that Curl_resolv() returns. It * returns a Curl_addrinfo pointer that may not always look the same. @@ -2066,7 +2066,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, *addr = NULL; /* nothing yet */ *async = FALSE; - + /************************************************************* * Check input data *************************************************************/ @@ -2299,7 +2299,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->proxyuser = strdup(proxyuser); if(!conn->proxyuser) return CURLE_OUT_OF_MEMORY; - + conn->proxypasswd = strdup(proxypasswd); if(!conn->proxypasswd) return CURLE_OUT_OF_MEMORY; @@ -2958,7 +2958,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * new one. *************************************************************/ - /* get a cloned copy of the SSL config situation stored in the + /* get a cloned copy of the SSL config situation stored in the connection struct */ if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) return CURLE_OUT_OF_MEMORY; @@ -2969,7 +2969,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, authentication phase). */ if(data->set.reuse_fresh && !data->state.this_is_a_follow) reuse = FALSE; - else + else reuse = ConnectionExists(data, conn, &conn_temp); if(reuse) { @@ -3126,7 +3126,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif /* SIGALRM */ } #endif /* USE_ARES */ - + /************************************************************* * Resolve the name of the server or proxy *************************************************************/ @@ -3203,7 +3203,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* the alarm period is counted in even number of seconds */ alarm_set = prev_alarm - elapsed_ms/1000; - + if(!alarm_set || ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { /* if the alarm time-left reached zero or turned "negative" (counted @@ -3228,7 +3228,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* SetupConnection() should be called after the name resolve initiated in * CreateConnection() is all done. */ - + static CURLcode SetupConnection(struct connectdata *conn, struct Curl_dns_entry *hostaddr) { @@ -3319,7 +3319,7 @@ CURLcode Curl_connect(struct SessionHandle *data, struct Curl_dns_entry *dns; *asyncp = FALSE; /* assume synchronous resolves by default */ - + /* call the stuff that needs to be called */ code = CreateConnection(data, in_connect, &dns, asyncp); @@ -3333,7 +3333,7 @@ CURLcode Curl_connect(struct SessionHandle *data, /* else response will be received and treated async wise */ } - + if(CURLE_OK != code) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ @@ -3474,13 +3474,13 @@ CURLcode Curl_do(struct connectdata **connp) result = Curl_wait_for_resolv(conn, NULL); if(result) return result; - + /* Resolved, continue with the connection */ - result = Curl_async_resolved(conn); + result = Curl_async_resolved(conn); if(result) return result; } - + /* ... finally back to actually retry the DO phase */ result = conn->curl_do(conn); } -- cgit v1.2.1 From 59f904d8de005755f87aa0a4312ab7570a62c6f7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 May 2004 07:13:48 +0000 Subject: Robert D. Young reported that CURLOPT_COOKIEFILE and CURLOPT_COOKIE could not be used both in one request. Fixed it and added test case 172 to verify. --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f8c8caf85..d55086fed 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1415,7 +1415,6 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.accept_encoding); Curl_safefree(conn->allocptr.rangeline); Curl_safefree(conn->allocptr.ref); - Curl_safefree(conn->allocptr.cookie); Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); -- cgit v1.2.1 From 24420c21915ff74a8a13c284a1fa66aaff1e847b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 May 2004 07:40:00 +0000 Subject: Simon Josefsson added a idn_free() function in libidn 0.4.5 as a reaction to Gisle's previous mail. We now use this function, and thus we require libidn 0.4.5 or later. No earler version will do. --- lib/url.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d55086fed..de7601ebd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -87,6 +87,8 @@ #ifdef USE_LIBIDN #include #include +void idn_free (void *ptr); /* prototype from idn-free.h, not provided by + libidn 0.4.5's make install! */ #endif #ifdef HAVE_OPENSSL_ENGINE_H @@ -1390,13 +1392,13 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ if(conn->host.encalloc) - (free)(conn->host.encalloc); /* encoded host name buffer, must be freed - with free() since this was allocated by - libidn */ + idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed + with idn_free() since this was allocated + by libidn */ if(conn->proxy.encalloc) - (free)(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed - with free() since this was allocated by - libidn */ + idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be + freed with idn_free() since this was + allocated by libidn */ Curl_SSL_Close(conn); /* close possibly still open sockets */ @@ -1997,7 +1999,8 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) /************************************************************* * Check name for non-ASCII and convert hostname to ACE form. *************************************************************/ - if (!is_ASCII_name(host->name)) { + if (!is_ASCII_name(host->name) && + stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { char *ace_hostname = NULL; struct SessionHandle *data = conn->data; int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); -- cgit v1.2.1 From 85b2056dc7d758e679a19e2a4afe0c3447fb2b5c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 May 2004 08:19:37 +0000 Subject: only idn_free() if built with libidn --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index de7601ebd..13ce60a15 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1391,6 +1391,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ +#ifdef USE_LIBIDN if(conn->host.encalloc) idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed with idn_free() since this was allocated @@ -1399,6 +1400,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed with idn_free() since this was allocated by libidn */ +#endif Curl_SSL_Close(conn); /* close possibly still open sockets */ -- cgit v1.2.1 From 0912015a5c34ade7acad04db43604f781cd8306e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 May 2004 12:00:15 +0000 Subject: preprocessor magic around the libidn idn_free() stuff to remain workable both with older libidn versions without idn_free() and with libidn versions that gets installed without idn-free.h --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 13ce60a15..d65f6aec9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -87,9 +87,18 @@ #ifdef USE_LIBIDN #include #include +#ifdef HAVE_IDN_FREE_H +#include +#else void idn_free (void *ptr); /* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */ #endif +#ifndef HAVE_IDN_FREE +/* if idn_free() was not found in this version of libidn, use plain free() + instead */ +#define idn_free(x) (free)(x) +#endif +#endif #ifdef HAVE_OPENSSL_ENGINE_H #include -- cgit v1.2.1 From fd802db39f77fa3985d20e461742bf24644065d6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 May 2004 21:47:29 +0000 Subject: initial support for "uploading" to file:// URLs --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d65f6aec9..188bf4c9e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2711,7 +2711,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_FILE; conn->curl_do = Curl_file; - /* no done() function */ + conn->curl_done = Curl_file_done; /* anyway, this is supposed to be the connect function so we better at least check that the file is present here! */ -- cgit v1.2.1 From 2c43d64302cc58532768e7e98fceb0e3032950cc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 26 May 2004 08:54:36 +0000 Subject: Added a new 'bit' in the connect struct named 'tunnel_proxy' that is set if a connection is tunneled through a proxy. A tunnel is done with CONNECT, either when using HTTPS or FTPS, or if explicitly enabled by the app. --- lib/url.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 188bf4c9e..65c99981e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2137,6 +2137,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.user_passwd = data->set.userpwd?1:0; conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; conn->bits.no_body = data->set.opt_no_body; + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; /* This initing continues below, see the comment "Continue connectdata * initialization here" */ @@ -2837,6 +2838,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, free(proxydup); /* free the duplicate pointer and not the modified */ } + /************************************************************* + * If the protcol is using SSL and HTTP proxy is used, we set + * the tunnel_proxy bit. + *************************************************************/ + if((conn->protocol&PROT_SSL) && conn->bits.httpproxy) + conn->bits.tunnel_proxy = TRUE; + /************************************************************* * Take care of user and password authentication stuff *************************************************************/ -- cgit v1.2.1 From aca79af7deb696cc97d7f332ef9c20bdd0096d5b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 28 May 2004 09:56:59 +0000 Subject: check for failing strdup()s --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 65c99981e..e11d58624 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2836,6 +2836,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->proxy.name = conn->proxy.rawalloc; free(proxydup); /* free the duplicate pointer and not the modified */ + if(!conn->proxy.rawalloc) + return CURLE_OUT_OF_MEMORY; } /************************************************************* @@ -2964,7 +2966,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->user = strdup(CURL_DEFAULT_USER); conn->passwd = strdup(CURL_DEFAULT_PASSWORD); - /* This is the default password, so DON'T set conn->bits.user_passwd */ } else { @@ -2972,6 +2973,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->user = strdup(user); conn->passwd = strdup(passwd); } + if(!conn->user || !conn->passwd) + return CURLE_OUT_OF_MEMORY; /************************************************************* * Check the current list of connections to see if we can -- cgit v1.2.1 From d3f796ac59f37c65c04e0bd459fda74d5da4fc70 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 2 Jun 2004 13:57:38 +0000 Subject: Made CURLOPT_UPLOAD and CURLOPT_PUT mean the same thing internally (the previous difference was not clear nor documented properly). They can now both be used interchangeably, but we prefer UPLOAD to PUT since it is a more generic term. --- lib/url.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e11d58624..f66f70ab5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -499,8 +499,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_UPLOAD: + case CURLOPT_PUT: /* - * We want to sent data to the remote host + * We want to sent data to the remote host. If this is HTTP, that equals + * using the PUT request. */ data->set.upload = va_arg(param, long)?TRUE:FALSE; if(data->set.upload) @@ -583,14 +585,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE; break; - case CURLOPT_PUT: - /* - * Use the HTTP PUT request to transfer data if this is TRUE. If this is - * FALSE, don't set the httpreq. We can't know what to revert it to! - */ - if(va_arg(param, long)) - data->set.httpreq = HTTPREQ_PUT; - break; case CURLOPT_TIMECONDITION: /* * Set HTTP time condition. This must be one of the defines in the -- cgit v1.2.1 From ea81dd9e2e163f096df884b22e823f1a0e8569f0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Jun 2004 11:41:05 +0000 Subject: Alexander Krasnostavsky's FTP third party transfer (proxy) support --- lib/url.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f66f70ab5..b53dcd1c4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1337,6 +1337,57 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.tcp_nodelay = (bool)va_arg(param, long); break; + /*********** 3rd party transfer options ***********/ + case CURLOPT_SOURCE_HOST: + /* + * Use SOURCE HOST + */ + data->set.source_host = va_arg(param, char *); + data->set.printhost = (data->set.source_host != NULL); + break; + + case CURLOPT_SOURCE_PORT: + /* + * Use SOURCE PORT + */ + data->set.source_port = va_arg(param, char *); + break; + + case CURLOPT_SOURCE_USERPWD: + /* + * Use SOURCE USER[:PASSWORD] + */ + data->set.source_userpwd = va_arg(param, char *); + break; + + case CURLOPT_SOURCE_PATH: + /* + * Use SOURCE PATH + */ + data->set.source_path = va_arg(param, char *); + break; + + case CURLOPT_PASV_HOST: + /* + * Indicates whether source or target host is passive + */ + data->set.pasvHost = va_arg(param, long)?CURL_SOURCE_PASV:CURL_TARGET_PASV; + break; + + case CURLOPT_SOURCE_PREQUOTE: + /* + * List of RAW FTP commands to use before a transfer on the source host + */ + data->set.source_prequote = va_arg(param, struct curl_slist *); + break; + + case CURLOPT_SOURCE_POSTQUOTE: + /* + * List of RAW FTP commands to use after a transfer on the source host + */ + data->set.source_postquote = va_arg(param, struct curl_slist *); + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 90037b85d1a6c46979729d0735eef094516dc31f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 9 Jun 2004 08:23:55 +0000 Subject: Alexander Krasnostavsky's fix to make libcurl build fine with configure --disable-http, which thus builds a libcurl without HTTP support. --- lib/url.c | 480 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 249 insertions(+), 231 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b53dcd1c4..2bc9e53c6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -238,6 +238,8 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_cookie_cleanup(data->cookies); } Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + + Curl_digest_cleanup(data); #endif /* free the connection cache */ @@ -245,8 +247,6 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->info.contenttype); - Curl_digest_cleanup(data); - #ifdef USE_ARES /* this destroys the channel and we cannot use it anymore after this */ ares_destroy(data->state.areschannel); @@ -555,27 +555,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.netrc_file = va_arg(param, char *); break; - case CURLOPT_FOLLOWLOCATION: - /* - * Follow Location: header hints on a HTTP-server. - */ - data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_UNRESTRICTED_AUTH: - /* - * Send authentication (user+password) when following locations, even when - * hostname changed. - */ - data->set.http_disable_hostname_check_before_authentication = - va_arg(param, long)?TRUE:FALSE; - break; - case CURLOPT_HTTP_VERSION: - /* - * This sets a requested HTTP version to be used. The value is one of - * the listed enums in curl/curl.h. - */ - data->set.httpversion = va_arg(param, long); - break; case CURLOPT_TRANSFERTEXT: /* * This option was previously named 'FTPASCII'. Renamed to work with @@ -607,117 +586,86 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ssl.version = va_arg(param, long); break; - case CURLOPT_COOKIESESSION: - /* - * Set this option to TRUE to start a new "cookie session". It will - * prevent the forthcoming read-cookies-from-file actions to accept - * cookies that are marked as being session cookies, as they belong to a - * previous session. - * - * In the original Netscape cookie spec, "session cookies" are cookies - * with no expire date set. RFC2109 describes the same action if no - * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds - * a 'Discard' action that can enforce the discard even for cookies that - * have a Max-Age. - * - * We run mostly with the original cookie spec, as hardly anyone implements - * anything else. - */ - data->set.cookiesession = (bool)va_arg(param, long); - break; - #ifndef CURL_DISABLE_HTTP - case CURLOPT_COOKIEFILE: + case CURLOPT_AUTOREFERER: /* - * Set cookie file to read and parse. Can be used multiple times. + * Switch on automatic referer that gets set if curl follows locations. */ - cookiefile = (char *)va_arg(param, void *); - if(cookiefile) { - struct curl_slist *cl; - /* append the cookie file name to the list of file names, and deal with - them later */ - cl = curl_slist_append(data->change.cookielist, cookiefile); - - if(!cl) - return CURLE_OUT_OF_MEMORY; - - data->change.cookielist = cl; - } + data->set.http_auto_referer = va_arg(param, long)?1:0; break; - case CURLOPT_COOKIEJAR: + case CURLOPT_ENCODING: /* - * Set cookie file name to dump all cookies to when we're done. + * String to use at the value of Accept-Encoding header. + * + * If the encoding is set to "" we use an Accept-Encoding header that + * encompasses all the encodings we support. + * If the encoding is set to NULL we don't send an Accept-Encoding header + * and ignore an received Content-Encoding header. + * */ - data->set.cookiejar = (char *)va_arg(param, void *); + data->set.encoding = va_arg(param, char *); + if(data->set.encoding && !*data->set.encoding) + data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; + break; + case CURLOPT_FOLLOWLOCATION: /* - * Activate the cookie parser. This may or may not already - * have been made. + * Follow Location: header hints on a HTTP-server. */ - data->cookies = Curl_cookie_init(data, NULL, data->cookies, - data->set.cookiesession); + data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; break; -#endif - case CURLOPT_WRITEHEADER: + case CURLOPT_UNRESTRICTED_AUTH: /* - * Custom pointer to pass the header write callback function + * Send authentication (user+password) when following locations, even when + * hostname changed. */ - data->set.writeheader = (void *)va_arg(param, void *); + data->set.http_disable_hostname_check_before_authentication = + va_arg(param, long)?TRUE:FALSE; break; - case CURLOPT_COOKIE: + + case CURLOPT_MAXREDIRS: /* - * Cookie string to send to the remote server in the request. + * The maximum amount of hops you allow curl to follow Location: + * headers. This should mostly be used to detect never-ending loops. */ - data->set.cookie = va_arg(param, char *); + data->set.maxredirs = va_arg(param, long); break; - case CURLOPT_ERRORBUFFER: - /* - * Error buffer provided by the caller to get the human readable - * error string in. - */ - data->set.errorbuffer = va_arg(param, char *); + + case CURLOPT_POST: + /* Does this option serve a purpose anymore? Yes it does, when + CURLOPT_POSTFIELDS isn't used and the POST data is read off the + callback! */ + if(va_arg(param, long)) + data->set.httpreq = HTTPREQ_POST; break; - case CURLOPT_FILE: + + case CURLOPT_POSTFIELDS: /* - * FILE pointer to write to or include in the data write callback + * A string with POST data. Makes curl HTTP POST. */ - data->set.out = va_arg(param, FILE *); + data->set.postfields = va_arg(param, char *); + if(data->set.postfields) + data->set.httpreq = HTTPREQ_POST; break; - case CURLOPT_FTPPORT: + + case CURLOPT_POSTFIELDSIZE: /* - * Use FTP PORT, this also specifies which IP address to use + * The size of the POSTFIELD data to prevent libcurl to do strlen() to + * figure it out. Enables binary posts. */ - data->set.ftpport = va_arg(param, char *); - data->set.ftp_use_port = data->set.ftpport?1:0; - break; - - case CURLOPT_FTP_USE_EPRT: - data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE; - break; - - case CURLOPT_FTP_USE_EPSV: - data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; + data->set.postfieldsize = va_arg(param, long); break; - case CURLOPT_HTTPHEADER: + case CURLOPT_POSTFIELDSIZE_LARGE: /* - * Set a list with HTTP headers to use (or replace internals with) + * The size of the POSTFIELD data to prevent libcurl to do strlen() to + * figure it out. Enables binary posts. */ - data->set.headers = va_arg(param, struct curl_slist *); + data->set.postfieldsize = va_arg(param, curl_off_t); break; - case CURLOPT_CUSTOMREQUEST: - /* - * Set a custom string to use as request - */ - data->set.customrequest = va_arg(param, char *); - /* we don't set - data->set.httpreq = HTTPREQ_CUSTOM; - here, we continue as if we were using the already set type - and this just changes the actual request keyword */ - break; case CURLOPT_HTTPPOST: /* * Set to make us do HTTP POST @@ -727,116 +675,134 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.httpreq = HTTPREQ_POST_FORM; break; - case CURLOPT_HTTPGET: + case CURLOPT_REFERER: /* - * Set to force us do HTTP GET + * String to set in the HTTP Referer: field. */ - if(va_arg(param, long)) { - data->set.httpreq = HTTPREQ_GET; - data->set.upload = FALSE; /* switch off upload */ + 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_INFILE: + case CURLOPT_USERAGENT: /* - * FILE pointer to read the file to be uploaded from. Or possibly - * used as argument to the read callback. + * String to use in the HTTP User-Agent field */ - data->set.in = va_arg(param, FILE *); + data->set.useragent = va_arg(param, char *); break; - case CURLOPT_INFILESIZE: + + case CURLOPT_HTTPHEADER: /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. + * Set a list with HTTP headers to use (or replace internals with) */ - data->set.infilesize = va_arg(param, long); + data->set.headers = va_arg(param, struct curl_slist *); break; - case CURLOPT_INFILESIZE_LARGE: + + case CURLOPT_HTTP200ALIASES: /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. + * Set a list of aliases for HTTP 200 in response header */ - data->set.infilesize = va_arg(param, curl_off_t); + data->set.http200aliases = va_arg(param, struct curl_slist *); break; - case CURLOPT_LOW_SPEED_LIMIT: + + case CURLOPT_COOKIE: /* - * The low speed limit that if transfers are below this for - * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. + * Cookie string to send to the remote server in the request. */ - data->set.low_speed_limit=va_arg(param, long); + data->set.cookie = va_arg(param, char *); break; - case CURLOPT_LOW_SPEED_TIME: + + case CURLOPT_COOKIEFILE: /* - * The low speed time that if transfers are below the set - * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. + * Set cookie file to read and parse. Can be used multiple times. */ - data->set.low_speed_time=va_arg(param, long); + cookiefile = (char *)va_arg(param, void *); + if(cookiefile) { + struct curl_slist *cl; + /* append the cookie file name to the list of file names, and deal with + them later */ + cl = curl_slist_append(data->change.cookielist, cookiefile); + + if(!cl) + return CURLE_OUT_OF_MEMORY; + + data->change.cookielist = cl; + } break; - case CURLOPT_URL: + + case CURLOPT_COOKIEJAR: /* - * The URL to fetch. + * Set cookie file name to dump all cookies to when we're done. */ - if(data->change.url_alloc) { - /* the already set URL is allocated, free it first! */ - free(data->change.url); - data->change.url_alloc=FALSE; - } - data->set.set_url = va_arg(param, char *); - data->change.url = data->set.set_url; - data->change.url_changed = TRUE; - break; - case CURLOPT_PORT: + data->set.cookiejar = (char *)va_arg(param, void *); + /* - * The port number to use when getting the URL + * Activate the cookie parser. This may or may not already + * have been made. */ - data->set.use_port = va_arg(param, long); - break; - case CURLOPT_POST: - /* Does this option serve a purpose anymore? Yes it does, when - CURLOPT_POSTFIELDS isn't used and the POST data is read off the - callback! */ - if(va_arg(param, long)) - data->set.httpreq = HTTPREQ_POST; + data->cookies = Curl_cookie_init(data, NULL, data->cookies, + data->set.cookiesession); break; - case CURLOPT_POSTFIELDS: + + case CURLOPT_COOKIESESSION: /* - * A string with POST data. Makes curl HTTP POST. + * Set this option to TRUE to start a new "cookie session". It will + * prevent the forthcoming read-cookies-from-file actions to accept + * cookies that are marked as being session cookies, as they belong to a + * previous session. + * + * In the original Netscape cookie spec, "session cookies" are cookies + * with no expire date set. RFC2109 describes the same action if no + * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds + * a 'Discard' action that can enforce the discard even for cookies that + * have a Max-Age. + * + * We run mostly with the original cookie spec, as hardly anyone implements + * anything else. */ - data->set.postfields = va_arg(param, char *); - if(data->set.postfields) - data->set.httpreq = HTTPREQ_POST; + data->set.cookiesession = (bool)va_arg(param, long); break; - case CURLOPT_POSTFIELDSIZE: + + case CURLOPT_HTTPGET: /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. + * Set to force us do HTTP GET */ - data->set.postfieldsize = va_arg(param, long); + if(va_arg(param, long)) { + data->set.httpreq = HTTPREQ_GET; + data->set.upload = FALSE; /* switch off upload */ + } break; - case CURLOPT_POSTFIELDSIZE_LARGE: + + case CURLOPT_HTTP_VERSION: /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. + * This sets a requested HTTP version to be used. The value is one of + * the listed enums in curl/curl.h. */ - data->set.postfieldsize = va_arg(param, curl_off_t); + data->set.httpversion = va_arg(param, long); break; - case CURLOPT_REFERER: + + case CURLOPT_HTTPPROXYTUNNEL: /* - * String to set in the HTTP Referer: field. + * Tunnel operations through the proxy instead of normal proxy use */ - 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; + data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE; break; - case CURLOPT_AUTOREFERER: + + case CURLOPT_CUSTOMREQUEST: /* - * Switch on automatic referer that gets set if curl follows locations. + * Set a custom string to use as request */ - data->set.http_auto_referer = va_arg(param, long)?1:0; + data->set.customrequest = va_arg(param, char *); + + /* we don't set + data->set.httpreq = HTTPREQ_CUSTOM; + here, we continue as if we were using the already set type + and this just changes the actual request keyword */ break; + case CURLOPT_PROXY: /* * Set proxy server:port to use as HTTP proxy. @@ -857,58 +823,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) 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->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE; - break; + case CURLOPT_PROXYPORT: /* * Explicitly set HTTP proxy port number. */ 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->set.timeout = va_arg(param, long); - break; - case CURLOPT_CONNECTTIMEOUT: - /* - * The maximum time you allow curl to use to connect. - */ - 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->set.maxredirs = va_arg(param, long); - break; - case CURLOPT_USERAGENT: - /* - * String to use in the HTTP User-Agent field - */ - data->set.useragent = va_arg(param, char *); - break; - case CURLOPT_ENCODING: - /* - * String to use at the value of Accept-Encoding header. - * - * If the encoding is set to "" we use an Accept-Encoding header that - * encompasses all the encodings we support. - * If the encoding is set to NULL we don't send an Accept-Encoding header - * and ignore an received Content-Encoding header. - * - */ - data->set.encoding = va_arg(param, char *); - if(data->set.encoding && !*data->set.encoding) - data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; - break; case CURLOPT_HTTPAUTH: /* @@ -949,6 +870,110 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.proxyauth = auth; } break; +#endif /* CURL_DISABLE_HTTP */ + + case CURLOPT_WRITEHEADER: + /* + * Custom pointer to pass the header write callback function + */ + data->set.writeheader = (void *)va_arg(param, void *); + break; + case CURLOPT_ERRORBUFFER: + /* + * Error buffer provided by the caller to get the human readable + * error string in. + */ + data->set.errorbuffer = va_arg(param, char *); + break; + case CURLOPT_FILE: + /* + * FILE pointer to write to or include in the data write callback + */ + data->set.out = va_arg(param, FILE *); + break; + case CURLOPT_FTPPORT: + /* + * Use FTP PORT, this also specifies which IP address to use + */ + data->set.ftpport = va_arg(param, char *); + data->set.ftp_use_port = data->set.ftpport?1:0; + break; + + case CURLOPT_FTP_USE_EPRT: + data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE; + break; + + case CURLOPT_FTP_USE_EPSV: + data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; + break; + + case CURLOPT_INFILE: + /* + * FILE pointer to read the file to be uploaded from. Or possibly + * used as argument to the read callback. + */ + 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->set.infilesize = va_arg(param, long); + break; + case CURLOPT_INFILESIZE_LARGE: + /* + * If known, this should inform curl about the file size of the + * to-be-uploaded file. + */ + data->set.infilesize = va_arg(param, curl_off_t); + 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->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->set.low_speed_time=va_arg(param, long); + break; + case CURLOPT_URL: + /* + * The URL to fetch. + */ + if(data->change.url_alloc) { + /* the already set URL is allocated, free it first! */ + free(data->change.url); + data->change.url_alloc=FALSE; + } + data->set.set_url = va_arg(param, char *); + data->change.url = data->set.set_url; + data->change.url_changed = TRUE; + break; + case CURLOPT_PORT: + /* + * The port number to use when getting the URL + */ + data->set.use_port = va_arg(param, long); + break; + case CURLOPT_TIMEOUT: + /* + * The maximum time you allow curl to use for a single transfer + * operation. + */ + data->set.timeout = va_arg(param, long); + break; + case CURLOPT_CONNECTTIMEOUT: + /* + * The maximum time you allow curl to use to connect. + */ + data->set.connecttimeout = va_arg(param, long); + break; case CURLOPT_USERPWD: /* @@ -1262,22 +1287,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->hostcache = data->share->hostcache; } - +#ifndef CURL_DISABLE_HTTP if(data->share->cookies) { /* use shared cookie list, first free own one if any */ if (data->cookies) Curl_cookie_cleanup(data->cookies); data->cookies = data->share->cookies; } - +#endif /* CURL_DISABLE_HTTP */ Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } - +#ifndef CURL_DISABLE_HTTP /* check cookie list is set */ if(!data->cookies) data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE ); - +#endif /* CURL_DISABLE_HTTP */ /* check for host cache not needed, * it will be done by curl_easy_perform */ } @@ -1297,13 +1322,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.private = va_arg(param, char *); break; - case CURLOPT_HTTP200ALIASES: - /* - * Set a list of aliases for HTTP 200 in response header - */ - data->set.http200aliases = va_arg(param, struct curl_slist *); - break; - case CURLOPT_MAXFILESIZE: /* * Set the maximum size of a file to download. -- cgit v1.2.1 From 9f341f9ce5ff2cc85a4cbdd38cd4b5c68b02504d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 10 Jun 2004 11:06:21 +0000 Subject: Gisle Vanem's improved verbose output and timeout handling when connecting to a host name that resolves to multiple IP addresses. --- lib/url.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2bc9e53c6..f83e49435 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1990,22 +1990,18 @@ static CURLcode ConnectPlease(struct connectdata *conn, static void verboseconnect(struct connectdata *conn) { struct SessionHandle *data = conn->data; - const char *host=NULL; - char addrbuf[256]; - - /* Get a printable version of the network address. */ + char addrbuf[256] = ""; #ifdef ENABLE_IPV6 - struct addrinfo *ai = conn->serv_addr; - host = Curl_printable_address(ai->ai_family, ai->ai_addr, - addrbuf, sizeof(addrbuf)); + const Curl_ipconnect *addr = conn->serv_addr; #else - struct in_addr in; - (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); - host = Curl_inet_ntop(AF_INET, &in, addrbuf, sizeof(addrbuf)); + const Curl_ipconnect *addr = &conn->serv_addr.sin_addr; #endif + + /* Get a printable version of the network address. */ + Curl_printable_address(addr, addrbuf, sizeof(addrbuf)); infof(data, "Connected to %s (%s) port %d\n", - conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname, - host?host:"", conn->port); + conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, + addrbuf[0] ? addrbuf : "??", conn->port); } /* -- cgit v1.2.1 From bd3d5a17b49dfdb9029376961f429a21dd045af4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 18 Jun 2004 06:20:43 +0000 Subject: Gisle's "SSL patch" from June 16th 2004, modified by me as discussed on the mailing list. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f83e49435..e165b3730 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1892,7 +1892,7 @@ static int handleSock5Proxy(const char *proxy_name, } #else failf(conn->data, - "%s:%d has an internal error an needs to be fixed to work", + "%s:%d has an internal error and needs to be fixed to work", __FILE__, __LINE__); #endif } -- cgit v1.2.1 From d73425061ab5154b1d1218bc1f6f5c3bfea26b5c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 22 Jun 2004 15:23:01 +0000 Subject: Moved the "About to connect() to" text to the place where the host name is actually known, as before this text lied when used in i.e FTP. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e165b3730..4c4453a77 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1940,6 +1940,11 @@ static CURLcode ConnectPlease(struct connectdata *conn, { CURLcode result; Curl_ipconnect *addr; + struct SessionHandle *data = conn->data; + char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; + + infof(data, "About to connect() to %s port %d\n", + hostname, conn->port); /************************************************************* * Connect to server/proxy -- cgit v1.2.1 From c39858aac0584716282dcb097ce9d972b43dbcb2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 24 Jun 2004 07:43:48 +0000 Subject: Source cleanups. The major one being that we now _always_ use a Curl_addrinfo linked list for name resolved data, even on hosts/systems with only IPv4 stacks as this simplifies a lot of code. --- lib/url.c | 68 ++++++++++++++++++++++++--------------------------------------- 1 file changed, 26 insertions(+), 42 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4c4453a77..be46e7bcb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -273,13 +273,11 @@ CURLcode Curl_open(struct SessionHandle **curl) CURLcode res = CURLE_OK; struct SessionHandle *data; /* Very simple start-up: alloc the struct, init it with zeroes and return */ - data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle)); + data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle)); if(!data) /* this is a very serious error */ return CURLE_OUT_OF_MEMORY; - memset(data, 0, sizeof(struct SessionHandle)); - #ifdef USE_ARES if(ARES_SUCCESS != ares_init(&data->state.areschannel)) { free(data); @@ -1859,7 +1857,6 @@ static int handleSock5Proxy(const char *proxy_name, socksreq[3] = 1; /* IPv4 = 1 */ { -#ifndef ENABLE_IPV6 struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; int rc = Curl_resolv(conn, conn->host.name, conn->remote_port, &dns); @@ -1877,24 +1874,28 @@ static int handleSock5Proxy(const char *proxy_name, */ if(dns) hp=dns->addr; - if (hp && hp->h_addr_list[0]) { - socksreq[4] = ((char*)hp->h_addr_list[0])[0]; - socksreq[5] = ((char*)hp->h_addr_list[0])[1]; - socksreq[6] = ((char*)hp->h_addr_list[0])[2]; - socksreq[7] = ((char*)hp->h_addr_list[0])[3]; + if (hp) { + char buf[64]; + unsigned short ip[4]; + Curl_printable_address(hp, buf, sizeof(buf)); + + if(4 == sscanf( buf, "%hu.%hu.%hu.%hu", + &ip[0], &ip[1], &ip[2], &ip[3])) { + socksreq[4] = ip[0]; + socksreq[5] = ip[1]; + socksreq[6] = ip[2]; + socksreq[7] = ip[3]; + } + else + hp = NULL; /* fail! */ Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ } - else { + if(!hp) { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", conn->host.name); return 1; } -#else - failf(conn->data, - "%s:%d has an internal error and needs to be fixed to work", - __FILE__, __LINE__); -#endif } *((unsigned short*)&socksreq[8]) = htons(conn->remote_port); @@ -1939,7 +1940,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, bool *connected) { CURLcode result; - Curl_ipconnect *addr; + Curl_addrinfo *addr; struct SessionHandle *data = conn->data; char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; @@ -1951,25 +1952,13 @@ static CURLcode ConnectPlease(struct connectdata *conn, *************************************************************/ result= Curl_connecthost(conn, hostaddr, - conn->port, &conn->sock[FIRSTSOCKET], &addr, connected); if(CURLE_OK == result) { - /* All is cool, then we store the current information from the hostaddr - struct to the serv_addr, as it might be needed later. The address - returned from the function above is crucial here. */ - conn->connect_addr = hostaddr; - -#ifdef ENABLE_IPV6 - conn->serv_addr = addr; -#else - memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr)); - memcpy((char *)&(conn->serv_addr.sin_addr), - (struct in_addr *)addr, sizeof(struct in_addr)); - conn->serv_addr.sin_family = hostaddr->addr->h_addrtype; - conn->serv_addr.sin_port = htons((unsigned short)conn->port); -#endif + /* All is cool, then we store the current information */ + conn->dns_entry = hostaddr; + conn->ip_addr = addr; if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { return handleSock5Proxy(conn->proxyuser, @@ -1995,15 +1984,10 @@ static CURLcode ConnectPlease(struct connectdata *conn, static void verboseconnect(struct connectdata *conn) { struct SessionHandle *data = conn->data; - char addrbuf[256] = ""; -#ifdef ENABLE_IPV6 - const Curl_ipconnect *addr = conn->serv_addr; -#else - const Curl_ipconnect *addr = &conn->serv_addr.sin_addr; -#endif + char addrbuf[256]; /* Get a printable version of the network address. */ - Curl_printable_address(addr, addrbuf, sizeof(addrbuf)); + Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf)); infof(data, "Connected to %s (%s) port %d\n", conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, addrbuf[0] ? addrbuf : "??", conn->port); @@ -3221,8 +3205,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->bits.reuse) { /* re-used connection, no resolving is necessary */ hostaddr = NULL; - conn->connect_addr = NULL; /* we don't connect now so we don't have any - fresh connect_addr struct to point to */ + conn->dns_entry = NULL; /* we don't connect now so we don't have any fresh + dns entry struct to point to */ } else { /* this is a fresh connect */ @@ -3476,8 +3460,8 @@ CURLcode Curl_done(struct connectdata **connp, conn->newurl = NULL; } - if(conn->connect_addr) - Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */ + if(conn->dns_entry) + Curl_resolv_unlock(conn->data, conn->dns_entry); /* done with this */ #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ -- cgit v1.2.1 From 00ee738fdd3a32d47060e041d18ee8300980e350 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 24 Jun 2004 09:14:59 +0000 Subject: typecasts to prevent warnings --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index be46e7bcb..59d674ca1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1881,10 +1881,10 @@ static int handleSock5Proxy(const char *proxy_name, if(4 == sscanf( buf, "%hu.%hu.%hu.%hu", &ip[0], &ip[1], &ip[2], &ip[3])) { - socksreq[4] = ip[0]; - socksreq[5] = ip[1]; - socksreq[6] = ip[2]; - socksreq[7] = ip[3]; + socksreq[4] = (unsigned char)ip[0]; + socksreq[5] = (unsigned char)ip[1]; + socksreq[6] = (unsigned char)ip[2]; + socksreq[7] = (unsigned char)ip[3]; } else hp = NULL; /* fail! */ -- cgit v1.2.1 From 185baf036b9bcfe1386a6fd1549ca5403ec66812 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 Jun 2004 11:09:16 +0000 Subject: NOBODY set TRUE after a POST makes a good HEAD now --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 59d674ca1..3fbc7b3e6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -488,6 +488,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Do not include the body part in the output data stream. */ data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE; + if(data->set.opt_no_body) + /* in HTTP lingo, this means using the HEAD request */ + data->set.httpreq = HTTPREQ_HEAD; break; case CURLOPT_FAILONERROR: /* -- cgit v1.2.1 From f05d47ddd6d706dcda05504da8c90a111d53f67b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 1 Jul 2004 07:43:20 +0000 Subject: variable type cleanup to fix picky compiler warnings --- lib/url.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3fbc7b3e6..1ed05f021 100644 --- a/lib/url.c +++ b/lib/url.c @@ -151,12 +151,12 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "memdebug.h" /* Local static prototypes */ -static int ConnectionKillOne(struct SessionHandle *data); +static long ConnectionKillOne(struct SessionHandle *data); static bool ConnectionExists(struct SessionHandle *data, struct connectdata *needle, struct connectdata **usethis); -static unsigned int ConnectionStore(struct SessionHandle *data, - struct connectdata *conn); +static long ConnectionStore(struct SessionHandle *data, + struct connectdata *conn); static bool safe_strequal(char* str1, char* str2); #ifndef USE_ARES @@ -411,17 +411,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { long newconnects= va_arg(param, long); struct connectdata **newptr; + long i; 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->state.numconnects; i++) Curl_disconnect(data->state.connects[i]); } if(newconnects) { - int i; newptr= (struct connectdata **) realloc(data->state.connects, sizeof(struct connectdata *) * newconnects); @@ -577,7 +576,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * This is the value to compare with the remote document with the * method set with CURLOPT_TIMECONDITION */ - data->set.timevalue = va_arg(param, long); + data->set.timevalue = (time_t)va_arg(param, long); break; case CURLOPT_SSLVERSION: /* @@ -1633,14 +1632,14 @@ ConnectionExists(struct SessionHandle *data, * should take the previously set policy into account when deciding which * of the connections to kill. */ -static int +static long ConnectionKillOne(struct SessionHandle *data) { long i; struct connectdata *conn; - int highscore=-1; - int connindex=-1; - int score; + long highscore=-1; + long connindex=-1; + long score; struct timeval now; now = Curl_tvnow(); @@ -1697,7 +1696,7 @@ ConnectionKillOne(struct SessionHandle *data) * The given connection should be unique. That must've been checked prior to * this call. */ -static unsigned int +static long ConnectionStore(struct SessionHandle *data, struct connectdata *conn) { @@ -1787,8 +1786,8 @@ static int handleSock5Proxy(const char *proxy_name, /* Needs user name and password */ int userlen, pwlen, len; - userlen = strlen(proxy_name); - pwlen = proxy_password?strlen(proxy_password):0; + userlen = (int)strlen(proxy_name); + pwlen = proxy_password?(int)strlen(proxy_password):0; /* username/password request looks like * +----+------+----------+------+----------+ @@ -2108,7 +2107,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, CURLcode result=CURLE_OK; struct connectdata *conn; struct connectdata *conn_temp; - int urllen; + size_t urllen; struct Curl_dns_entry *hostaddr; #ifdef HAVE_ALARM unsigned int prev_alarm=0; @@ -2407,7 +2406,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; while(nope) { - unsigned int namelen; + size_t namelen; char *endptr = strchr(conn->host.name, ':'); if(endptr) namelen=endptr-conn->host.name; @@ -3290,7 +3289,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, failf(data, "Previous alarm fired off!"); } else - alarm(alarm_set); + alarm((unsigned int)alarm_set); } else alarm(0); /* just shut it off */ -- cgit v1.2.1 From d2e6a0583a6fd310b946dfd7f88942b0d9650f4c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 4 Jul 2004 21:36:14 +0000 Subject: made 'connectindex' a long variable to prevent compiler warnings when implicitly converting it to int --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1ed05f021..c97ab6a1f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1453,7 +1453,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(-1 != conn->connectindex) { /* unlink ourselves! */ - infof(data, "Closing connection #%d\n", conn->connectindex); + infof(data, "Closing connection #%ld\n", conn->connectindex); data->state.connects[conn->connectindex] = NULL; } @@ -3123,7 +3123,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, *in_connect = conn; /* return this instead! */ - infof(data, "Re-using existing connection! (#%d) with host %s\n", + infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->host.dispname); } else { @@ -3500,7 +3500,7 @@ CURLcode Curl_done(struct connectdata **connp, result = res2; } else - infof(data, "Connection #%d to host %s left intact\n", + infof(data, "Connection #%ld to host %s left intact\n", conn->connectindex, conn->host.dispname); return result; -- cgit v1.2.1 From 17841a20e35b9406cb838b7bbcc1b4cf8e6b7c1f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 4 Jul 2004 21:37:35 +0000 Subject: explicit typecasts when converting from long to int to avoid warnings --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c97ab6a1f..e6c742219 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1861,7 +1861,7 @@ static int handleSock5Proxy(const char *proxy_name, { struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; - int rc = Curl_resolv(conn, conn->host.name, conn->remote_port, &dns); + int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns); if(rc == CURLRESOLV_ERROR) return 1; @@ -3222,7 +3222,7 @@ 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->host.name, conn->port, &hostaddr); + rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr); if(rc == CURLRESOLV_PENDING) *async = TRUE; @@ -3239,7 +3239,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, fix_hostname(conn, &conn->proxy); /* resolve proxy */ - rc = Curl_resolv(conn, conn->proxy.name, conn->port, &hostaddr); + rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr); if(rc == CURLRESOLV_PENDING) *async = TRUE; -- cgit v1.2.1 From 03cb3b9db10831ff76133df15722cc9c8878ae99 Mon Sep 17 00:00:00 2001 From: Gunter Knauf Date: Sat, 10 Jul 2004 23:11:22 +0000 Subject: ifdef keep_sigact since its only used when SIGALRM is defined. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e6c742219..467ae94be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2118,6 +2118,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, int rc; bool reuse; +#ifdef SIGALRM #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ bool keep_copysig=FALSE; /* did copy it? */ @@ -2125,6 +2126,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_SIGNAL void *keep_sigact; /* store the old handler here */ #endif +#endif #endif *addr = NULL; /* nothing yet */ -- cgit v1.2.1 From b9f1dd7691f3de2dc3c333579340f55aff72198d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 28 Jul 2004 21:27:33 +0000 Subject: Bertrand Demiddelaer fixed the host name to get setup properly even when a connection is re-used, when a proxy is in use. --- lib/url.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 467ae94be..42ac2fee6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3071,10 +3071,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.user_passwd = old_conn->bits.user_passwd; conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; + /* host can change, when doing keepalive with a proxy ! */ + if (conn->bits.httpproxy) { + free(conn->host.rawalloc); + conn->host=old_conn->host; + } + /* get the newly set value, not the old one */ conn->bits.no_body = old_conn->bits.no_body; - free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ + if (!conn->bits.httpproxy) + free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ free(conn->pathbuffer); /* free the newly allocated path pointer */ conn->pathbuffer = old_conn->pathbuffer; /* use the old one */ @@ -3126,7 +3133,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, *in_connect = conn; /* return this instead! */ infof(data, "Re-using existing connection! (#%ld) with host %s\n", - conn->connectindex, conn->host.dispname); + conn->connectindex, + conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); } else { /* @@ -3211,6 +3219,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, hostaddr = NULL; conn->dns_entry = NULL; /* we don't connect now so we don't have any fresh dns entry struct to point to */ + + if (conn->bits.httpproxy) + fix_hostname(conn, &conn->host); } else { /* this is a fresh connect */ @@ -3503,7 +3514,8 @@ CURLcode Curl_done(struct connectdata **connp, } else infof(data, "Connection #%ld to host %s left intact\n", - conn->connectindex, conn->host.dispname); + conn->connectindex, + conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); return result; } -- cgit v1.2.1 From 0cfa9b52ae28b252acf7b9ca5a374ad4dbdab864 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Jul 2004 08:06:33 +0000 Subject: prevent all the sig and alarm stuff when using ares --- lib/url.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 42ac2fee6..5b10eb310 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2109,7 +2109,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, struct connectdata *conn_temp; size_t urllen; struct Curl_dns_entry *hostaddr; -#ifdef HAVE_ALARM +#if defined(HAVE_ALARM) && !defined(USE_ARES) unsigned int prev_alarm=0; #endif char endbracket; @@ -2118,6 +2118,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, int rc; bool reuse; +#ifndef USE_ARES #ifdef SIGALRM #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ @@ -2125,9 +2126,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else #ifdef HAVE_SIGNAL void *keep_sigact; /* store the old handler here */ -#endif -#endif -#endif +#endif /* HAVE_SIGNAL */ +#endif /* HAVE_SIGACTION */ +#endif /* SIGALRM */ +#endif /* USE_ARES */ *addr = NULL; /* nothing yet */ *async = FALSE; @@ -3266,7 +3268,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } *addr = hostaddr; -#if defined(HAVE_ALARM) && defined(SIGALRM) +#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { #ifdef HAVE_SIGACTION if(keep_copysig) { -- cgit v1.2.1 From d5bdf5f89c482d2da64fc0785306a7410b29b556 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Aug 2004 13:21:32 +0000 Subject: Ok, setting CURLOPT_POST to 0 will now convert the request to a GET (this remains undocumented as this is not the way we recommend) --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5b10eb310..23100fc13 100644 --- a/lib/url.c +++ b/lib/url.c @@ -639,6 +639,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) callback! */ if(va_arg(param, long)) data->set.httpreq = HTTPREQ_POST; + else + data->set.httpreq = HTTPREQ_GET; break; case CURLOPT_POSTFIELDS: -- cgit v1.2.1 From 2646af106b04480fa5b063625deb5feb25c8df65 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 16 Aug 2004 13:25:30 +0000 Subject: allow a custom "Accept-Encoding:" header override the internally set one that gets set with CURLOPT_ENCODING --- lib/url.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 23100fc13..8099688df 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3348,14 +3348,6 @@ static CURLcode SetupConnection(struct connectdata *conn, } } - if(data->set.encoding) { - Curl_safefree(conn->allocptr.accept_encoding); - conn->allocptr.accept_encoding = - aprintf("Accept-Encoding: %s\015\012", data->set.encoding); - if(!conn->allocptr.accept_encoding) - return CURLE_OUT_OF_MEMORY; - } - conn->bytecount = 0; conn->headerbytecount = 0; -- cgit v1.2.1 From b8b56248bddc646bf8d262dc9c5b45ce68a1ef08 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Sep 2004 20:58:51 +0000 Subject: - Bug report #1025986. When following a Location: with a custom Host: header replacement, curl only replaced the Host: header on the initial request and didn't replace it on the following ones. This resulted in requests with two Host: headers. Now, curl checks if the location is on the same host as the initial request and then continues to replace the Host: header. And when it moves to another host, it doesn't replace the Host: header but it also doesn't make the second Host: header get used in the request. This change is verified by the two new test cases 184 and 185. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8099688df..8bf89cf01 100644 --- a/lib/url.c +++ b/lib/url.c @@ -211,7 +211,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->change.cookielist) /* clean up list if any */ curl_slist_free_all(data->change.cookielist); - Curl_safefree(data->state.auth_host); + Curl_safefree(data->state.first_host); Curl_safefree(data->state.scratch); if(data->change.proxy_alloc) -- cgit v1.2.1 From 6a06667cc0a6915510a7f3d789a0bcf470a9b7d8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Sep 2004 21:45:16 +0000 Subject: Added CURLOPT_FTPSSLAUTH --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8bf89cf01..9e915f4fa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1338,6 +1338,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long); break; + case CURLOPT_FTPSSLAUTH: + /* + * Set a specific auth for FTP-SSL transfers. + */ + data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long); + break; + case CURLOPT_IPRESOLVE: data->set.ip_version = va_arg(param, long); break; -- cgit v1.2.1 From c18968718827979b6fdb71addf8d145c5ef64019 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 25 Sep 2004 21:28:26 +0000 Subject: allow setting CURLOPT_SSLENGINE to NULL even if no SSL engine is supported --- lib/url.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9e915f4fa..611d938cf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1125,12 +1125,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * String that holds the SSL crypto engine. */ -#ifdef HAVE_OPENSSL_ENGINE_H { const char *cpTemp = va_arg(param, char *); - ENGINE *e; if (cpTemp && cpTemp[0]) { - e = ENGINE_by_id(cpTemp); +#ifdef HAVE_OPENSSL_ENGINE_H + ENGINE *e = ENGINE_by_id(cpTemp); if (e) { if (data->engine) { ENGINE_free(data->engine); @@ -1141,12 +1140,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) failf(data, "SSL Engine '%s' not found", cpTemp); return CURLE_SSL_ENGINE_NOTFOUND; } +#else + failf(data, "SSL Engine not supported"); + return CURLE_SSL_ENGINE_NOTFOUND; +#endif } } break; -#else - return CURLE_SSL_ENGINE_NOTFOUND; -#endif + case CURLOPT_SSLENGINE_DEFAULT: /* * flag to set engine as default. -- cgit v1.2.1 From 1003628103d98b3a3c077a3531c71e66d50a0085 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 28 Sep 2004 07:11:32 +0000 Subject: Only active the engine code if ssl is enabled. This is how the actual engine member in the struct is used. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 611d938cf..3f40b6b61 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1128,7 +1128,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { const char *cpTemp = va_arg(param, char *); if (cpTemp && cpTemp[0]) { -#ifdef HAVE_OPENSSL_ENGINE_H +#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) ENGINE *e = ENGINE_by_id(cpTemp); if (e) { if (data->engine) { @@ -1152,7 +1152,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * flag to set engine as default. */ -#ifdef HAVE_OPENSSL_ENGINE_H +#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) if (data->engine) { if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) { #ifdef DEBUG -- cgit v1.2.1 From 19b284c21452b2c50924de3e0a04f5ed8040430d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 2 Oct 2004 13:01:44 +0000 Subject: Gisle Vanem provided code that displays an error message when the (libidn based) IDN conversion fails. This is really due to a missing suitable function in the libidn API that I hope we can remove once libidn gets a function like this. --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f40b6b61..c0921ced4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -116,6 +116,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "progress.h" #include "cookie.h" #include "strequal.h" +#include "strerror.h" #include "escape.h" #include "strtok.h" #include "share.h" @@ -2078,8 +2079,8 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) infof (data, "Input domain encoded as `%s'\n", stringprep_locale_charset ()); if (rc != IDNA_SUCCESS) - infof(data, "Failed to convert %s to ACE; IDNA error %d\n", - host->name, rc); + infof(data, "Failed to convert %s to ACE; %s\n", + host->name, Curl_idn_strerror(conn,rc)); else { host->encalloc = ace_hostname; /* change the name pointer to point to the encoded hostname */ -- cgit v1.2.1 From 95def48071e54c769ee063ddf53f05c9595602d2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 4 Oct 2004 10:36:51 +0000 Subject: Made the dns entry remain locked while a connection to the host remains to allow verbose output during this period. Bertrand Demiddelaer reported and helped fixing. --- lib/url.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c0921ced4..9ac054a68 100644 --- a/lib/url.c +++ b/lib/url.c @@ -204,6 +204,12 @@ CURLcode Curl_close(struct SessionHandle *data) /* Loop through all open connections and kill them one by one */ while(-1 != ConnectionKillOne(data)); + if ( ! (data->share && data->share->hostcache) ) { + if ( !Curl_global_host_cache_use(data)) { + Curl_hash_destroy(data->hostcache); + } + } + #ifdef USE_SSLEAY /* Close down all open SSL info and sessions */ Curl_SSL_Close_All(data); @@ -1432,6 +1438,17 @@ CURLcode Curl_disconnect(struct connectdata *conn) data = conn->data; + if(conn->dns_entry) + Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ + +#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) + /* scan for DNS cache entries still marked as in use */ + Curl_hash_apply(data->hostcache, + NULL, Curl_scan_cache_used); +#endif + + Curl_hostcache_prune(data); /* kill old DNS cache entries */ + /* * The range string is usually freed in curl_done(), but we might * get here *instead* if we fail prematurely. Thus we need to be able @@ -3230,8 +3247,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->bits.reuse) { /* re-used connection, no resolving is necessary */ hostaddr = NULL; - conn->dns_entry = NULL; /* we don't connect now so we don't have any fresh - dns entry struct to point to */ + /* we'll need to clear conn->dns_entry later in Curl_disconnect() */ if (conn->bits.httpproxy) fix_hostname(conn, &conn->host); @@ -3480,17 +3496,6 @@ CURLcode Curl_done(struct connectdata **connp, conn->newurl = NULL; } - if(conn->dns_entry) - Curl_resolv_unlock(conn->data, conn->dns_entry); /* done with this */ - -#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) - /* scan for DNS cache entries still marked as in use */ - Curl_hash_apply(data->hostcache, - NULL, Curl_scan_cache_used); -#endif - - Curl_hostcache_prune(data); /* kill old DNS cache entries */ - /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) result = conn->curl_done(conn, status); -- cgit v1.2.1 From 1a61bcecfc1ed56abb418d3278f13f278fa57e39 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Oct 2004 11:03:59 +0000 Subject: minor edit to re-use a variable and to hopefully avoid a (moot) warning about code that won't be reached --- lib/url.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9ac054a68..3673fa576 100644 --- a/lib/url.c +++ b/lib/url.c @@ -374,7 +374,7 @@ CURLcode Curl_open(struct SessionHandle **curl) CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { va_list param; - char *cookiefile; + char *argptr; va_start(param, option); @@ -728,12 +728,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set cookie file to read and parse. Can be used multiple times. */ - cookiefile = (char *)va_arg(param, void *); - if(cookiefile) { + argptr = (char *)va_arg(param, void *); + if(argptr) { struct curl_slist *cl; /* append the cookie file name to the list of file names, and deal with them later */ - cl = curl_slist_append(data->change.cookielist, cookiefile); + cl = curl_slist_append(data->change.cookielist, argptr); if(!cl) return CURLE_OUT_OF_MEMORY; @@ -1132,26 +1132,24 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * String that holds the SSL crypto engine. */ - { - const char *cpTemp = va_arg(param, char *); - if (cpTemp && cpTemp[0]) { + argptr = va_arg(param, char *); + if (argptr && argptr[0]) { #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) - ENGINE *e = ENGINE_by_id(cpTemp); - if (e) { - if (data->engine) { - ENGINE_free(data->engine); - } - data->engine = e; - } - else { - failf(data, "SSL Engine '%s' not found", cpTemp); - return CURLE_SSL_ENGINE_NOTFOUND; + ENGINE *e = ENGINE_by_id(argptr); + if (e) { + if (data->engine) { + ENGINE_free(data->engine); } -#else - failf(data, "SSL Engine not supported"); + data->engine = e; + } + else { + failf(data, "SSL Engine '%s' not found", argptr); return CURLE_SSL_ENGINE_NOTFOUND; -#endif } +#else + failf(data, "SSL Engine not supported"); + return CURLE_SSL_ENGINE_NOTFOUND; +#endif } break; -- cgit v1.2.1 From 39af394a1c3ae1d8ac71ad263a7c524988702c2e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 6 Oct 2004 07:50:18 +0000 Subject: removed tabs and trailing whitespace from source --- lib/url.c | 70 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3673fa576..07d85fd71 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2451,23 +2451,23 @@ static CURLcode CreateConnection(struct SessionHandle *data, break; } } - nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); + nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); } if(!nope) { - /* It was not listed as without proxy */ - char *protop = conn->protostr; - char *envp = proxy_env; - char *prox; + /* It was not listed as without proxy */ + char *protop = conn->protostr; + char *envp = proxy_env; + char *prox; - /* Now, build _proxy and check for such a one to use */ - while(*protop) - *envp++ = tolower((int)*protop++); + /* Now, build _proxy and check for such a one to use */ + while(*protop) + *envp++ = tolower((int)*protop++); - /* append _proxy */ - strcpy(envp, "_proxy"); + /* append _proxy */ + strcpy(envp, "_proxy"); - /* read the protocol proxy: */ - prox=curl_getenv(proxy_env); + /* read the protocol proxy: */ + prox=curl_getenv(proxy_env); /* * We don't try the uppercase version of HTTP_PROXY because of @@ -2481,21 +2481,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, * This can cause 'internal' http/ftp requests to be * arbitrarily redirected by any external attacker. */ - if(!prox && !strequal("http_proxy", proxy_env)) { + if(!prox && !strequal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ - for(envp = proxy_env; *envp; envp++) - *envp = toupper((int)*envp); - prox=curl_getenv(proxy_env); - } - - if(prox && *prox) { /* don't count "" strings */ - proxy = prox; /* use this */ - } - else { - proxy = curl_getenv("all_proxy"); /* default proxy to use */ - if(!proxy) + for(envp = proxy_env; *envp; envp++) + *envp = toupper((int)*envp); + prox=curl_getenv(proxy_env); + } + + if(prox && *prox) { /* don't count "" strings */ + proxy = prox; /* use this */ + } + else { + proxy = curl_getenv("all_proxy"); /* default proxy to use */ + if(!proxy) proxy=curl_getenv("ALL_PROXY"); - } + } if(proxy && *proxy) { /* we have a proxy here to set */ @@ -2652,7 +2652,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (isdigit((int)conn->path[1])) { conn->path = strchr(&conn->path[1], '/'); if (conn->path == NULL) - conn->path = conn->pathbuffer; + conn->path = conn->pathbuffer; } conn->protocol |= PROT_GOPHER; conn->curl_do = Curl_http; @@ -2728,16 +2728,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, command = toupper((int)type[6]); switch(command) { case 'A': /* ASCII mode */ - data->set.ftp_ascii = 1; - break; + data->set.ftp_ascii = 1; + break; case 'D': /* directory mode */ - data->set.ftp_list_only = 1; - break; + data->set.ftp_list_only = 1; + break; case 'I': /* binary mode */ default: - /* switch off ASCII */ - data->set.ftp_ascii = 0; - break; + /* switch off ASCII */ + data->set.ftp_ascii = 0; + break; } } #else /* CURL_DISABLE_FTP */ @@ -3162,7 +3162,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, - conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); + conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); } else { /* @@ -3523,7 +3523,7 @@ CURLcode Curl_done(struct connectdata **connp, else infof(data, "Connection #%ld to host %s left intact\n", conn->connectindex, - conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); + conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); return result; } -- cgit v1.2.1 From f0d6cc23ae53ce7e51bdb56ad03a2f9fd3aae2df Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Wed, 6 Oct 2004 18:40:10 +0000 Subject: USE_LIBIDN: Added Top-level-domain (TLD) check for host->name. Only print a warning if check fails. --- lib/url.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 07d85fd71..e83836e74 100644 --- a/lib/url.c +++ b/lib/url.c @@ -86,6 +86,7 @@ #ifdef USE_LIBIDN #include +#include #include #ifdef HAVE_IDN_FREE_H #include @@ -2075,6 +2076,36 @@ static bool is_ASCII_name (const char *hostname) } return TRUE; } + +/* + * Check if characters in hostname is allowed in Top Level Domain. + */ +static bool tld_check_name (struct connectdata *conn, + const char *ace_hostname) +{ + struct SessionHandle *data = conn->data; + size_t err_pos; + char *uc_name = NULL; + int rc; + + /* Convert (and downcase) ACE-name back into locale's character set */ + rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); + if (rc != IDNA_SUCCESS) + infof(data, "Failed to convert %s from ACE; %s\n", + ace_hostname, Curl_idn_strerror(conn,rc)); + + rc = tld_check_lz(uc_name, &err_pos, NULL); + if (rc == TLD_INVALID) + infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", + tld_strerror(rc), err_pos, uc_name[err_pos], + uc_name[err_pos] & 255); + else if (rc != TLD_SUCCESS) + infof(data, "WARNING: TLD check for %s failed; %s\n", + uc_name, tld_strerror(rc)); + if (uc_name) + idn_free(uc_name); + return (rc == TLD_SUCCESS); +} #endif static void fix_hostname(struct connectdata *conn, struct hostname *host) @@ -2097,6 +2128,8 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) infof(data, "Failed to convert %s to ACE; %s\n", host->name, Curl_idn_strerror(conn,rc)); else { + tld_check_name(conn, ace_hostname); + host->encalloc = ace_hostname; /* change the name pointer to point to the encoded hostname */ host->name = host->encalloc; -- cgit v1.2.1 From 071218a201d5b86fbfdf1ae72a3ddf51633b8d99 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Wed, 6 Oct 2004 18:55:58 +0000 Subject: Fixed tld_check_name(). idna_to_unicode_lzlz() should never fail, but return FALSE if 'uc_name == NULL' just in case. --- lib/url.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e83836e74..51b171129 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2080,10 +2080,9 @@ static bool is_ASCII_name (const char *hostname) /* * Check if characters in hostname is allowed in Top Level Domain. */ -static bool tld_check_name (struct connectdata *conn, +static bool tld_check_name (struct SessionHandle *data, const char *ace_hostname) { - struct SessionHandle *data = conn->data; size_t err_pos; char *uc_name = NULL; int rc; @@ -2091,8 +2090,7 @@ static bool tld_check_name (struct connectdata *conn, /* Convert (and downcase) ACE-name back into locale's character set */ rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); if (rc != IDNA_SUCCESS) - infof(data, "Failed to convert %s from ACE; %s\n", - ace_hostname, Curl_idn_strerror(conn,rc)); + return (FALSE); rc = tld_check_lz(uc_name, &err_pos, NULL); if (rc == TLD_INVALID) @@ -2128,7 +2126,7 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) infof(data, "Failed to convert %s to ACE; %s\n", host->name, Curl_idn_strerror(conn,rc)); else { - tld_check_name(conn, ace_hostname); + tld_check_name(data, ace_hostname); host->encalloc = ace_hostname; /* change the name pointer to point to the encoded hostname */ -- cgit v1.2.1 From c274e516540270b0f353a8eefe4da5a64a6445a4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 7 Oct 2004 07:41:44 +0000 Subject: use tld_strerror() only if previously detected, since otherwise we can't work with libidn < 0.5.6 --- lib/url.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 51b171129..7d7865316 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2095,11 +2095,22 @@ static bool tld_check_name (struct SessionHandle *data, rc = tld_check_lz(uc_name, &err_pos, NULL); if (rc == TLD_INVALID) infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", - tld_strerror(rc), err_pos, uc_name[err_pos], +#ifdef HAVE_TLD_STRERROR + tld_strerror(rc), +#else + "", +#endif + err_pos, uc_name[err_pos], uc_name[err_pos] & 255); else if (rc != TLD_SUCCESS) infof(data, "WARNING: TLD check for %s failed; %s\n", - uc_name, tld_strerror(rc)); + uc_name, +#ifdef HAVE_TLD_STRERROR + tld_strerror(rc) +#else + "" +#endif + ); if (uc_name) idn_free(uc_name); return (rc == TLD_SUCCESS); -- cgit v1.2.1 From 5322a86313b84e5c6732b23bbea011b14e82fbbb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 10 Oct 2004 14:36:22 +0000 Subject: another lame attempt to avoid the "warning: will never be executed" warning by gcc 3.4 --- lib/url.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7d7865316..db7cf2ab5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -376,6 +376,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { va_list param; char *argptr; + CURLcode result = CURLE_OK; va_start(param, option); @@ -1145,11 +1146,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } else { failf(data, "SSL Engine '%s' not found", argptr); - return CURLE_SSL_ENGINE_NOTFOUND; + result = CURLE_SSL_ENGINE_NOTFOUND; } #else failf(data, "SSL Engine not supported"); - return CURLE_SSL_ENGINE_NOTFOUND; + result = CURLE_SSL_ENGINE_NOTFOUND; #endif } break; @@ -1424,9 +1425,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) default: /* unknown tag and its companion, just ignore: */ - return CURLE_FAILED_INIT; /* correct this */ + result = CURLE_FAILED_INIT; /* correct this */ + break; } - return CURLE_OK; + + return result; } CURLcode Curl_disconnect(struct connectdata *conn) -- cgit v1.2.1 From e8f85cba0f8c19369d39b1c6616dc51dae1dd179 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Oct 2004 13:44:54 +0000 Subject: Eric Vergnaud pointed out that libcurl didn't treat ?-letters in the user name and password fields properly in URLs, like ftp://us?er:pass?word@site.com/. Added test 191 to verify the fix. --- lib/url.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index db7cf2ab5..e84d05489 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2175,6 +2175,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, bool *async) { char *tmp; + char *at; CURLcode result=CURLE_OK; struct connectdata *conn; struct connectdata *conn_temp; @@ -2349,13 +2350,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Set default path */ 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 - * http://example.com?param= (notice the missing '/'). Later we'll insert - * that missing slash at the beginning of the path. - */ if (2 > sscanf(data->change.url, - "%15[^\n:]://%[^\n/?]%[^\n]", + "%15[^\n:]://%[^\n/]%[^\n]", conn->protostr, conn->host.name, conn->path)) { @@ -2363,7 +2359,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ - if((1 > sscanf(data->change.url, "%[^\n/?]%[^\n]", + if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]", conn->host.name, conn->path)) ) { /* * We couldn't even get this format. @@ -2404,6 +2400,27 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } + /* We search for '?' in the host name (but only on the right side of a + * @-letter to allow ?-letters in username and password) to handle things + * like http://example.com?param= (notice the missing '/'). + */ + at = strchr(conn->host.name, '@'); + if(at) + tmp = strchr(at+1, '?'); + else + tmp = strchr(conn->host.name, '?'); + + if(tmp) { + /* The right part of the ?-letter needs to be moved to prefix + the current path buffer! */ + size_t len = strlen(tmp); + /* move the existing path plus the zero byte */ + memmove(conn->path+len+1, conn->path, strlen(conn->path)+1); + conn->path[0]='/'; /* prepend the missing slash */ + memcpy(conn->path+1, tmp, len); /* now copy the prefix part */ + *tmp=0; /* now cut off the hostname at the ? */ + } + /* If the URL is malformatted (missing a '/' after hostname before path) we * insert a slash here. The only letter except '/' we accept to start a path * is '?'. -- cgit v1.2.1 From 24d47a6e07304cf0921f2d30734b3c64360773c3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Nov 2004 10:12:22 +0000 Subject: Paul Nolan fix to make libcurl build nicely on Windows CE --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e84d05489..c474bdcab 100644 --- a/lib/url.c +++ b/lib/url.c @@ -30,9 +30,12 @@ #include #include #include +#ifdef HAVE_SYS_TYPES_H #include +#endif +#ifdef HAVE_SYS_STAT_H #include - +#endif #include #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -- cgit v1.2.1 From 59c063dfd38972e06a7f3a0b8f94860a67acdc96 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 11 Nov 2004 23:11:04 +0000 Subject: Fix behaviour when passing NULL to CURLOPT_POSTFIELDS and CURLOPT_HTTPPOST. --- lib/url.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c474bdcab..5d0e801b5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -317,6 +317,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.fread = (curl_read_callback)fread; data->set.infilesize = -1; /* we don't know any size */ + data->set.postfieldsize = -1; data->state.current_speed = -1; /* init to negative == impossible */ @@ -657,11 +658,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) case CURLOPT_POSTFIELDS: /* - * A string with POST data. Makes curl HTTP POST. + * A string with POST data. Makes curl HTTP POST. Even if it is NULL. */ data->set.postfields = va_arg(param, char *); - if(data->set.postfields) - data->set.httpreq = HTTPREQ_POST; + data->set.httpreq = HTTPREQ_POST; break; case CURLOPT_POSTFIELDSIZE: @@ -685,8 +685,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Set to make us do HTTP POST */ data->set.httppost = va_arg(param, struct curl_httppost *); - if(data->set.httppost) - data->set.httpreq = HTTPREQ_POST_FORM; + data->set.httpreq = HTTPREQ_POST_FORM; break; case CURLOPT_REFERER: -- cgit v1.2.1 From 94043b11508b9a4bf1fbee9ea17ef658c6413d9d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Nov 2004 09:18:14 +0000 Subject: Dan Fandrich added the --disable-crypto-auth option to configure to allow libcurl to build without Digest support. (I figure it should also explicitly disable Negotiate and NTLM.) --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5d0e801b5..78224df0e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -250,7 +250,9 @@ CURLcode Curl_close(struct SessionHandle *data) } Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); +#ifndef CURL_DISABLE_CRYPTO_AUTH Curl_digest_cleanup(data); +#endif #endif /* free the connection cache */ -- cgit v1.2.1 From 5931d43a36d092d0c6a266c8cf619814c2f62d22 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 15 Nov 2004 11:27:03 +0000 Subject: clean up start time and t_startsingle use so that redirect_time works properly --- lib/url.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 78224df0e..6ee238360 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2259,11 +2259,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->range = data->set.set_range; /* clone the range setting */ conn->resume_from = data->set.set_resume_from; /* inherite resume_from */ - /* Set the start time temporary to this creation time to allow easier - timeout checks before the transfer has started for real. The start time - is later set "for real" using Curl_pgrsStartNow(). */ - conn->data->progress.start = conn->created; - conn->bits.user_passwd = data->set.userpwd?1:0; conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; conn->bits.no_body = data->set.opt_no_body; -- cgit v1.2.1 From dcea109bb5ce1c8afeb0510945eb15e86cfcf1dc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 18 Nov 2004 14:04:40 +0000 Subject: Dan Fandrich fix: eliminates some pedantic CodeWarrior compiler warnings and errors. --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6ee238360..882d74719 100644 --- a/lib/url.c +++ b/lib/url.c @@ -206,7 +206,8 @@ void Curl_safefree(void *ptr) CURLcode Curl_close(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ - while(-1 != ConnectionKillOne(data)); + while(-1 != ConnectionKillOne(data)) + ; /* empty loop */ if ( ! (data->share && data->share->hostcache) ) { if ( !Curl_global_host_cache_use(data)) { -- cgit v1.2.1 From 1a05a90f1ce86394d7966aaaa9539adaa228c6bf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Nov 2004 08:52:33 +0000 Subject: David Phillips' FD_SETSIZE fix --- lib/url.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 882d74719..c1ff23993 100644 --- a/lib/url.c +++ b/lib/url.c @@ -64,10 +64,6 @@ #include #endif -#ifdef HAVE_SYS_SELECT_H -#include -#endif - #ifdef VMS #include #include @@ -77,9 +73,6 @@ #include #endif -#ifndef HAVE_SELECT -#error "We can't compile without select() support!" -#endif #ifndef HAVE_SOCKET #error "We can't compile without socket() support!" #endif @@ -127,6 +120,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "content_encoding.h" #include "http_digest.h" #include "http_negotiate.h" +#include "select.h" /* And now for the protocols */ #include "ftp.h" @@ -1552,16 +1546,8 @@ static bool SocketIsDead(curl_socket_t sock) { int sval; bool ret_val = TRUE; - fd_set check_set; - struct timeval to; - - FD_ZERO(&check_set); - FD_SET(sock, &check_set); - - to.tv_sec = 0; - to.tv_usec = 0; - sval = select(sock + 1, &check_set, 0, 0, &to); + sval = Curl_select(sock, CURL_SOCKET_BAD, 0); if(sval == 0) /* timeout */ ret_val = FALSE; -- cgit v1.2.1 From 3e1caa61859a6057a65eb7c1585d47e05026c4f2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Nov 2004 16:11:35 +0000 Subject: HTTP "auth done right". See lib/README.httpauth --- lib/url.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c1ff23993..1b15d6957 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1099,6 +1099,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* When set to NULL, reset to our internal default function */ data->set.fread = (curl_read_callback)fread; break; + case CURLOPT_IOCTLFUNCTION: + /* + * I/O control callback. Might be NULL. + */ + data->set.ioctl = va_arg(param, curl_ioctl_callback); + break; + case CURLOPT_IOCTLDATA: + /* + * I/O control data pointer. Might be NULL. + */ + data->set.ioctl_client = va_arg(param, void *); + break; case CURLOPT_SSLCERT: /* * String that holds file name of the SSL certificate to use -- cgit v1.2.1 From bf51f05a50a63ade21316a18d2bf1801767ab234 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 25 Nov 2004 22:21:49 +0000 Subject: FTP improvements: If EPSV, EPRT or LPRT is tried and doesn't work, it will not be retried on the same server again even if a following request is made using a persistent connection. If a second request is made to a server, requesting a file from the same directory as the previous request operated on, libcurl will no longer make that long series of CWD commands just to end up on the same spot. Note that this is only for *exactly* the same dir. There is still room for improvements to optimize the CWD-sending when the dirs are only slightly different. Added test 210, 211 and 212 to verify these changes. Had to improve the test script too and added a new primitive to the test file format. --- lib/url.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1b15d6957..cfc791104 100644 --- a/lib/url.c +++ b/lib/url.c @@ -321,6 +321,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + data->set.ftp_use_lprt = TRUE; /* FTP defaults to EPRT operations */ data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ @@ -911,6 +912,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) case CURLOPT_FTP_USE_EPRT: data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE; + data->set.ftp_use_lprt = data->set.ftp_use_eprt; break; case CURLOPT_FTP_USE_EPSV: @@ -1439,7 +1441,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) result = CURLE_FAILED_INIT; /* correct this */ break; } - + return result; } @@ -2262,6 +2264,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; conn->bits.no_body = data->set.opt_no_body; conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; + conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; + conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + conn->bits.ftp_use_lprt = data->set.ftp_use_lprt; /* This initing continues below, see the comment "Continue connectdata * initialization here" */ -- cgit v1.2.1 From af114358c86a9c6a85402d80980bb919c99bbef9 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Fri, 26 Nov 2004 14:57:01 +0000 Subject: Renamed urldata.h members 'ioctl*' to 'ioctrl*' due to clash with djgpp ioctl() macro in setup.h. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cfc791104..21531da54 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1105,13 +1105,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * I/O control callback. Might be NULL. */ - data->set.ioctl = va_arg(param, curl_ioctl_callback); + data->set.ioctrl = va_arg(param, curl_ioctl_callback); break; case CURLOPT_IOCTLDATA: /* * I/O control data pointer. Might be NULL. */ - data->set.ioctl_client = va_arg(param, void *); + data->set.ioctrl_client = va_arg(param, void *); break; case CURLOPT_SSLCERT: /* -- cgit v1.2.1 From d85bc18178c0eb03f5a691e18f772bfbc34a35cc Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Fri, 26 Nov 2004 16:08:15 +0000 Subject: I changed my mind. Remove ioctl() macro in setup.h instead. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 21531da54..cfc791104 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1105,13 +1105,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * I/O control callback. Might be NULL. */ - data->set.ioctrl = va_arg(param, curl_ioctl_callback); + data->set.ioctl = va_arg(param, curl_ioctl_callback); break; case CURLOPT_IOCTLDATA: /* * I/O control data pointer. Might be NULL. */ - data->set.ioctrl_client = va_arg(param, void *); + data->set.ioctl_client = va_arg(param, void *); break; case CURLOPT_SSLCERT: /* -- cgit v1.2.1 From ac269a8f68323db6b579f11f864035bc2691081d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 5 Dec 2004 23:59:32 +0000 Subject: Dan Fandrich added the --disable-cookies option to configure to build libcurl without cookie support. This is mainly useful if you want to build a minimalistic libcurl with no cookies support at all. Like for embedded systems or similar. --- lib/url.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cfc791104..74e65d164 100644 --- a/lib/url.c +++ b/lib/url.c @@ -214,9 +214,6 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_SSL_Close_All(data); #endif - if(data->change.cookielist) /* clean up list if any */ - curl_slist_free_all(data->change.cookielist); - Curl_safefree(data->state.first_host); Curl_safefree(data->state.scratch); @@ -231,7 +228,10 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.headerbuff); -#ifndef CURL_DISABLE_HTTP +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) + if(data->change.cookielist) /* clean up list if any */ + curl_slist_free_all(data->change.cookielist); + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); if(data->set.cookiejar) { /* we have a "destination" for all the cookies to get dumped to */ @@ -244,10 +244,10 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_cookie_cleanup(data->cookies); } Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); +#endif -#ifndef CURL_DISABLE_CRYPTO_AUTH +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) Curl_digest_cleanup(data); -#endif #endif /* free the connection cache */ @@ -719,6 +719,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.http200aliases = va_arg(param, struct curl_slist *); break; +#if !defined(CURL_DISABLE_COOKIES) case CURLOPT_COOKIE: /* * Cookie string to send to the remote server in the request. @@ -776,6 +777,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.cookiesession = (bool)va_arg(param, long); break; +#endif case CURLOPT_HTTPGET: /* @@ -1310,7 +1312,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->hostcache = data->share->hostcache; } -#ifndef CURL_DISABLE_HTTP +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(data->share->cookies) { /* use shared cookie list, first free own one if any */ if (data->cookies) @@ -1321,7 +1323,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } -#ifndef CURL_DISABLE_HTTP +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) /* check cookie list is set */ if(!data->cookies) data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE ); -- cgit v1.2.1 From 8a4eb8ed45f927b6d2c9c49fb3d290da1c5c2f6f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Dec 2004 15:11:11 +0000 Subject: move the port number extraction to after the extraction of user name/password, as suggested by Kai Sommerfeld --- lib/url.c | 96 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 74e65d164..7c1cf19be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2885,54 +2885,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } - /************************************************************* - * Figure out the remote port number - * - * No matter if we use a proxy or not, we have to figure out the remote - * port number of various reasons. - * - * To be able to detect port number flawlessly, we must not confuse them - * IPv6-specified addresses in the [0::1] style. (RFC2732) - * - * The conn->host.name is currently [user:passwd@]host[:port] where host - * could be a hostname, IPv4 address or IPv6 address. - *************************************************************/ - if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && - (']' == endbracket)) { - /* this is a RFC2732-style specified IP-address */ - conn->bits.ipv6_ip = TRUE; - - conn->host.name++; /* pass the starting bracket */ - tmp = strchr(conn->host.name, ']'); - *tmp = 0; /* zero terminate */ - tmp++; /* pass the ending bracket */ - if(':' != *tmp) - tmp = NULL; /* no port number available */ - } - else - tmp = strrchr(conn->host.name, ':'); - - if (tmp) { - char *rest; - unsigned long port; - - port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ - - if (rest != (tmp+1) && *rest == '\0') { - /* The colon really did have only digits after it, - * so it is either a port number or a mistake */ - - if (port > 0xffff) { /* Single unix standard says port numbers are - * 16 bits long */ - failf(data, "Port number too large: %lu", port); - return CURLE_URL_MALFORMAT; - } - - *tmp = '\0'; /* cut off the name there */ - conn->remote_port = (unsigned short)port; - } - } - if(data->change.proxy && *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 @@ -3079,6 +3031,54 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } + /************************************************************* + * Figure out the remote port number + * + * No matter if we use a proxy or not, we have to figure out the remote + * port number of various reasons. + * + * To be able to detect port number flawlessly, we must not confuse them + * IPv6-specified addresses in the [0::1] style. (RFC2732) + * + * The conn->host.name is currently [user:passwd@]host[:port] where host + * could be a hostname, IPv4 address or IPv6 address. + *************************************************************/ + if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && + (']' == endbracket)) { + /* this is a RFC2732-style specified IP-address */ + conn->bits.ipv6_ip = TRUE; + + conn->host.name++; /* pass the starting bracket */ + tmp = strchr(conn->host.name, ']'); + *tmp = 0; /* zero terminate */ + tmp++; /* pass the ending bracket */ + if(':' != *tmp) + tmp = NULL; /* no port number available */ + } + else + tmp = strrchr(conn->host.name, ':'); + + if (tmp) { + char *rest; + unsigned long port; + + port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ + + if (rest != (tmp+1) && *rest == '\0') { + /* The colon really did have only digits after it, + * so it is either a port number or a mistake */ + + if (port > 0xffff) { /* Single unix standard says port numbers are + * 16 bits long */ + failf(data, "Port number too large: %lu", port); + return CURLE_URL_MALFORMAT; + } + + *tmp = '\0'; /* cut off the name there */ + conn->remote_port = (unsigned short)port; + } + } + /* Programmatically set password: * - always applies, if available * - takes precedence over the values we just set above -- cgit v1.2.1 From bdb0620529ecb58b879dcf7de67885f211812aee Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Mon, 13 Dec 2004 16:43:00 +0000 Subject: Added handling of CURLINFO_SSL_ENGINES; Added Curl_SSL_engines_list(), cleanup SSL in url.c (no HAVE_OPENSSL_x etc.). --- lib/url.c | 39 +++------------------------------------ 1 file changed, 3 insertions(+), 36 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7c1cf19be..4b077dfe2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -97,9 +97,6 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #endif #endif -#ifdef HAVE_OPENSSL_ENGINE_H -#include -#endif #include "urldata.h" #include "netrc.h" @@ -1150,45 +1147,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * String that holds the SSL crypto engine. */ argptr = va_arg(param, char *); - if (argptr && argptr[0]) { -#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) - ENGINE *e = ENGINE_by_id(argptr); - if (e) { - if (data->engine) { - ENGINE_free(data->engine); - } - data->engine = e; - } - else { - failf(data, "SSL Engine '%s' not found", argptr); - result = CURLE_SSL_ENGINE_NOTFOUND; - } -#else - failf(data, "SSL Engine not supported"); - result = CURLE_SSL_ENGINE_NOTFOUND; -#endif - } + if (argptr && argptr[0]) + result = Curl_SSL_set_engine(data, argptr); break; case CURLOPT_SSLENGINE_DEFAULT: /* * flag to set engine as default. */ -#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) - if (data->engine) { - if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) { -#ifdef DEBUG - fprintf(stderr,"set default crypto engine\n"); -#endif - } - else { -#ifdef DEBUG - failf(data, "set default crypto engine failed"); -#endif - return CURLE_SSL_ENGINE_SETFAILED; - } - } -#endif + result = Curl_SSL_set_engine_default(data); break; case CURLOPT_CRLF: /* -- cgit v1.2.1 From 0d0d5e7ee3b8575118d8d268802623f2a9a49ee5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 14 Dec 2004 21:22:51 +0000 Subject: Harshal Pradhan fixed changing username/password on a persitent HTTP connection. --- lib/url.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4b077dfe2..65d7cf032 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3131,7 +3131,26 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* get the user+password information from the old_conn struct since it may * be new for this request even when we re-use an existing connection */ conn->bits.user_passwd = old_conn->bits.user_passwd; + if (conn->bits.user_passwd) { + /* use the new user namd and password though */ + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + conn->user = old_conn->user; + conn->passwd = old_conn->passwd; + old_conn->user = NULL; + old_conn->passwd = NULL; + } + conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; + if (conn->bits.proxy_user_passwd) { + /* use the new proxy user name and proxy password though */ + Curl_safefree(conn->proxyuser); + Curl_safefree(conn->proxypasswd); + conn->proxyuser = old_conn->proxyuser; + conn->proxypasswd = old_conn->proxypasswd; + old_conn->proxyuser = NULL; + old_conn->proxypasswd = NULL; + } /* host can change, when doing keepalive with a proxy ! */ if (conn->bits.httpproxy) { -- cgit v1.2.1 From 26fe6da93bfbc80e34878fbab899959d15d70194 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 16 Dec 2004 21:27:23 +0000 Subject: Renamed a struct member to avoid conflict with a C++ reserved word. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 65d7cf032..50b50615d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1311,7 +1311,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) /* * Set private data pointer. */ - data->set.private = va_arg(param, char *); + data->set.private_data = va_arg(param, char *); break; case CURLOPT_MAXFILESIZE: -- cgit v1.2.1 From b1bdba7db55a9dee799d95aebf82d9f6c3674871 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Fri, 17 Dec 2004 12:26:18 +0000 Subject: Print true netrc name (.netrc/_netrc). --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 50b50615d..bb4364302 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3067,7 +3067,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(Curl_parsenetrc(conn->host.name, user, passwd, data->set.netrc_file)) { - infof(data, "Couldn't find host %s in the .netrc file, using defaults\n", + infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n", conn->host.name); } else -- cgit v1.2.1 From 21bb852750d39a51d20e29652d29b0be5fdbef38 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 Jan 2005 10:07:07 +0000 Subject: Pavel Orehov reported memory problems with the multi interface in bug report #1098843. In short, a shared DNS cache was setup for a multi handle and when the shared cache was deleted before the individual easy handles, the latter cleanups caused read/writes to already freed memory. --- lib/url.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bb4364302..29c35bf05 100644 --- a/lib/url.c +++ b/lib/url.c @@ -118,6 +118,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "http_digest.h" #include "http_negotiate.h" #include "select.h" +#include "multi.h" /* And now for the protocols */ #include "ftp.h" @@ -196,6 +197,10 @@ void Curl_safefree(void *ptr) CURLcode Curl_close(struct SessionHandle *data) { + if(data->multi) { + /* this handle is still part of a multi handle, take care of this first */ + Curl_multi_rmeasy(data->multi, data); + } /* Loop through all open connections and kill them one by one */ while(-1 != ConnectionKillOne(data)) ; /* empty loop */ @@ -1422,7 +1427,10 @@ CURLcode Curl_disconnect(struct connectdata *conn) data = conn->data; - if(conn->dns_entry) + if(conn->dns_entry && data->hostcache) + /* if the DNS entry is still around, and the host cache is not blanked + (which it is for example when a shared one is killed by + curl_multi_cleanup() and similar stuff) */ Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) -- cgit v1.2.1 From 9d1145598abf9fddae2e88cca9e114c12a1b7d9d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 Jan 2005 23:32:14 +0000 Subject: Bruce Mitchener identified (bug report #1099640) the never-ending SOCKS5 problem with the version byte and the check for bad versions. Bruce has lots of clues on this, and based on his suggestion I've now removed the check of that byte since it seems to be able to contain 1 or 5. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 29c35bf05..6c3b662b4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1829,8 +1829,8 @@ static int handleSock5Proxy(const char *proxy_name, return 1; } - if ((socksreq[0] != 5) || /* version */ - (socksreq[1] != 0)) { /* status */ + /* ignore the first (VER) byte */ + if (socksreq[1] != 0) { /* status */ failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); return 1; -- cgit v1.2.1 From e3fa7d021e4f37db40229a7c8f93296d4132e4db Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Jan 2005 15:25:29 +0000 Subject: Renamed easy.h and multi.h to easyif.h and multiif.h to make sure they don't shadow our public headers with the former names. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6c3b662b4..67e634077 100644 --- a/lib/url.c +++ b/lib/url.c @@ -118,7 +118,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "http_digest.h" #include "http_negotiate.h" #include "select.h" -#include "multi.h" +#include "multiif.h" /* And now for the protocols */ #include "ftp.h" -- cgit v1.2.1 From e0bea7d54152e0acd5b10c5ac616ccbad6168da7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 16 Jan 2005 08:51:52 +0000 Subject: Alex aka WindEagle pointed out that when doing "curl -v dictionary.com", curl assumed this used the DICT protocol. While guessing protocols will remain fuzzy, I've now made sure that the host names must start with "[protocol]." for them to be a valid guessable name. I also removed "https" as a prefix that indicates HTTPS, since we hardly ever see any host names using that. --- lib/url.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 67e634077..f634d2835 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2356,21 +2356,19 @@ 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->host.name)) + if(checkprefix("GOPHER.", conn->host.name)) strcpy(conn->protostr, "gopher"); #ifdef USE_SSLEAY - else if(checkprefix("HTTPS", conn->host.name)) - strcpy(conn->protostr, "https"); else if(checkprefix("FTPS", conn->host.name)) strcpy(conn->protostr, "ftps"); #endif /* USE_SSLEAY */ - else if(checkprefix("FTP", conn->host.name)) + else if(checkprefix("FTP.", conn->host.name)) strcpy(conn->protostr, "ftp"); - else if(checkprefix("TELNET", conn->host.name)) + else if(checkprefix("TELNET.", conn->host.name)) strcpy(conn->protostr, "telnet"); - else if (checkprefix("DICT", conn->host.name)) + else if (checkprefix("DICT.", conn->host.name)) strcpy(conn->protostr, "DICT"); - else if (checkprefix("LDAP", conn->host.name)) + else if (checkprefix("LDAP.", conn->host.name)) strcpy(conn->protostr, "LDAP"); else { strcpy(conn->protostr, "http"); -- cgit v1.2.1 From a0c8b9bc68730bf6290a308602d3f793a6bde25f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 19 Jan 2005 09:36:44 +0000 Subject: Stephan Bergmann pointed out two flaws in libcurl built with HTTP disabled: 1) the proxy environment variables are still read and used to set HTTP proxy 2) you couldn't disable http proxy with CURLOPT_PROXY (since the option was disabled) --- lib/url.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f634d2835..df2011ec6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -779,7 +779,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.cookiesession = (bool)va_arg(param, long); break; -#endif +#endif /* CURL_DISABLE_COOKIES */ case CURLOPT_HTTPGET: /* @@ -818,27 +818,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) and this just changes the actual request keyword */ break; - case CURLOPT_PROXY: - /* - * Set proxy server:port to use as HTTP proxy. - * - * If the proxy is set to "" we explicitly say that we don't want to use a - * proxy (even though there might be environment variables saying so). - * - * Setting it to NULL, means no proxy but allows the environment variables - * to decide for us. - */ - if(data->change.proxy_alloc) { - /* - * The already set string is allocated, free that first - */ - data->change.proxy_alloc=FALSE;; - free(data->change.proxy); - } - data->set.set_proxy = va_arg(param, char *); - data->change.proxy = data->set.set_proxy; - break; - case CURLOPT_PROXYPORT: /* * Explicitly set HTTP proxy port number. @@ -887,6 +866,27 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; #endif /* CURL_DISABLE_HTTP */ + case CURLOPT_PROXY: + /* + * Set proxy server:port to use as HTTP proxy. + * + * If the proxy is set to "" we explicitly say that we don't want to use a + * proxy (even though there might be environment variables saying so). + * + * Setting it to NULL, means no proxy but allows the environment variables + * to decide for us. + */ + if(data->change.proxy_alloc) { + /* + * The already set string is allocated, free that first + */ + data->change.proxy_alloc=FALSE;; + free(data->change.proxy); + } + data->set.set_proxy = va_arg(param, char *); + data->change.proxy = data->set.set_proxy; + break; + case CURLOPT_WRITEHEADER: /* * Custom pointer to pass the header write callback function @@ -2439,6 +2439,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; } +#ifndef CURL_DISABLE_HTTP /************************************************************* * Detect what (if any) proxy to use *************************************************************/ @@ -2603,6 +2604,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(no_proxy) free(no_proxy); } /* if not using proxy */ +#endif /* CURL_DISABLE_HTTP */ /************************************************************* * No protocol part in URL was used, add it! -- cgit v1.2.1 From 7e42cb61f75890832792c082510ec610f4c32cbe Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 21 Jan 2005 09:32:32 +0000 Subject: FTP third transfer support overhaul. See CHANGES for details. --- lib/url.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index df2011ec6..8b433f606 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1360,19 +1360,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; /*********** 3rd party transfer options ***********/ - case CURLOPT_SOURCE_HOST: + case CURLOPT_SOURCE_URL: /* - * Use SOURCE HOST + * SOURCE URL */ - data->set.source_host = va_arg(param, char *); - data->set.printhost = (data->set.source_host != NULL); - break; - - case CURLOPT_SOURCE_PORT: - /* - * Use SOURCE PORT - */ - data->set.source_port = va_arg(param, char *); + data->set.source_url = va_arg(param, char *); + data->set.printhost = (data->set.source_url != NULL); break; case CURLOPT_SOURCE_USERPWD: @@ -1382,18 +1375,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.source_userpwd = va_arg(param, char *); break; - case CURLOPT_SOURCE_PATH: - /* - * Use SOURCE PATH - */ - data->set.source_path = va_arg(param, char *); - break; - - case CURLOPT_PASV_HOST: + case CURLOPT_SOURCE_QUOTE: /* - * Indicates whether source or target host is passive + * List of RAW FTP commands to use after a connect */ - data->set.pasvHost = va_arg(param, long)?CURL_SOURCE_PASV:CURL_TARGET_PASV; + data->set.source_quote = va_arg(param, struct curl_slist *); break; case CURLOPT_SOURCE_PREQUOTE: -- cgit v1.2.1 From 177dbc7be07125582ddb7416dba7140b88ab9f62 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Jan 2005 22:13:12 +0000 Subject: Ian Ford asked about support for the FTP command ACCT, and I discovered it is present in RFC959... so now (lib)curl supports it as well. --ftp-account and CURLOPT_FTP_ACCOUNT set the account string. (The server may ask for an account string after PASS have been sent away. The client responds with "ACCT [account string]".) Added test case 228 and 229 to verify the functionality. Updated the test FTP server to support ACCT somewhat. --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8b433f606..f5fc82be4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1396,6 +1396,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.source_postquote = va_arg(param, struct curl_slist *); break; + case CURLOPT_FTP_ACCOUNT: + data->set.ftp_account = va_arg(param, char *); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 4551e7ce49275da08e5fcf0ef46944b42de892fc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 28 Jan 2005 22:14:48 +0000 Subject: KNOWN_BUGS #17 fixed. A DNS cache entry may not remain locked between two curl_easy_perform() invokes. It was previously unlocked at disconnect, which could mean that it remained locked between multiple transfers. The DNS cache may not live as long as the connection cache does, as they are separate. To deal with the lack of DNS (host address) data availability in re-used connections, libcurl now keeps a copy of the IP adress as a string, to be able to show it even on subsequent requests on the same connection. --- lib/url.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f5fc82be4..c8c4360be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1417,12 +1417,6 @@ CURLcode Curl_disconnect(struct connectdata *conn) data = conn->data; - if(conn->dns_entry && data->hostcache) - /* if the DNS entry is still around, and the host cache is not blanked - (which it is for example when a shared one is killed by - curl_multi_cleanup() and similar stuff) */ - Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ - #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, @@ -1503,6 +1497,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->ip_addr_str); #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ defined(USE_THREADING_GETADDRINFO) @@ -1991,10 +1986,22 @@ static void verboseconnect(struct connectdata *conn) char addrbuf[256]; /* Get a printable version of the network address. */ - Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf)); + if(!conn->bits.reuse) { + Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf)); + + /* save the string */ + if(conn->ip_addr_str) + free(conn->ip_addr_str); + conn->ip_addr_str = strdup(addrbuf); + if(!conn->ip_addr_str) + return; /* FAIL */ + } + /* else, + Re-used, ip_addr is not safe to access. */ + infof(data, "Connected to %s (%s) port %d\n", conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, - addrbuf[0] ? addrbuf : "??", conn->port); + conn->ip_addr_str, conn->port); } /* @@ -3533,12 +3540,16 @@ CURLcode Curl_done(struct connectdata **connp, struct SessionHandle *data=conn->data; /* cleanups done even if the connection is re-used */ - if(conn->bits.rangestringalloc) { free(conn->range); conn->bits.rangestringalloc = FALSE; } + if(conn->dns_entry) { + Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ + conn->dns_entry = NULL; + } + /* Cleanup possible redirect junk */ if(conn->newurl) { free(conn->newurl); -- cgit v1.2.1 From c4ff5eb0ca9322a6671d581e80e0c63085b21426 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 29 Jan 2005 13:07:16 +0000 Subject: conn->ip_addr MUST NOT be used on re-used connections --- lib/url.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c8c4360be..de6d4c2c9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1959,6 +1959,8 @@ static CURLcode ConnectPlease(struct connectdata *conn, conn->dns_entry = hostaddr; conn->ip_addr = addr; + Curl_store_ip_addr(conn); + if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { return handleSock5Proxy(conn->proxyuser, conn->proxypasswd, @@ -1982,24 +1984,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, */ static void verboseconnect(struct connectdata *conn) { - struct SessionHandle *data = conn->data; - char addrbuf[256]; - - /* Get a printable version of the network address. */ - if(!conn->bits.reuse) { - Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf)); - - /* save the string */ - if(conn->ip_addr_str) - free(conn->ip_addr_str); - conn->ip_addr_str = strdup(addrbuf); - if(!conn->ip_addr_str) - return; /* FAIL */ - } - /* else, - Re-used, ip_addr is not safe to access. */ - - infof(data, "Connected to %s (%s) port %d\n", + infof(conn->data, "Connected to %s (%s) port %d\n", conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, conn->ip_addr_str, conn->port); } -- cgit v1.2.1 From e6034ea2997e9df872c930cd626fc0c71912fc46 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 30 Jan 2005 12:42:15 +0000 Subject: Use calloc() to save us the memset() call and terminate conn->host.name properly, to avoid reading uninited variables when using file:// (valgrind) --- lib/url.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index de6d4c2c9..d25f43ebc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2182,7 +2182,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, to not have to modify everything at once, we allocate a temporary connection data struct and fill in for comparison purposes. */ - conn = (struct connectdata *)malloc(sizeof(struct connectdata)); + conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1); if(!conn) { *in_connect = NULL; /* clear the pointer */ return CURLE_OUT_OF_MEMORY; @@ -2192,9 +2192,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, any failure */ *in_connect = conn; - /* we have to init the struct */ - memset(conn, 0, sizeof(struct connectdata)); - /* and we setup a few fields in case we end up actually using this struct */ conn->data = data; /* remember our daddy */ conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ @@ -2249,6 +2246,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(NULL == conn->host.rawalloc) return CURLE_OUT_OF_MEMORY; conn->host.name = conn->host.rawalloc; + conn->host.name[0] = 0; /************************************************************* * Parse the URL. -- cgit v1.2.1 From 6a2e21ec8cbaf7c719902e06953d9dbec629ad4f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 9 Feb 2005 13:06:40 +0000 Subject: FTP code turned into state machine. Not completely yet, but a good start. The tag 'before_ftp_statemachine' was set just before this commit in case of future need. --- lib/url.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 125 insertions(+), 33 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d25f43ebc..7de06ff3f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1989,41 +1989,117 @@ static void verboseconnect(struct connectdata *conn) conn->ip_addr_str, conn->port); } +CURLcode Curl_protocol_fdset(struct connectdata *conn, + fd_set *read_fd_set, + fd_set *write_fd_set, + int *max_fdp) +{ + CURLcode res = CURLE_OK; + if(conn->curl_proto_fdset) + res = conn->curl_proto_fdset(conn, read_fd_set, write_fd_set, max_fdp); + return res; +} + +CURLcode Curl_doing_fdset(struct connectdata *conn, + fd_set *read_fd_set, + fd_set *write_fd_set, + int *max_fdp) +{ + CURLcode res = CURLE_OK; + if(conn && conn->curl_doing_fdset) + res = conn->curl_doing_fdset(conn, read_fd_set, write_fd_set, max_fdp); + return res; +} + +/* + * We are doing protocol-specific connecting and this is being called over and + * over from the multi interface until the connection phase is done on + * protocol layer. + */ + +CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done) +{ + CURLcode result=CURLE_OK; + + if(conn && conn->curl_connecting) { + *done = FALSE; + result = conn->curl_connecting(conn, done); + } + else + *done = TRUE; + + return result; +} + +/* + * We are DOING this is being called over and over from the multi interface + * until the DOING phase is done on protocol layer. + */ + +CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) +{ + CURLcode result=CURLE_OK; + + if(conn && conn->curl_doing) { + *done = FALSE; + result = conn->curl_doing(conn, done); + } + else + *done = TRUE; + + return result; +} + /* * We have discovered that the TCP connection has been successful, we can now * proceed with some action. * - * If we're using the multi interface, this host address pointer is most - * likely NULL at this point as we can't keep the resolved info around. This - * may call for some reworking, like a reference counter in the struct or - * something. */ -CURLcode Curl_protocol_connect(struct connectdata *conn) +CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done) { struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; - if(conn->bits.tcpconnect) + *protocol_done = FALSE; + + if(conn->bits.tcpconnect && conn->bits.protoconnstart) { /* We already are connected, get back. This may happen when the connect worked fine in the first call, like when we connect to a local server - or proxy. */ + or proxy. Note that we don't know if the protocol is actually done. + + Unless this protocol doesn't have any protocol-connect callback, as + then we know we're done. */ + if(!conn->curl_connecting) + *protocol_done = TRUE; + return CURLE_OK; + } + + if(!conn->bits.tcpconnect) { - Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ - if(data->set.verbose) - verboseconnect(conn); + if(data->set.verbose) + verboseconnect(conn); + } - if(conn->curl_connect) { - /* is there a protocol-specific connect() procedure? */ + if(!conn->bits.protoconnstart) { + if(conn->curl_connect) { + /* is there a protocol-specific connect() procedure? */ - /* set start time here for timeout purposes in the - * connect procedure, it is later set again for the - * progress meter purpose */ - conn->now = Curl_tvnow(); + /* Set start time here for timeout purposes in the connect procedure, it + is later set again for the progress meter purpose */ + conn->now = Curl_tvnow(); - /* Call the protocol-specific connect function */ - result = conn->curl_connect(conn); + /* Call the protocol-specific connect function */ + result = conn->curl_connect(conn, protocol_done); + } + else + *protocol_done = TRUE; + + /* it has started, possibly even completed but that knowledge isn't stored + in this bit! */ + conn->bits.protoconnstart = TRUE; } return result; /* pass back status */ @@ -2733,6 +2809,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_do_more = Curl_ftp_nextconnect; conn->curl_done = Curl_ftp_done; conn->curl_connect = Curl_ftp_connect; + conn->curl_connecting = Curl_ftp_multi_statemach; + conn->curl_doing = Curl_ftp_doing; + conn->curl_proto_fdset = Curl_ftp_fdset; + conn->curl_doing_fdset = Curl_ftp_fdset; conn->curl_disconnect = Curl_ftp_disconnect; } @@ -3385,17 +3465,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ static CURLcode SetupConnection(struct connectdata *conn, - struct Curl_dns_entry *hostaddr) + struct Curl_dns_entry *hostaddr, + bool *protocol_done) { struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; Curl_pgrsTime(data, TIMER_NAMELOOKUP); - if(conn->protocol & PROT_FILE) + if(conn->protocol & PROT_FILE) { /* There's nothing in this function to setup if we're only doing a file:// transfer */ + *protocol_done = TRUE; return result; + } + *protocol_done = FALSE; /* default to not done */ /************************************************************* * Send user-agent to HTTP proxies even if the target protocol @@ -3416,13 +3500,13 @@ static CURLcode SetupConnection(struct connectdata *conn, conn->headerbytecount = 0; if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { - bool connected; + bool connected = FALSE; /* Connect only if not already connected! */ result = ConnectPlease(conn, hostaddr, &connected); if(connected) { - result = Curl_protocol_connect(conn); + result = Curl_protocol_connect(conn, protocol_done); if(CURLE_OK == result) conn->bits.tcpconnect = TRUE; } @@ -3436,6 +3520,7 @@ static CURLcode SetupConnection(struct connectdata *conn, else { Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ conn->bits.tcpconnect = TRUE; + *protocol_done = TRUE; if(data->set.verbose) verboseconnect(conn); } @@ -3460,7 +3545,8 @@ static CURLcode SetupConnection(struct connectdata *conn, CURLcode Curl_connect(struct SessionHandle *data, struct connectdata **in_connect, - bool *asyncp) + bool *asyncp, + bool *protocol_done) { CURLcode code; struct Curl_dns_entry *dns; @@ -3476,7 +3562,7 @@ CURLcode Curl_connect(struct SessionHandle *data, /* If an address is available it means that we already have the name resolved, OR it isn't async. If so => continue connecting from here */ - code = SetupConnection(*in_connect, dns); + code = SetupConnection(*in_connect, dns, protocol_done); /* else response will be received and treated async wise */ } @@ -3494,12 +3580,16 @@ CURLcode Curl_connect(struct SessionHandle *data, } /* Call this function after Curl_connect() has returned async=TRUE and - then a successful name resolve has been received */ -CURLcode Curl_async_resolved(struct connectdata *conn) + then a successful name resolve has been received. + + Note: this function disconnects and frees the conn data in case of + resolve failure */ +CURLcode Curl_async_resolved(struct connectdata *conn, + bool *protocol_done) { #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ defined(USE_THREADING_GETADDRINFO) - CURLcode code = SetupConnection(conn, conn->async.dns); + CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done); if(code) /* We're not allowed to return failure with memory left allocated @@ -3573,7 +3663,7 @@ CURLcode Curl_done(struct connectdata **connp, return result; } -CURLcode Curl_do(struct connectdata **connp) +CURLcode Curl_do(struct connectdata **connp, bool *done) { CURLcode result=CURLE_OK; struct connectdata *conn = *connp; @@ -3583,7 +3673,7 @@ CURLcode Curl_do(struct connectdata **connp) if(conn->curl_do) { /* generic protocol-specific function pointer set in curl_connect() */ - result = conn->curl_do(conn); + result = conn->curl_do(conn, done); /* This was formerly done in transfer.c, but we better do it here */ @@ -3603,8 +3693,10 @@ CURLcode Curl_do(struct connectdata **connp) if(CURLE_OK == result) { bool async; + bool protocol_done = TRUE; + /* Now, redo the connect and get a new connection */ - result = Curl_connect(data, connp, &async); + result = Curl_connect(data, connp, &async, &protocol_done); if(CURLE_OK == result) { /* We have connected or sent away a name resolve query fine */ @@ -3617,13 +3709,13 @@ CURLcode Curl_do(struct connectdata **connp) return result; /* Resolved, continue with the connection */ - result = Curl_async_resolved(conn); + result = Curl_async_resolved(conn, &protocol_done); if(result) return result; } /* ... finally back to actually retry the DO phase */ - result = conn->curl_do(conn); + result = conn->curl_do(conn, done); } } } -- cgit v1.2.1 From 89cac6f25cd14dc2a0ff4164ccff761c3a6e6304 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 9 Feb 2005 22:47:57 +0000 Subject: prevent a compiler warning --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7de06ff3f..42b7350b0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3599,6 +3599,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, return code; #else (void)conn; + (void)protocol_done; return CURLE_OK; #endif } -- cgit v1.2.1 From 0472629222e92cdeafae00b0acc3dd12c2e0e01e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 9 Mar 2005 22:13:52 +0000 Subject: As reported by 'nodak sodak' we should check for a NULL pointer before referencing the proxy name pointer. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 42b7350b0..a6e60a92a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1831,7 +1831,7 @@ static int handleSock5Proxy(const char *proxy_name, return 1; } else if (socksreq[1] == 255) { - if (proxy_name[0] == 0) { + if (!proxy_name || !*proxy_name) { failf(conn->data, "No authentication method was acceptable. (It is quite likely" " that the SOCKS5 server wanted a username/password, since none" -- cgit v1.2.1 From d1d35ba85fe6f8a9e6a86d2a6c60109cf90edd6c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 10 Mar 2005 23:15:29 +0000 Subject: Christopher R. Palmer made it possible to build libcurl with the USE_WINDOWS_SSPI on Windows, and then libcurl will be built to use the native way to do NTLM. SSPI also allows libcurl to pass on the current user and its password in the request. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a6e60a92a..06b330391 100644 --- a/lib/url.c +++ b/lib/url.c @@ -832,7 +832,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { long auth = va_arg(param, long); /* switch off bits we can't support */ -#ifndef USE_SSLEAY +#if ! defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI) auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef HAVE_GSSAPI @@ -1449,6 +1449,10 @@ CURLcode Curl_disconnect(struct connectdata *conn) data->state.authhost.want; data->state.authproblem = FALSE; + +#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) + Curl_ntlm_cleanup(conn); +#endif } if(conn->curl_disconnect) -- cgit v1.2.1 From fb9ae9d0e2e3397d3072fd89a4f103907bff1a28 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 11 Mar 2005 05:49:04 +0000 Subject: Fixed some compiler warnings. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 06b330391..921df3d15 100644 --- a/lib/url.c +++ b/lib/url.c @@ -130,6 +130,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "url.h" #include "connect.h" #include "inet_ntop.h" +#include "http_ntlm.h" #include #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -- cgit v1.2.1 From 62970da6752495421543bddcefd0b8eedd6cbb13 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 14 Mar 2005 00:00:45 +0000 Subject: Removed security.h since it shadows an include file mingw needs when building for SSPI support. The contents of the file has been moved into the krb4.h file. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 921df3d15..bd5f2ed53 100644 --- a/lib/url.c +++ b/lib/url.c @@ -141,7 +141,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include #ifdef HAVE_KRB4 -#include "security.h" +#include "krb4.h" #endif #include "memory.h" -- cgit v1.2.1 From efaf6886505cd29084af05aa06edc19fd71bdfe9 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 15 Mar 2005 21:00:46 +0000 Subject: Fixed ftp support with uClibc due to differing inet_ntoa_r() behaviour. --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bd5f2ed53..e3e24a5ce 100644 --- a/lib/url.c +++ b/lib/url.c @@ -104,7 +104,6 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "base64.h" #include "ssluse.h" #include "hostip.h" -#include "if2ip.h" #include "transfer.h" #include "sendf.h" #include "progress.h" -- cgit v1.2.1 From 0b4543113982c5d81c71d3b0250ed68fb13e75ae Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Mon, 4 Apr 2005 12:30:03 +0000 Subject: hostthre.c: destroy_thread_data() made public. Called from url.c: Curl_disconnect(). --- lib/url.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e3e24a5ce..9d62f4290 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1503,11 +1503,12 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->ip_addr_str); -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ - defined(USE_THREADING_GETADDRINFO) - /* possible left-overs from the async name resolve */ + /* possible left-overs from the async name resolvers */ +#if defined(USE_ARES) Curl_safefree(conn->async.hostname); Curl_safefree(conn->async.os_specific); +#elif defined(CURLRES_THREADED) + Curl_destroy_thread_data(&conn->async); #endif Curl_free_ssl_config(&conn->ssl_config); -- cgit v1.2.1 From 6e619393824922118317689ef59a73c556b7ef98 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 7 Apr 2005 15:27:13 +0000 Subject: GnuTLS support added. There's now a "generic" SSL layer that we use all over internally, with code provided by sslgen.c. All SSL-layer-specific code is then written in ssluse.c (for OpenSSL) and gtls.c (for GnuTLS). As far as possible, internals should not need to know what SSL layer that is in use. Building with GnuTLS currently makes two test cases fail. TODO.gnutls contains a few known outstanding issues for the GnuTLS support. GnuTLS support is enabled with configure --with-gnutls --- lib/url.c | 120 ++++++++------------------------------------------------------ 1 file changed, 14 insertions(+), 106 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9d62f4290..7174e8cf0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -102,7 +102,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "formdata.h" #include "base64.h" -#include "ssluse.h" +#include "sslgen.h" #include "hostip.h" #include "transfer.h" #include "sendf.h" @@ -154,7 +154,6 @@ static bool ConnectionExists(struct SessionHandle *data, struct connectdata **usethis); static long ConnectionStore(struct SessionHandle *data, struct connectdata *conn); -static bool safe_strequal(char* str1, char* str2); #ifndef USE_ARES /* not for Win32, unless it is cygwin @@ -211,11 +210,8 @@ CURLcode Curl_close(struct SessionHandle *data) } } -#ifdef USE_SSLEAY /* Close down all open SSL info and sessions */ - Curl_SSL_Close_All(data); -#endif - + Curl_ssl_close_all(data); Curl_safefree(data->state.first_host); Curl_safefree(data->state.scratch); @@ -832,7 +828,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { long auth = va_arg(param, long); /* switch off bits we can't support */ -#if ! defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI) +#ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef HAVE_GSSAPI @@ -852,7 +848,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { long auth = va_arg(param, long); /* switch off bits we can't support */ -#ifndef USE_SSLEAY +#ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef HAVE_GSSAPI @@ -1153,14 +1149,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ argptr = va_arg(param, char *); if (argptr && argptr[0]) - result = Curl_SSL_set_engine(data, argptr); + result = Curl_ssl_set_engine(data, argptr); break; case CURLOPT_SSLENGINE_DEFAULT: /* * flag to set engine as default. */ - result = Curl_SSL_set_engine_default(data); + result = Curl_ssl_set_engine_default(data); break; case CURLOPT_CRLF: /* @@ -1450,9 +1446,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) data->state.authproblem = FALSE; -#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) Curl_ntlm_cleanup(conn); -#endif } if(conn->curl_disconnect) @@ -1481,7 +1475,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) freed with idn_free() since this was allocated by libidn */ #endif - Curl_SSL_Close(conn); + Curl_ssl_close(conn); /* close possibly still open sockets */ if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) @@ -2419,10 +2413,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(checkprefix("GOPHER.", conn->host.name)) strcpy(conn->protostr, "gopher"); -#ifdef USE_SSLEAY +#ifdef USE_SSL else if(checkprefix("FTPS", conn->host.name)) strcpy(conn->protostr, "ftps"); -#endif /* USE_SSLEAY */ +#endif /* USE_SSL */ else if(checkprefix("FTP.", conn->host.name)) strcpy(conn->protostr, "ftp"); else if(checkprefix("TELNET.", conn->host.name)) @@ -2728,7 +2722,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif } else if (strequal(conn->protostr, "HTTPS")) { -#if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP) +#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) conn->port = (data->set.use_port && data->state.allow_port)? data->set.use_port:PORT_HTTPS; @@ -2740,11 +2734,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; -#else /* USE_SSLEAY */ +#else /* USE_SS */ failf(data, LIBCURL_NAME " was built with SSL disabled, https: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; -#endif /* !USE_SSLEAY */ +#endif /* !USE_SSL */ } else if (strequal(conn->protostr, "GOPHER")) { #ifndef CURL_DISABLE_GOPHER @@ -2774,7 +2768,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, int port = PORT_FTP; if(strequal(conn->protostr, "FTPS")) { -#ifdef USE_SSLEAY +#ifdef USE_SSL conn->protocol |= PROT_FTPS|PROT_SSL; conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */ port = PORT_FTPS; @@ -2782,7 +2776,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, failf(data, LIBCURL_NAME " was built with SSL disabled, ftps: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; -#endif /* !USE_SSLEAY */ +#endif /* !USE_SSL */ } conn->port = (data->set.use_port && data->state.allow_port)? @@ -3739,89 +3733,3 @@ CURLcode Curl_do_more(struct connectdata *conn) return result; } -static bool safe_strequal(char* str1, char* str2) -{ - if(str1 && str2) - /* both pointers point to something then compare them */ - return strequal(str1, str2); - else - /* if both pointers are NULL then treat them as equal */ - return (!str1 && !str2); -} - -bool -Curl_ssl_config_matches(struct ssl_config_data* data, - struct ssl_config_data* needle) -{ - if((data->version == needle->version) && - (data->verifypeer == needle->verifypeer) && - (data->verifyhost == needle->verifyhost) && - safe_strequal(data->CApath, needle->CApath) && - safe_strequal(data->CAfile, needle->CAfile) && - safe_strequal(data->random_file, needle->random_file) && - safe_strequal(data->egdsocket, needle->egdsocket) && - safe_strequal(data->cipher_list, needle->cipher_list)) - return TRUE; - - return FALSE; -} - -bool -Curl_clone_ssl_config(struct ssl_config_data *source, - struct ssl_config_data *dest) -{ - dest->verifyhost = source->verifyhost; - dest->verifypeer = source->verifypeer; - dest->version = source->version; - - if(source->CAfile) { - dest->CAfile = strdup(source->CAfile); - if(!dest->CAfile) - return FALSE; - } - - if(source->CApath) { - dest->CApath = strdup(source->CApath); - if(!dest->CApath) - return FALSE; - } - - if(source->cipher_list) { - dest->cipher_list = strdup(source->cipher_list); - if(!dest->cipher_list) - return FALSE; - } - - if(source->egdsocket) { - dest->egdsocket = strdup(source->egdsocket); - if(!dest->egdsocket) - return FALSE; - } - - if(source->random_file) { - dest->random_file = strdup(source->random_file); - if(!dest->random_file) - return FALSE; - } - - return TRUE; -} - -void Curl_free_ssl_config(struct ssl_config_data* sslc) -{ - if(sslc->CAfile) - free(sslc->CAfile); - - if(sslc->CApath) - free(sslc->CApath); - - if(sslc->cipher_list) - free(sslc->cipher_list); - - if(sslc->egdsocket) - free(sslc->egdsocket); - - if(sslc->random_file) - free(sslc->random_file); -} - -- cgit v1.2.1 From 63d109f7be8ddd027c86355dd09d02189b731a46 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 18 Apr 2005 19:41:04 +0000 Subject: Olivier reported that even though he used CURLOPT_PORT, libcurl clearly still used the default port. He was right. I fixed the problem and added the test cases 521, 522 and 523 to verify the fix. --- lib/url.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7174e8cf0..12597311a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2707,8 +2707,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (strequal(conn->protostr, "HTTP")) { #ifndef CURL_DISABLE_HTTP - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_HTTP; + conn->port = PORT_HTTP; conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; @@ -2724,8 +2723,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, else if (strequal(conn->protostr, "HTTPS")) { #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_HTTPS; + conn->port = PORT_HTTPS; conn->remote_port = PORT_HTTPS; conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; @@ -2742,8 +2740,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } else if (strequal(conn->protostr, "GOPHER")) { #ifndef CURL_DISABLE_GOPHER - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_GOPHER; + conn->port = PORT_GOPHER; conn->remote_port = PORT_GOPHER; /* Skip // in path if present */ if (isdigit((int)conn->path[1])) { @@ -2779,8 +2776,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #endif /* !USE_SSL */ } - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:port; + conn->port = port; conn->remote_port = port; conn->protocol |= PROT_FTP; @@ -2852,8 +2848,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* telnet testing factory */ conn->protocol |= PROT_TELNET; - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port: PORT_TELNET; + conn->port = PORT_TELNET; conn->remote_port = PORT_TELNET; conn->curl_do = Curl_telnet; conn->curl_done = Curl_telnet_done; @@ -2865,8 +2860,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, else if (strequal(conn->protostr, "DICT")) { #ifndef CURL_DISABLE_DICT conn->protocol |= PROT_DICT; - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_DICT; + conn->port = PORT_DICT; conn->remote_port = PORT_DICT; conn->curl_do = Curl_dict; conn->curl_done = NULL; /* no DICT-specific done */ @@ -2878,8 +2872,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, else if (strequal(conn->protostr, "LDAP")) { #ifndef CURL_DISABLE_LDAP conn->protocol |= PROT_LDAP; - conn->port = (data->set.use_port && data->state.allow_port)? - data->set.use_port:PORT_LDAP; + conn->port = PORT_LDAP; conn->remote_port = PORT_LDAP; conn->curl_do = Curl_ldap; conn->curl_done = NULL; /* no LDAP-specific done */ @@ -3092,7 +3085,31 @@ static CURLcode CreateConnection(struct SessionHandle *data, else tmp = strrchr(conn->host.name, ':'); - if (tmp) { + if(data->set.use_port && data->state.allow_port) { + /* if set, we use this and ignore the port possibly given in the URL */ + conn->remote_port = data->set.use_port; + if(tmp) + *tmp = '\0'; /* cut off the name there anyway - if there was a port + number - since the port number is to be ignored! */ + if(conn->bits.httpproxy) { + /* we need to create new URL with the new port number */ + char *url; + + url = aprintf("http://%s:%d%s", conn->host.name, conn->remote_port, + conn->path); + if(!url) + return CURLE_OUT_OF_MEMORY; + + if(data->change.url_alloc) + free(data->change.url); + + data->change.url = url; + data->change.url_alloc = TRUE; + } + } + else if (tmp) { + /* no CURLOPT_PORT given, extract the one from the URL */ + char *rest; unsigned long port; -- cgit v1.2.1 From 8bd6d6a4ded4e9f5726effc4ee85f822fe3926e7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 19 Apr 2005 23:37:45 +0000 Subject: added typecast when converting from long to unsigned short, to prevent compiler warning --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 12597311a..e75c29043 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3087,7 +3087,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(data->set.use_port && data->state.allow_port) { /* if set, we use this and ignore the port possibly given in the URL */ - conn->remote_port = data->set.use_port; + conn->remote_port = (unsigned short)data->set.use_port; if(tmp) *tmp = '\0'; /* cut off the name there anyway - if there was a port number - since the port number is to be ignored! */ -- cgit v1.2.1 From 01165e08e0d131b399fba2190f17af67e66f0888 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2005 21:39:48 +0000 Subject: Fred New reported a bug where we used Basic auth and user name and password in .netrc, and when following a Location: the subsequent requests didn't properly use the auth as found in the netrc file. Added test case 257 to verify my fix. --- lib/url.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e75c29043..fb9c5905d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3147,15 +3147,23 @@ static CURLcode CreateConnection(struct SessionHandle *data, user, passwd); } + conn->bits.netrc = FALSE; if (data->set.use_netrc != CURL_NETRC_IGNORED) { if(Curl_parsenetrc(conn->host.name, user, passwd, data->set.netrc_file)) { - infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n", + infof(data, "Couldn't find host %s in the " DOT_CHAR + "netrc file, using defaults\n", conn->host.name); } - else + else { + /* set bits.netrc TRUE to remember that we got the name from a .netrc + file, so that it is safe to use even if we followed a Location: to a + different host or similar. */ + conn->bits.netrc = TRUE; + conn->bits.user_passwd = 1; /* enable user+password */ + } } /* If our protocol needs a password and we have none, use the defaults */ -- cgit v1.2.1 From 6b1220b61d5ed2481dbf31714a68be6ef6eed3da Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 26 Apr 2005 13:08:49 +0000 Subject: Cory Nelson's work on nuking compiler warnings when building on x64 with VS2005. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fb9c5905d..75e340064 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1748,7 +1748,7 @@ static int handleSock5Proxy(const char *proxy_name, ssize_t written; int result; CURLcode code; - int sock = conn->sock[FIRSTSOCKET]; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; Curl_nonblock(sock, FALSE); -- cgit v1.2.1 From 5f538ce3f81565d7a9aa3d112cd3ebc023390e55 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 12 May 2005 08:51:30 +0000 Subject: typecast to fix warning on 64bit systems --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 75e340064..6d4ed94aa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3373,9 +3373,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_ALARM /* alarm() makes a signal get sent when the timeout fires off, and that will abort system calls */ - prev_alarm = alarm(data->set.connecttimeout? - data->set.connecttimeout: - data->set.timeout); + prev_alarm = alarm((unsigned int) (data->set.connecttimeout? + data->set.connecttimeout: + data->set.timeout)); /* We can expect the conn->created time to be "now", as that was just recently set in the beginning of this function and nothing slow has been done since then until now. */ -- cgit v1.2.1 From 3f23e8443e67e5f415aaf532062c1054ab1b9a1a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 12 May 2005 13:44:25 +0000 Subject: oops, found by bug reported in bug report #1200661 --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6d4ed94aa..8adcbda8d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1442,7 +1442,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) data->state.authproxy.done = FALSE; data->state.authproxy.picked = - data->state.authhost.want; + data->state.authproxy.want; data->state.authproblem = FALSE; -- cgit v1.2.1 From ecdcb0ef67882b6d80e4849142bb3f398e1fac0b Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Sat, 14 May 2005 06:00:40 +0000 Subject: Some patches for (a stricter/smarter) gcc 4.0 and warnings like: 'x' may be used uninitialized in this function. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8adcbda8d..24c0a7407 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2217,7 +2217,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, char *at; CURLcode result=CURLE_OK; struct connectdata *conn; - struct connectdata *conn_temp; + struct connectdata *conn_temp = NULL; size_t urllen; struct Curl_dns_entry *hostaddr; #if defined(HAVE_ALARM) && !defined(USE_ARES) -- cgit v1.2.1 From 4a091bbd8a30685d4f676a023c0488abb0469d3f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 18 May 2005 20:01:01 +0000 Subject: Bug report #1204435 identified a problem with malformed URLs like "http://somehost?data" as it added a slash too much in the request ("GET /?data/"...). Added test case 260 to verify. --- lib/url.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 24c0a7407..33afb0108 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2382,8 +2382,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, strcpy(conn->protostr, "file"); /* store protocol string lowercase */ } else { - /* Set default path */ - strcpy(conn->path, "/"); + /* clear path */ + conn->path[0]=0; if (2 > sscanf(data->change.url, "%15[^\n:]://%[^\n/]%[^\n]", @@ -2444,13 +2444,26 @@ static CURLcode CreateConnection(struct SessionHandle *data, tmp = strchr(conn->host.name, '?'); if(tmp) { - /* The right part of the ?-letter needs to be moved to prefix - the current path buffer! */ - size_t len = strlen(tmp); - /* move the existing path plus the zero byte */ - memmove(conn->path+len+1, conn->path, strlen(conn->path)+1); + /* We must insert a slash before the '?'-letter in the URL. If the URL had + a slash after the '?', that is where the path currently begins and the + '?string' is still part of the host name. + + We must move the trailing part from the host name and put it first in + the path. And have it all prefixed with a slash. + */ + + size_t hostlen = strlen(tmp); + size_t pathlen = strlen(conn->path); + + /* move the existing path plus the zero byte forward, to make room for + the host-name part */ + memmove(conn->path+hostlen+1, conn->path, pathlen+1); + + /* now copy the trailing host part in front of the existing path */ + memcpy(conn->path+1, tmp, hostlen); + conn->path[0]='/'; /* prepend the missing slash */ - memcpy(conn->path+1, tmp, len); /* now copy the prefix part */ + *tmp=0; /* now cut off the hostname at the ? */ } -- cgit v1.2.1 From eff36caea8bfcdc05be67a240d11a2387e8a0648 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 19 May 2005 07:21:18 +0000 Subject: additional fix for the malformed URL fix of yday --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 33afb0108..9b0006007 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2466,6 +2466,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, *tmp=0; /* now cut off the hostname at the ? */ } + else if(!conn->path[0]) { + /* if there's no path set, use a single slash */ + strcpy(conn->path, "/"); + } /* If the URL is malformatted (missing a '/' after hostname before path) we * insert a slash here. The only letter except '/' we accept to start a path -- cgit v1.2.1 From 300b4a915820293d6ba3a83150cbb585c288a482 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 31 May 2005 13:03:26 +0000 Subject: Todd Kulesza reported a flaw in the proxy option, since a numerical IPv6 address was not possible to use. It is now, but requires it written RFC2732-style, within brackets - which incidently is how you enter numerical IPv6 addresses in URLs. Test case 263 added to verify. --- lib/url.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9b0006007..4ccd27438 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2943,25 +2943,44 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* We use 'proxyptr' to point to the proxy name from now on... */ char *proxyptr=proxydup; + char *portptr; if(NULL == proxydup) { failf(data, "memory shortage"); return CURLE_OUT_OF_MEMORY; } - /* Daniel Dec 10, 1998: - We do the proxy host string parsing here. We want the host name and the - port name. Accept a protocol:// prefix, even though it should just be - ignored. */ + /* We do the proxy host string parsing here. We want the host name and the + * port name. Accept a protocol:// prefix, even though it should just be + * ignored. + */ - /* 1. skip the protocol part if present */ + /* Skip the protocol part if present */ endofprot=strstr(proxyptr, "://"); - if(endofprot) { + if(endofprot) proxyptr = endofprot+3; + + /* start scanning for port number at this point */ + portptr = proxyptr; + + /* detect and extract RFC2732-style IPv6-addresses */ + if(*proxyptr == '[') { + char *ptr = ++proxyptr; /* advance beyond the initial bracket */ + while(*ptr && (isxdigit((int)*ptr) || (*ptr == ':'))) + ptr++; + if(*ptr == ']') { + /* yeps, it ended nicely with a bracket as well */ + *ptr = 0; + portptr = ptr+1; + } + /* Note that if this didn't end with a bracket, we still advanced the + * proxyptr first, but I can't see anything wrong with that as no host + * name nor a numeric can legally start with a bracket. + */ } - /* allow user to specify proxy.server.com:1080 if desired */ - prox_portno = strchr (proxyptr, ':'); + /* Get port number off proxy.server.com:1080 */ + prox_portno = strchr(portptr, ':'); if (prox_portno) { *prox_portno = 0x0; /* cut off number from host name */ prox_portno ++; -- cgit v1.2.1 From 3b60bb725913ce7339aefef0a14b12df4c24db60 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 22 Jun 2005 22:24:10 +0000 Subject: David Shaw's fix that unifies proxy string treatment so that a proxy given with CURLOPT_PROXY can use a http:// prefix and user + password. The user and password fields are now also URL decoded properly. Test case 264 added to verify. --- lib/url.c | 109 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 51 insertions(+), 58 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4ccd27438..469e6b33c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2502,11 +2502,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", proxyuser, proxypasswd); - conn->proxyuser = strdup(proxyuser); + conn->proxyuser = curl_unescape(proxyuser,0); if(!conn->proxyuser) return CURLE_OUT_OF_MEMORY; - conn->proxypasswd = strdup(proxypasswd); + conn->proxypasswd = curl_unescape(proxypasswd,0); if(!conn->proxypasswd) return CURLE_OUT_OF_MEMORY; } @@ -2611,62 +2611,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if(proxy && *proxy) { - /* we have a proxy here to set */ - char *ptr; - char proxyuser[MAX_CURL_USER_LENGTH]; - char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; - - char *fineptr; - - /* skip the possible protocol piece */ - ptr=strstr(proxy, "://"); - if(ptr) - ptr += 3; - else - ptr = proxy; - - fineptr = ptr; - - /* check for an @-letter */ - ptr = strchr(ptr, '@'); - if(ptr && (2 == sscanf(fineptr, - "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - proxyuser, proxypasswd))) { - CURLcode res = CURLE_OK; - - /* found user and password, rip them out */ - Curl_safefree(conn->proxyuser); - conn->proxyuser = strdup(proxyuser); - - if(!conn->proxyuser) - res = CURLE_OUT_OF_MEMORY; - else { - Curl_safefree(conn->proxypasswd); - conn->proxypasswd = strdup(proxypasswd); - - if(!conn->proxypasswd) - res = CURLE_OUT_OF_MEMORY; - } - - if(CURLE_OK == res) { - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - ptr = strdup(ptr+1); /* the right side of the @-letter */ - - if(ptr) { - free(proxy); /* free the former proxy string */ - proxy = ptr; /* now use this instead */ - } - else - res = CURLE_OUT_OF_MEMORY; - } - - if(res) { - free(proxy); /* free the allocated proxy string */ - return res; - } - } - data->change.proxy = proxy; data->change.proxy_alloc=TRUE; /* this needs to be freed later */ conn->bits.httpproxy = TRUE; @@ -2944,6 +2888,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* We use 'proxyptr' to point to the proxy name from now on... */ char *proxyptr=proxydup; char *portptr; + char *atsign; if(NULL == proxydup) { failf(data, "memory shortage"); @@ -2960,6 +2905,54 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(endofprot) proxyptr = endofprot+3; + /* Is there a username and password given in this proxy url? */ + atsign = strchr(proxyptr, '@'); + if(atsign) { + char proxyuser[MAX_CURL_USER_LENGTH]; + char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; + + if(2 == sscanf(proxyptr, + "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", + proxyuser, proxypasswd)) { + CURLcode res = CURLE_OK; + + /* found user and password, rip them out. note that we are + unescaping them, as there is otherwise no way to have a + username or password with reserved characters like ':' in + them. */ + Curl_safefree(conn->proxyuser); + conn->proxyuser = curl_unescape(proxyuser,0); + + if(!conn->proxyuser) + res = CURLE_OUT_OF_MEMORY; + else { + Curl_safefree(conn->proxypasswd); + conn->proxypasswd = curl_unescape(proxypasswd,0); + + if(!conn->proxypasswd) + res = CURLE_OUT_OF_MEMORY; + } + + if(CURLE_OK == res) { + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + atsign = strdup(atsign+1); /* the right side of the @-letter */ + + if(atsign) { + free(proxydup); /* free the former proxy string */ + proxydup = proxyptr = atsign; /* now use this instead */ + } + else + res = CURLE_OUT_OF_MEMORY; + } + + if(res) { + free(proxydup); /* free the allocated proxy string */ + return res; + } + } + } + /* start scanning for port number at this point */ portptr = proxyptr; -- cgit v1.2.1 From 465e19dbe9603bacba53bd73a607d5fbb37c08a4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 12 Jul 2005 18:15:34 +0000 Subject: Adrian Schuur added trailer support in the chunked encoding stream. The trailer is then sent to the normal header callback/stream. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 469e6b33c..9c05c803a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1496,6 +1496,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->ip_addr_str); + Curl_safefree(conn->trailer); /* possible left-overs from the async name resolvers */ #if defined(USE_ARES) -- cgit v1.2.1 From 492290499105496458c4f76abdaef115adb0ec4c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 Jul 2005 12:44:11 +0000 Subject: Simplified the code within curl_easy_perform() that calls Curl_perform(). Pointed out by Bjorn Reese. --- lib/url.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9c05c803a..98662ceb9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -372,14 +372,12 @@ CURLcode Curl_open(struct SessionHandle **curl) return CURLE_OK; } -CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) +CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + va_list param) { - va_list param; char *argptr; CURLcode result = CURLE_OK; - va_start(param, option); - switch(option) { case CURLOPT_DNS_CACHE_TIMEOUT: data->set.dns_cache_timeout = va_arg(param, int); -- cgit v1.2.1 From 2236ba0d206fe9fef5d93889ee652feaa03fe089 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 27 Jul 2005 22:17:14 +0000 Subject: Peteris Krumins added CURLOPT_COOKIELIST and CURLINFO_COOKIELIST, which is a simple interface to extracting and setting cookies in libcurl's internal "cookie jar". See the new cookie_interface.c example code. --- lib/url.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 98662ceb9..07a34a94e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -773,6 +773,37 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.cookiesession = (bool)va_arg(param, long); break; + + case CURLOPT_COOKIELIST: + argptr = va_arg(param, char *); + + if (argptr == NULL) + break; + + if (strequal(argptr, "ALL")) { + if (data->cookies == NULL) { + break; + } + else { + /* clear all cookies */ + Curl_cookie_freelist(data->cookies->cookies); + data->cookies->cookies = NULL; + break; + } + } + + if (!data->cookies) + /* if cookie engine was not running, activate it */ + data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); + + if (checkprefix("Set-Cookie:", argptr)) + /* HTTP Header format line */ + Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL); + + else + /* Netscape format line */ + Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL); + break; #endif /* CURL_DISABLE_COOKIES */ case CURLOPT_HTTPGET: -- cgit v1.2.1 From 726b9e2240a272304cefc61b6fb9d9bb9a9a78f4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 27 Jul 2005 22:29:50 +0000 Subject: If any of the options CURLOPT_HTTPGET, CURLOPT_POST and CURLOPT_HTTPPOST is set to 1, CURLOPT_NOBODY will now automatically be set to 0. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 07a34a94e..7c34ee19a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -644,8 +644,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* Does this option serve a purpose anymore? Yes it does, when CURLOPT_POSTFIELDS isn't used and the POST data is read off the callback! */ - if(va_arg(param, long)) + if(va_arg(param, long)) { data->set.httpreq = HTTPREQ_POST; + data->set.opt_no_body = FALSE; /* this is implied */ + } else data->set.httpreq = HTTPREQ_GET; break; @@ -680,6 +682,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.httppost = va_arg(param, struct curl_httppost *); data->set.httpreq = HTTPREQ_POST_FORM; + data->set.opt_no_body = FALSE; /* this is implied */ break; case CURLOPT_REFERER: @@ -813,6 +816,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(va_arg(param, long)) { data->set.httpreq = HTTPREQ_GET; data->set.upload = FALSE; /* switch off upload */ + data->set.opt_no_body = FALSE; /* this is implied */ } break; -- cgit v1.2.1 From ec3f269d1fa82a1101a638f1df6fd14c9fc831e5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Jul 2005 21:50:34 +0000 Subject: now strdups the cookielist inpointer before passed on, as the cookie function modifies it --- lib/url.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7c34ee19a..2cef9e471 100644 --- a/lib/url.c +++ b/lib/url.c @@ -780,32 +780,37 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_COOKIELIST: argptr = va_arg(param, char *); - if (argptr == NULL) + if(argptr == NULL) break; - if (strequal(argptr, "ALL")) { - if (data->cookies == NULL) { - break; - } - else { + if(strequal(argptr, "ALL")) { + if(data->cookies) { /* clear all cookies */ Curl_cookie_freelist(data->cookies->cookies); data->cookies->cookies = NULL; - break; } + break; } - if (!data->cookies) + if(!data->cookies) /* if cookie engine was not running, activate it */ data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); - if (checkprefix("Set-Cookie:", argptr)) + argptr = strdup(argptr); + if(!argptr) { + result = CURLE_OUT_OF_MEMORY; + break; + } + + if(checkprefix("Set-Cookie:", argptr)) /* HTTP Header format line */ Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL); else /* Netscape format line */ Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL); + + free(argptr); break; #endif /* CURL_DISABLE_COOKIES */ -- cgit v1.2.1 From e358a24a75d42714795200c9528c3f5ba90cdab2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Jul 2005 21:53:09 +0000 Subject: reset the numcookies counter too (I missed it in the previous commit) --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2cef9e471..bb8aa1819 100644 --- a/lib/url.c +++ b/lib/url.c @@ -788,6 +788,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* clear all cookies */ Curl_cookie_freelist(data->cookies->cookies); data->cookies->cookies = NULL; + data->cookies->numcookies = 0; } break; } -- cgit v1.2.1 From aeb04136f7c2c72f9005546bfff22c4046f93a74 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 7 Aug 2005 21:39:44 +0000 Subject: Don't prevent FTPS:// through a http proxy, as we cannot know if it works or not! --- lib/url.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bb8aa1819..f587b79f1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2786,12 +2786,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, !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) { - /* FTPS is a hacked protocol and does not work through your - ordinary http proxy! */ - failf(data, "ftps does not work through http proxy!"); - return CURLE_UNSUPPORTED_PROTOCOL; - } #ifndef CURL_DISABLE_HTTP conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; -- cgit v1.2.1 From 493d6033aa299b614f0edecd86e1eccf95a86a00 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 7 Aug 2005 22:59:06 +0000 Subject: Jon Grubbs filed bug report #1249962 which identified a problem with NTLM on a HTTP proxy if an FTP URL was given. libcurl now properly switches to pure HTTP internally when an HTTP proxy is used, even for FTP URLs. The problem would also occur with other multi-pass auth methods. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f587b79f1..3698affd1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2651,9 +2651,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if(proxy && *proxy) { + long bits = conn->protocol & (PROT_HTTPS|PROT_SSL); data->change.proxy = proxy; data->change.proxy_alloc=TRUE; /* this needs to be freed later */ conn->bits.httpproxy = TRUE; + + /* force this to become HTTP */ + conn->protocol = PROT_HTTP | bits; } } /* if (!nope) - it wasn't specified non-proxy */ } /* NO_PROXY wasn't specified or '*' */ @@ -2789,6 +2793,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifndef CURL_DISABLE_HTTP conn->curl_do = Curl_http; conn->curl_done = Curl_http_done; + conn->protocol = PROT_HTTP; /* switch to HTTP */ #else failf(data, "FTP over http proxy requires HTTP support built-in!"); return CURLE_UNSUPPORTED_PROTOCOL; -- cgit v1.2.1 From a676c18502d5ec3128db11accf04d6de3f9be949 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 17 Aug 2005 08:55:43 +0000 Subject: - Jeff Pohlmeyer found out that if you ask libcurl to load a cookiefile (with CURLOPT_COOKIEFILE), add a cookie (with CURLOPT_COOKIELIST), tell it to write the result to a given cookie jar and then never actually call curl_easy_perform() - the given file(s) to read was never read but the output file was written and thus it caused a "funny" result. - While doing some tests for the bug above, I noticed that Firefox generates large numbers (for the expire time) in the cookies.txt file and libcurl didn't treat them properly. Now it does. --- lib/url.c | 90 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 41 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3698affd1..f245a1986 100644 --- a/lib/url.c +++ b/lib/url.c @@ -227,16 +227,24 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.headerbuff); #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(data->change.cookielist) /* clean up list if any */ - curl_slist_free_all(data->change.cookielist); - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); if(data->set.cookiejar) { + if(data->change.cookielist) + /* If there is a list of cookie files to read, do it first so that + we have all the told files read before we write the new jar */ + Curl_cookie_loadfiles(data); + /* we have a "destination" for all the cookies to get dumped to */ if(Curl_cookie_output(data->cookies, data->set.cookiejar)) infof(data, "WARNING: failed to save cookies in %s\n", data->set.cookiejar); } + else { + if(data->change.cookielist) + /* since nothing is written, we can just free the list of cookie file + names */ + curl_slist_free_all(data->change.cookielist); /* clean up list */ + } if( !data->share || (data->cookies != data->share->cookies) ) { Curl_cookie_cleanup(data->cookies); @@ -2951,44 +2959,44 @@ static CURLcode CreateConnection(struct SessionHandle *data, char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; if(2 == sscanf(proxyptr, - "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - proxyuser, proxypasswd)) { - CURLcode res = CURLE_OK; - - /* found user and password, rip them out. note that we are - unescaping them, as there is otherwise no way to have a - username or password with reserved characters like ':' in - them. */ - Curl_safefree(conn->proxyuser); - conn->proxyuser = curl_unescape(proxyuser,0); - - if(!conn->proxyuser) - res = CURLE_OUT_OF_MEMORY; - else { - Curl_safefree(conn->proxypasswd); - conn->proxypasswd = curl_unescape(proxypasswd,0); - - if(!conn->proxypasswd) - res = CURLE_OUT_OF_MEMORY; - } - - if(CURLE_OK == res) { - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - atsign = strdup(atsign+1); /* the right side of the @-letter */ - - if(atsign) { - free(proxydup); /* free the former proxy string */ - proxydup = proxyptr = atsign; /* now use this instead */ - } - else - res = CURLE_OUT_OF_MEMORY; - } - - if(res) { - free(proxydup); /* free the allocated proxy string */ - return res; - } + "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", + proxyuser, proxypasswd)) { + CURLcode res = CURLE_OK; + + /* found user and password, rip them out. note that we are + unescaping them, as there is otherwise no way to have a + username or password with reserved characters like ':' in + them. */ + Curl_safefree(conn->proxyuser); + conn->proxyuser = curl_unescape(proxyuser,0); + + if(!conn->proxyuser) + res = CURLE_OUT_OF_MEMORY; + else { + Curl_safefree(conn->proxypasswd); + conn->proxypasswd = curl_unescape(proxypasswd,0); + + if(!conn->proxypasswd) + res = CURLE_OUT_OF_MEMORY; + } + + if(CURLE_OK == res) { + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + atsign = strdup(atsign+1); /* the right side of the @-letter */ + + if(atsign) { + free(proxydup); /* free the former proxy string */ + proxydup = proxyptr = atsign; /* now use this instead */ + } + else + res = CURLE_OUT_OF_MEMORY; + } + + if(res) { + free(proxydup); /* free the allocated proxy string */ + return res; + } } } -- cgit v1.2.1 From a4773fcbbbf42a25c1037573fbab58aa275b9ed1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Aug 2005 10:57:28 +0000 Subject: Toby Peterson added CURLOPT_IGNORE_CONTENT_LENGTH to the library, accessible from the command line tool with --ignore-content-length. This will make it easier to download files from Apache 1.x (and similar) servers that are still having problems serving files larger than 2 or 4 GB. When this option is enabled, curl will simply have to wait for the server to close the connection to signal end of transfer. I wrote test case 269 that runs a simple test that this works. --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f245a1986..92d81caa4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1443,6 +1443,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ftp_account = va_arg(param, char *); break; + case CURLOPT_IGNORE_CONTENT_LENGTH: + data->set.ignorecl = va_arg(param, long)?TRUE:FALSE; + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 56d9624b566ac15ffb4b4b6eef220a5000b767e0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 2 Sep 2005 15:11:08 +0000 Subject: John Kelly added TFTP support to libcurl. A bunch of new error codes was added. TODO: add them to docs. add TFTP server to test suite. add TFTP to list of protocols whereever those are mentioned. --- lib/url.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 92d81caa4..06784fe34 100644 --- a/lib/url.c +++ b/lib/url.c @@ -77,9 +77,7 @@ #error "We can't compile without socket() support!" #endif - #endif - #ifdef USE_LIBIDN #include #include @@ -123,6 +121,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "ftp.h" #include "dict.h" #include "telnet.h" +#include "tftp.h" #include "http.h" #include "file.h" #include "ldap.h" @@ -2915,6 +2914,43 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else failf(data, LIBCURL_NAME " was built with FILE disabled!"); +#endif + } + else if (strequal(conn->protostr, "TFTP")) { +#ifndef CURL_DISABLE_TFTP + char *type; + conn->protocol |= PROT_TFTP; + conn->port = PORT_TFTP; + conn->remote_port = PORT_TFTP; + conn->curl_connect = Curl_tftp_connect; + conn->curl_do = Curl_tftp; + conn->curl_done = Curl_tftp_done; + /* TFTP URLs support an extension like ";mode=" that + * we'll try to get now! */ + type=strstr(conn->path, ";mode="); + if(!type) { + type=strstr(conn->host.rawalloc, ";mode="); + } + if(type) { + char command; + *type=0; /* it was in the middle of the hostname */ + command = toupper((int)type[6]); + switch(command) { + case 'A': /* ASCII mode */ + case 'N': /* NETASCII mode */ + data->set.ftp_ascii = 1; + break; + case 'O': /* octet mode */ + case 'I': /* binary mode */ + default: + /* switch off ASCII */ + data->set.ftp_ascii = 0; + break; + } + } +#else + failf(data, LIBCURL_NAME + " was built with TFTP disabled!"); #endif } else { -- cgit v1.2.1 From 7e845e7cfdd658caccc60f687d5d5d68d7e88937 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 4 Sep 2005 05:16:06 +0000 Subject: Added FTP_SKIP_PASV_IP and --ftp-skip-pasv-ip --- lib/url.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 06784fe34..c256cf23f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -965,6 +965,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_FTP_SKIP_PASV_IP: + /* + * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the + * bypass of the IP address in PASV responses. + */ + data->set.ftp_skip_ip = (bool)va_arg(param, long); + break; + case CURLOPT_INFILE: /* * FILE pointer to read the file to be uploaded from. Or possibly @@ -1240,7 +1248,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set a SSL_CTX callback */ - data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); + data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); break; case CURLOPT_SSL_CTX_DATA: /* -- cgit v1.2.1 From e7093b3ca8f54a9d67a078ce37afdc825c86fdf4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 16 Sep 2005 21:30:08 +0000 Subject: keep 'socktype' in the connectdata struct and make sure we use that for all protocol sockets even if the resolved address may say otherwise --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c256cf23f..f84ee3734 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2729,6 +2729,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Setup internals depending on protocol *************************************************************/ + conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ + if (strequal(conn->protostr, "HTTP")) { #ifndef CURL_DISABLE_HTTP conn->port = PORT_HTTP; @@ -2927,12 +2929,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, else if (strequal(conn->protostr, "TFTP")) { #ifndef CURL_DISABLE_TFTP char *type; + conn->socktype = SOCK_DGRAM; /* UDP datagram based */ conn->protocol |= PROT_TFTP; conn->port = PORT_TFTP; conn->remote_port = PORT_TFTP; conn->curl_connect = Curl_tftp_connect; conn->curl_do = Curl_tftp; - conn->curl_done = Curl_tftp_done; + conn->curl_done = Curl_tftp_done; /* TFTP URLs support an extension like ";mode=" that * we'll try to get now! */ type=strstr(conn->path, ";mode="); -- cgit v1.2.1 From e43217e6643b5ee9f20e37498240b819c88af687 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Sep 2005 11:37:52 +0000 Subject: Starting now, the verbose text that goes like "About to connect() to" will now contain the word "proxy" is the hostname is in fact a proxy. This will help users detect situations when they mistakenly use a proxy. --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f84ee3734..3f11b3e75 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2001,7 +2001,8 @@ static CURLcode ConnectPlease(struct connectdata *conn, struct SessionHandle *data = conn->data; char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; - infof(data, "About to connect() to %s port %d\n", + infof(data, "About to connect() to %s%s port %d\n", + data->change.proxy?"proxy ":"", hostname, conn->port); /************************************************************* -- cgit v1.2.1 From 1a1ab2e2e8abb6618721188109156e5bdda35cdd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 21 Oct 2005 21:00:44 +0000 Subject: "Ofer" reported a problem when libcurl re-used a connection and failed to do it, it could then accidentally actually crash. Presumably, this concerns FTP connections. http://curl.haxx.se/bug/view.cgi?id=1330310 --- lib/url.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f11b3e75..c4f3fbf3d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3844,7 +3844,14 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) /* conn may no longer be a good pointer */ - if(CURLE_OK == result) { + /* + * According to bug report #1330310. We need to check for + * CURLE_SEND_ERROR here as well. I figure this could happen when the + * request failed on a FTP connection and thus Curl_done() itself tried + * to use the connection (again). Slight Lack of feedback in the report, + * but I don't think this extra check can do much harm. + */ + if((CURLE_OK == result) || (CURLE_SEND_ERROR == result)) { bool async; bool protocol_done = TRUE; -- cgit v1.2.1 From 966fa848a0213be52d3a4b3787c36ec7c5553f22 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 27 Oct 2005 22:05:38 +0000 Subject: Nis Jorgensen filed bug report #1338648 (http://curl.haxx.se/bug/view.cgi?id=1338648) which really is more of a feature request, but anyway. It pointed out that --max-redirs did not allow it to be set to 0, which then would return an error code on the first Location: found. Based on Nis' patch, now libcurl supports CURLOPT_MAXREDIRS set to 0, or -1 for infinity. Added test case 274 to verify. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c4f3fbf3d..bff500f57 100644 --- a/lib/url.c +++ b/lib/url.c @@ -320,7 +320,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.infilesize = -1; /* we don't know any size */ data->set.postfieldsize = -1; - + data->set.maxredirs = -1; /* allow any amount by default */ data->state.current_speed = -1; /* init to negative == impossible */ data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ -- cgit v1.2.1 From 0fd282b078ace39aa03bc4be280129130b537d0c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 28 Nov 2005 23:06:00 +0000 Subject: new experimental "ftp method" code --- lib/url.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bff500f57..ff52e459f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -327,7 +327,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ data->set.ftp_use_lprt = TRUE; /* FTP defaults to EPRT operations */ - + data->set.ftp_filemethod = FTPFILE_MULTICWD; data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ /* make libcurl quiet by default: */ @@ -557,6 +557,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.ftp_append = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_FTP_FILEMETHOD: + /* + * How do access files over FTP. + */ + data->set.ftp_filemethod = va_arg(param, long); + break; case CURLOPT_NETRC: /* * Parse the $HOME/.netrc file -- cgit v1.2.1 From 176d4e85e9566ab00c7aa5da323d4392f49c83c7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 Nov 2005 13:09:48 +0000 Subject: cast the va_arg() assignment to ftp_filemethod properly --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ff52e459f..bc6033a36 100644 --- a/lib/url.c +++ b/lib/url.c @@ -561,7 +561,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * How do access files over FTP. */ - data->set.ftp_filemethod = va_arg(param, long); + data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long); break; case CURLOPT_NETRC: /* -- cgit v1.2.1 From f49df54a36a39995be32782154f3ca2692f17ac4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 6 Dec 2005 23:05:51 +0000 Subject: 7.15.1 with the now to be announced security flaw fixed --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bc6033a36..3715b10ca 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2378,12 +2378,18 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(urllen < LEAST_PATH_ALLOC) urllen=LEAST_PATH_ALLOC; - conn->pathbuffer=(char *)malloc(urllen); + /* + * We malloc() the buffers below urllen+2 to make room for to possibilities: + * 1 - an extra terminating zero + * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) + */ + + conn->pathbuffer=(char *)malloc(urllen+2); if(NULL == conn->pathbuffer) return CURLE_OUT_OF_MEMORY; /* really bad error */ conn->path = conn->pathbuffer; - conn->host.rawalloc=(char *)malloc(urllen); + conn->host.rawalloc=(char *)malloc(urllen+2); if(NULL == conn->host.rawalloc) return CURLE_OUT_OF_MEMORY; conn->host.name = conn->host.rawalloc; -- cgit v1.2.1 From 6dbfce1031a8dd177772e2ee356c712b2454f794 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 16 Dec 2005 14:52:16 +0000 Subject: Jean Jacques Drouin pointed out that you could only have a user name or password of 127 bytes or less embedded in a URL, where actually the code uses a 255 byte buffer for it! Modified now to use the full buffer size. --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3715b10ca..781d1d11d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3166,12 +3166,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(*userpass != ':') { /* the name is given, get user+password */ - sscanf(userpass, "%127[^:@]:%127[^@]", + sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", user, passwd); } else /* no name given, get the password only */ - sscanf(userpass, ":%127[^@]", passwd); + sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); if(user[0]) { char *newname=curl_unescape(user, 0); -- cgit v1.2.1 From 7d1e3ebeed8ec2e3b70e2d7e11015e50e3ec291c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Dec 2005 22:46:12 +0000 Subject: explain tld_check_name() --- lib/url.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 781d1d11d..e012e01af 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2174,7 +2174,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done) * Helpers for IDNA convertions. */ #ifdef USE_LIBIDN -static bool is_ASCII_name (const char *hostname) +static bool is_ASCII_name(const char *hostname) { const unsigned char *ch = (const unsigned char*)hostname; @@ -2188,8 +2188,8 @@ static bool is_ASCII_name (const char *hostname) /* * Check if characters in hostname is allowed in Top Level Domain. */ -static bool tld_check_name (struct SessionHandle *data, - const char *ace_hostname) +static bool tld_check_name(struct SessionHandle *data, + const char *ace_hostname) { size_t err_pos; char *uc_name = NULL; @@ -2245,7 +2245,9 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) infof(data, "Failed to convert %s to ACE; %s\n", host->name, Curl_idn_strerror(conn,rc)); else { - tld_check_name(data, ace_hostname); + /* tld_check_name() displays a warning if the host name contains + "illegal" characters for this TLD */ + (void)tld_check_name(data, ace_hostname); host->encalloc = ace_hostname; /* change the name pointer to point to the encoded hostname */ -- cgit v1.2.1 From 67a83c1b3465c44b249eaa44fdc492952e59b31f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 16 Jan 2006 22:14:37 +0000 Subject: David Shaw finally removed all traces of Gopher and we are now officially not supporting it. It hasn't been functioning for years anyway, so this is just finally stating what already was true. And a cleanup at the same time. --- lib/url.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e012e01af..b8927fbcd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2485,14 +2485,12 @@ 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->host.name)) - strcpy(conn->protostr, "gopher"); + if(checkprefix("FTP.", conn->host.name)) + strcpy(conn->protostr, "ftp"); #ifdef USE_SSL else if(checkprefix("FTPS", conn->host.name)) strcpy(conn->protostr, "ftps"); #endif /* USE_SSL */ - else if(checkprefix("FTP.", conn->host.name)) - strcpy(conn->protostr, "ftp"); else if(checkprefix("TELNET.", conn->host.name)) strcpy(conn->protostr, "telnet"); else if (checkprefix("DICT.", conn->host.name)) @@ -2596,7 +2594,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, * http_proxy=http://some.server.dom:port/ * https_proxy=http://some.server.dom:port/ * ftp_proxy=http://some.server.dom:port/ - * gopher_proxy=http://some.server.dom:port/ * no_proxy=domain1.dom,host.domain2.dom * (a comma-separated list of hosts which should * not be proxied, or an asterisk to override @@ -2778,25 +2775,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, " was built with SSL disabled, https: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; #endif /* !USE_SSL */ - } - else if (strequal(conn->protostr, "GOPHER")) { -#ifndef CURL_DISABLE_GOPHER - conn->port = PORT_GOPHER; - conn->remote_port = PORT_GOPHER; - /* Skip // in path if present */ - if (isdigit((int)conn->path[1])) { - 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; - conn->curl_done = Curl_http_done; -#else - failf(data, LIBCURL_NAME - " was built with GOPHER disabled, gopher: not supported!"); -#endif } else if(strequal(conn->protostr, "FTP") || strequal(conn->protostr, "FTPS")) { -- cgit v1.2.1 From fcfd6d950408d41f0ff7e664205f76146f180da8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 19 Jan 2006 23:52:03 +0000 Subject: Duane Cathey was one of our friends who reported that curl -P [IP] (CURLOPT_FTPPORT) didn't work for ipv6-enabed curls if the IP wasn't a "native" IP while it works fine for ipv6-disabled builds! In the process of fixing this, I removed the support for LPRT since I can't think of many reasons to keep doing it and asking on the mailing list didn't reveal anyone else that could either. The code that sends EPRT and PORT is now also a lot simpler than before (IMHO). --- lib/url.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b8927fbcd..a4bd0f509 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -326,7 +326,6 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ - data->set.ftp_use_lprt = TRUE; /* FTP defaults to EPRT operations */ data->set.ftp_filemethod = FTPFILE_MULTICWD; data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ @@ -964,7 +963,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_FTP_USE_EPRT: data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE; - data->set.ftp_use_lprt = data->set.ftp_use_eprt; break; case CURLOPT_FTP_USE_EPSV: @@ -2365,7 +2363,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; - conn->bits.ftp_use_lprt = data->set.ftp_use_lprt; /* This initing continues below, see the comment "Continue connectdata * initialization here" */ -- cgit v1.2.1 From 2fbf94b0f309de9bd9153274bb475abc744afb0a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 30 Jan 2006 08:24:07 +0000 Subject: Added CURLOPT_LOCALPORT and CURLOPT_LOCALPORTRANGE to libcurl. Set with the curl tool with --local-port. Plain and simply set the range of ports to bind the local end of connections to. Implemented on to popular demand. Not extensively tested. Please let me know how it works. --- lib/url.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a4bd0f509..f17213f79 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1222,13 +1222,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ 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. + * Set what interface or address/hostname to bind the socket to when + * performing an operation and thus what from-IP your connection will use. */ data->set.device = va_arg(param, char *); break; + case CURLOPT_LOCALPORT: + /* + * Set what local port to bind the socket to when performing an operation. + */ + data->set.localport = (unsigned short) va_arg(param, long); + break; + case CURLOPT_LOCALPORTRANGE: + /* + * Set number of local ports to try, starting with CURLOPT_LOCALPORT. + */ + data->set.localportrange = (int) va_arg(param, long); + break; case CURLOPT_KRB4LEVEL: /* * A string that defines the krb4 security level. -- cgit v1.2.1 From 87bcb6f3775a437579c7526d0972c714c2e5d31d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 11 Feb 2006 22:35:16 +0000 Subject: Karl M added the CURLOPT_CONNECT_ONLY and CURLINFO_LASTSOCKET options that an app can use to let libcurl only connect to a remote host and then extract the socket from libcurl. libcurl will then not attempt to do any transfer at all after the connect is done. --- lib/url.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f17213f79..49e7c1cbf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -352,6 +352,9 @@ CURLcode Curl_open(struct SessionHandle **curl) memset(data->state.connects, 0, sizeof(struct connectdata *)*data->state.numconnects); + /* most recent connection is not yet defined */ + data->state.lastconnect = -1; + /* * libcurl 7.10 introduced SSL verification *by default*! This needs to be * switched off unless wanted. @@ -432,6 +435,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, are being removed! */ for(i=newconnects; i< data->state.numconnects; i++) Curl_disconnect(data->state.connects[i]); + + /* If the most recent connection is no longer valid, mark it invalid. */ + if(data->state.lastconnect <= newconnects) + data->state.lastconnect = -1; } if(newconnects) { newptr= (struct connectdata **) @@ -453,8 +460,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* zero makes NO cache at all */ if(data->state.connects) free(data->state.connects); - data->state.connects=NULL; - data->state.numconnects=0; + data->state.connects = NULL; + data->state.numconnects = 0; + data->state.lastconnect = -1; } } break; @@ -1471,6 +1479,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ignorecl = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_CONNECT_ONLY: + /* + * No data transfer, set up connection and let application use the socket + */ + data->set.connect_only = va_arg(param, long)?TRUE:FALSE; + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -3811,10 +3826,14 @@ CURLcode Curl_done(struct connectdata **connp, if(!result && res2) result = res2; } - else + else { + /* remember the most recently used connection */ + data->state.lastconnect = conn->connectindex; + infof(data, "Connection #%ld to host %s left intact\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); + } return result; } -- cgit v1.2.1 From ad6511c313a06a62421e1b426974cf8b5e85f466 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Feb 2006 10:02:11 +0000 Subject: Added some clarifying comments --- lib/url.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 49e7c1cbf..fe0dc3c25 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2296,7 +2296,8 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) * * @param data The sessionhandle pointer * @param in_connect is set to the next connection data pointer - * @param addr is set to the new dns entry for this connection + * @param addr is set to the new dns entry for this connection. If this + * connection is re-used it will be NULL. * @param async is set TRUE/FALSE depending on the nature of this lookup * @return CURLcode * @see SetupConnection() @@ -3630,8 +3631,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, return result; } -/* SetupConnection() should be called after the name resolve initiated in +/* SetupConnection() is called after the name resolve initiated in * CreateConnection() is all done. + * + * NOTE: the argument 'hostaddr' is NULL when this function is called for a + * re-used connection. */ static CURLcode SetupConnection(struct connectdata *conn, @@ -3730,8 +3734,8 @@ CURLcode Curl_connect(struct SessionHandle *data, /* no error */ if(dns || !*asyncp) /* If an address is available it means that we already have the name - resolved, OR it isn't async. - If so => continue connecting from here */ + resolved, OR it isn't async. if this is a re-used connection 'dns' + will be NULL here. Continue connecting from here */ code = SetupConnection(*in_connect, dns, protocol_done); /* else response will be received and treated async wise */ -- cgit v1.2.1 From a15d107dde68f6173cfb1a590320cb108d4dd0f5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Feb 2006 07:46:41 +0000 Subject: Peter Su added support for SOCKS4 proxies. Enable this by setting the proxy type to the already provided type CURLPROXY_SOCKS4. I added a --socks4 option that works like the current --socks5 option but instead use the socks4 protocol. --- lib/url.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 192 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fe0dc3c25..c7aad213a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1809,6 +1809,191 @@ ConnectionStore(struct SessionHandle *data, return i; } +/* +* This function logs in to a SOCKS4 proxy and sends the specifies the final +* desitination server. +* +* Reference : +* http://socks.permeo.com/protocol/socks4.protocol +* +* Note : +* Nonsupport "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" +* Nonsupport "Identification Protocol (RFC1413)" +*/ +static int handleSock4Proxy(struct connectdata *conn) +{ + unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ + int result; + CURLcode code; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct SessionHandle *data = conn->data; + + Curl_nonblock(sock, FALSE); + + /* + * Compose socks4 request + * + * Request format + * + * +----+----+----+----+----+----+----+----+----+----+....+----+ + * | VN | CD | DSTPORT | DSTIP | USERID |NULL| + * +----+----+----+----+----+----+----+----+----+----+....+----+ + * # of bytes: 1 1 2 4 variable 1 + */ + + socksreq[0] = 4; /* version (SOCKS4) */ + socksreq[1] = 1; /* connect */ + *((unsigned short*)&socksreq[2]) = htons(conn->remote_port); + + /* DNS resolve */ + { + struct Curl_dns_entry *dns; + Curl_addrinfo *hp=NULL; + int rc; + + rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns); + + if(rc == CURLRESOLV_ERROR) + return 1; + + if(rc == CURLRESOLV_PENDING) + /* this requires that we're in "wait for resolve" state */ + rc = Curl_wait_for_resolv(conn, &dns); + + /* + * We cannot use 'hostent' as a struct that Curl_resolv() returns. It + * returns a Curl_addrinfo pointer that may not always look the same. + */ + if(dns) + hp=dns->addr; + if (hp) { + char buf[64]; + unsigned short ip[4]; + Curl_printable_address(hp, buf, sizeof(buf)); + + if(4 == sscanf( buf, "%hu.%hu.%hu.%hu", + &ip[0], &ip[1], &ip[2], &ip[3])) { + /* Set DSTIP */ + socksreq[4] = (unsigned char)ip[0]; + socksreq[5] = (unsigned char)ip[1]; + socksreq[6] = (unsigned char)ip[2]; + socksreq[7] = (unsigned char)ip[3]; + } + else + hp = NULL; /* fail! */ + + Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ + + } + if(!hp) { + failf(conn->data, "Failed to resolve \"%s\" for SOCKS4 connect.\n", + conn->host.name); + return 1; + } + } + + /* + * Make connection + */ + { + ssize_t actualread; + ssize_t written; + int packetsize = 9; /* request data size (include NULL) */ + + /* Send request */ + code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); + if ((code != CURLE_OK) || (written != packetsize)) { + failf(conn->data, "Failed to send SOCKS4 connect request.\n"); + return 1; + } + + packetsize = 8; /* receive data size */ + + /* Receive response */ + result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); + if ((result != CURLE_OK) || (actualread != packetsize)) { + failf(conn->data, "Failed to receive SOCKS4 connect request ack.\n"); + return 1; + } + + /* + * Response format + * + * +----+----+----+----+----+----+----+----+ + * | VN | CD | DSTPORT | DSTIP | + * +----+----+----+----+----+----+----+----+ + * # of bytes: 1 1 2 4 + * + * VN is the version of the reply code and should be 0. CD is the result + * code with one of the following values: + * + * 90: request granted + * 91: request rejected or failed + * 92: request rejected becasue SOCKS server cannot connect to + * identd on the client + * 93: request rejected because the client program and identd + * report different user-ids + */ + + /* wrong version ? */ + if (socksreq[0] != 0) { + failf(conn->data, + "SOCKS4 reply has wrong version, version should be 4.\n"); + return 1; + } + + /* Result */ + switch(socksreq[1]) + { + case 90: + infof(data, "SOCKS4 request granted.\n"); + break; + case 91: + failf(conn->data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", request rejected or failed.\n", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), + socksreq[1]); + return 1; + case 92: + failf(conn->data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", request rejected becasue SOCKS server cannot connect to " + "identd on the client.\n", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), + socksreq[1]); + return 1; + case 93: + failf(conn->data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", request rejected because the client program and identd " + "report different user-ids.\n", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), + socksreq[1]); + return 1; + default : + failf(conn->data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", Unknown.\n", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), + socksreq[1]); + return 1; + } + } + + Curl_nonblock(sock, TRUE); + + return 0; /* Proxy was successful! */ +} + /* * This function logs in to a SOCKS5 proxy and sends the specifies the final * desitination server. @@ -2052,16 +2237,18 @@ static CURLcode ConnectPlease(struct connectdata *conn, Curl_store_ip_addr(conn); - if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { + switch(conn->data->set.proxytype) { + case CURLPROXY_SOCKS5: return handleSock5Proxy(conn->proxyuser, conn->proxypasswd, conn) ? CURLE_COULDNT_CONNECT : CURLE_OK; - } - else if (conn->data->set.proxytype == CURLPROXY_HTTP) { + case CURLPROXY_HTTP: /* do nothing here. handled later. */ - } - else { + break; + case CURLPROXY_SOCKS4: + return handleSock4Proxy(conn) ? CURLE_COULDNT_CONNECT : CURLE_OK; + default: failf(conn->data, "unknown proxytype option given"); return CURLE_COULDNT_CONNECT; } -- cgit v1.2.1 From 75c943055962180f178f3b37bcee855fdaf640c0 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 22 Feb 2006 19:09:33 +0000 Subject: Fixed some spelling errors in comments, and extraneous \n in failf logs. --- lib/url.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c7aad213a..0c0933ca8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -362,7 +362,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.verifypeer = TRUE; data->set.ssl.verifyhost = 2; #ifdef CURL_CA_BUNDLE - /* This is our prefered CA cert bundle since install time */ + /* This is our preferred CA cert bundle since install time */ data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; #endif } @@ -1810,8 +1810,8 @@ ConnectionStore(struct SessionHandle *data, } /* -* This function logs in to a SOCKS4 proxy and sends the specifies the final -* desitination server. +* This function logs in to a SOCKS4 proxy and sends the specifics to the final +* destination server. * * Reference : * http://socks.permeo.com/protocol/socks4.protocol @@ -1886,7 +1886,7 @@ static int handleSock4Proxy(struct connectdata *conn) } if(!hp) { - failf(conn->data, "Failed to resolve \"%s\" for SOCKS4 connect.\n", + failf(conn->data, "Failed to resolve \"%s\" for SOCKS4 connect.", conn->host.name); return 1; } @@ -1903,7 +1903,7 @@ static int handleSock4Proxy(struct connectdata *conn) /* Send request */ code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); if ((code != CURLE_OK) || (written != packetsize)) { - failf(conn->data, "Failed to send SOCKS4 connect request.\n"); + failf(conn->data, "Failed to send SOCKS4 connect request."); return 1; } @@ -1912,7 +1912,7 @@ static int handleSock4Proxy(struct connectdata *conn) /* Receive response */ result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); if ((result != CURLE_OK) || (actualread != packetsize)) { - failf(conn->data, "Failed to receive SOCKS4 connect request ack.\n"); + failf(conn->data, "Failed to receive SOCKS4 connect request ack."); return 1; } @@ -1929,7 +1929,7 @@ static int handleSock4Proxy(struct connectdata *conn) * * 90: request granted * 91: request rejected or failed - * 92: request rejected becasue SOCKS server cannot connect to + * 92: request rejected because SOCKS server cannot connect to * identd on the client * 93: request rejected because the client program and identd * report different user-ids @@ -1938,7 +1938,7 @@ static int handleSock4Proxy(struct connectdata *conn) /* wrong version ? */ if (socksreq[0] != 0) { failf(conn->data, - "SOCKS4 reply has wrong version, version should be 4.\n"); + "SOCKS4 reply has wrong version, version should be 4."); return 1; } @@ -1951,7 +1951,7 @@ static int handleSock4Proxy(struct connectdata *conn) case 91: failf(conn->data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected or failed.\n", + ", request rejected or failed.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), @@ -1960,8 +1960,8 @@ static int handleSock4Proxy(struct connectdata *conn) case 92: failf(conn->data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected becasue SOCKS server cannot connect to " - "identd on the client.\n", + ", request rejected because SOCKS server cannot connect to " + "identd on the client.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), @@ -1971,7 +1971,7 @@ static int handleSock4Proxy(struct connectdata *conn) failf(conn->data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", request rejected because the client program and identd " - "report different user-ids.\n", + "report different user-ids.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), @@ -1980,7 +1980,7 @@ static int handleSock4Proxy(struct connectdata *conn) default : failf(conn->data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", Unknown.\n", + ", Unknown.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), @@ -1995,8 +1995,8 @@ static int handleSock4Proxy(struct connectdata *conn) } /* - * This function logs in to a SOCKS5 proxy and sends the specifies the final - * desitination server. + * This function logs in to a SOCKS5 proxy and sends the specifics to the final + * destination server. */ static int handleSock5Proxy(const char *proxy_name, const char *proxy_password, @@ -2558,7 +2558,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, (data->set.proxytype == CURLPROXY_HTTP))? TRUE:FALSE; /* http proxy or not */ - /* Default protocol-independent behavior doesn't support persistant + /* Default protocol-independent behavior doesn't support persistent connections, so we set this to force-close. Protocols that support this need to set this to FALSE in their "curl_do" functions. */ conn->bits.close = TRUE; @@ -2571,7 +2571,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, 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 */ + conn->resume_from = data->set.set_resume_from; /* inherit resume_from */ conn->bits.user_passwd = data->set.userpwd?1:0; conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; @@ -3470,7 +3470,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * so scribble it over the top. * User-supplied passwords are assumed not to need unescaping. * - * user_password is set in "inherite initial knowledge' above, + * user_password is set in "inherit initial knowledge' above, * so it doesn't have to be set in this block */ if (data->set.userpwd != NULL) { @@ -3654,7 +3654,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Continue connectdata initialization here. * * Inherit the proper values from the urldata struct AFTER we have arranged - * the persistant conncetion stuff */ + * the persistent conncetion stuff */ conn->fread = data->set.fread; conn->fread_in = data->set.in; -- cgit v1.2.1 From 6fdbb011948cc9fd2cadff04b230427cf02dbd7d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 23 Feb 2006 12:20:48 +0000 Subject: Lots of work and analysis by "xbx___" in bug #1431750 (http://curl.haxx.se/bug/view.cgi?id=1431750) helped me identify and fix two different but related bugs: 1) Removing an easy handle from a multi handle before the transfer is done could leave a connection in the connection cache for that handle that is in a state that isn't suitable for re-use. A subsequent re-use could then read from a NULL pointer and segfault. 2) When an easy handle was removed from the multi handle, there could be an outstanding c-ares DNS name resolve request. When the response arrived, it caused havoc since the connection struct it "belonged" to could've been freed already. Now Curl_done() is called when an easy handle is removed from a multi handle pre-maturely (that is, before the transfer was complteted). Curl_done() also makes sure to cancel all (if any) outstanding c-ares requests. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0c0933ca8..60172b395 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3654,7 +3654,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Continue connectdata initialization here. * * Inherit the proper values from the urldata struct AFTER we have arranged - * the persistent conncetion stuff */ + * the persistent connection stuff */ conn->fread = data->set.fread; conn->fread_in = data->set.in; @@ -3999,6 +3999,10 @@ CURLcode Curl_done(struct connectdata **connp, Curl_pgrsDone(conn); /* done with the operation */ + /* for ares-using, make sure all possible outstanding requests are properly + cancelled before we proceed */ + ares_cancel(data->state.areschannel); + /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this no matter what we think. -- cgit v1.2.1 From 0e6a1a44203fab41348c045bc746854273956d4b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 23 Feb 2006 14:42:47 +0000 Subject: Peter Su's SOCKS4 fix --- lib/url.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 60172b395..53a53e9a2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1822,7 +1822,7 @@ ConnectionStore(struct SessionHandle *data, */ static int handleSock4Proxy(struct connectdata *conn) { - unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ + unsigned char socksreq[9]; /* room for SOCKS4 request */ int result; CURLcode code; curl_socket_t sock = conn->sock[FIRSTSOCKET]; @@ -1893,8 +1893,13 @@ static int handleSock4Proxy(struct connectdata *conn) } /* - * Make connection - */ + * This is currently not supporting "Identification Protocol (RFC1413)". + */ + socksreq[8] = 0; /* NUL ending the nonexistent userid */ + + /* + * Make connection + */ { ssize_t actualread; ssize_t written; -- cgit v1.2.1 From 45e4b811b00e3f33d92bb1db8be6168c2d8a7ba2 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 23 Feb 2006 18:39:22 +0000 Subject: Fixed a few more comment typos. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 53a53e9a2..14345edb7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1226,7 +1226,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_CRLF: /* - * Kludgy option to enable CRLF convertions. Subject for removal. + * Kludgy option to enable CRLF conversions. Subject for removal. */ data->set.crlf = va_arg(param, long)?TRUE:FALSE; break; @@ -2656,7 +2656,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, host (or port) and the url-path is NOT part of the url-path. As most agents use file://localhost/foo to get '/foo' although the - slash preceeding foo is a separator and not a slash for the path, + slash preceding foo is a separator and not a slash for the path, a URL as file://localhost//foo must be valid as well, to refer to the same file with an absolute path. */ -- cgit v1.2.1 From a39ac3d94ad836785074287a5dd30757fddfc049 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 24 Feb 2006 21:35:48 +0000 Subject: Added user ID support to SOCKS4. --- lib/url.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 14345edb7..4eeb1dc9a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1820,9 +1820,9 @@ ConnectionStore(struct SessionHandle *data, * Nonsupport "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" * Nonsupport "Identification Protocol (RFC1413)" */ -static int handleSock4Proxy(struct connectdata *conn) +static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) { - unsigned char socksreq[9]; /* room for SOCKS4 request */ + unsigned char socksreq[262]; /* room for SOCKS4 request incl. user id */ int result; CURLcode code; curl_socket_t sock = conn->sock[FIRSTSOCKET]; @@ -1895,7 +1895,9 @@ static int handleSock4Proxy(struct connectdata *conn) /* * This is currently not supporting "Identification Protocol (RFC1413)". */ - socksreq[8] = 0; /* NUL ending the nonexistent userid */ + socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ + if (proxy_name) + strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8); /* * Make connection @@ -1903,7 +1905,7 @@ static int handleSock4Proxy(struct connectdata *conn) { ssize_t actualread; ssize_t written; - int packetsize = 9; /* request data size (include NULL) */ + int packetsize = 9 + strlen((char*)socksreq + 8); /* size including NUL */ /* Send request */ code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); @@ -2252,7 +2254,8 @@ static CURLcode ConnectPlease(struct connectdata *conn, /* do nothing here. handled later. */ break; case CURLPROXY_SOCKS4: - return handleSock4Proxy(conn) ? CURLE_COULDNT_CONNECT : CURLE_OK; + return handleSock4Proxy(conn->proxyuser, conn) ? + CURLE_COULDNT_CONNECT : CURLE_OK; default: failf(conn->data, "unknown proxytype option given"); return CURLE_COULDNT_CONNECT; -- cgit v1.2.1 From cffebd7fd6b7d9f24793f94fbae2a62c05c46eb0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 7 Mar 2006 23:11:41 +0000 Subject: Markus Koetter filed debian bug report #355715 which identified a problem with the multi interface and multi-part formposts. The fix from February 22nd could make the Curl_done() function get called twice on the same connection and it was not designed for that and thus tried to call free() on an already freed memory area! --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4eeb1dc9a..9a715c9f0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3982,6 +3982,11 @@ CURLcode Curl_done(struct connectdata **connp, struct connectdata *conn = *connp; struct SessionHandle *data=conn->data; + if(conn->bits.done) + return CURLE_OK; /* Curl_done() has already been called */ + + conn->bits.done = TRUE; /* called just now! */ + /* cleanups done even if the connection is re-used */ if(conn->bits.rangestringalloc) { free(conn->range); @@ -4047,6 +4052,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) struct connectdata *conn = *connp; struct SessionHandle *data=conn->data; + conn->bits.done = FALSE; /* Curl_done() is not called yet */ conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ if(conn->curl_do) { -- cgit v1.2.1 From 83367f67de9584b91570bcb53a153b8aa496d455 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Mar 2006 21:54:44 +0000 Subject: Xavier Bouchoux made the SSL connection non-blocking for the multi interface (when using OpenSSL). --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9a715c9f0..38a2a27da 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2990,6 +2990,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_do_more = NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; + conn->curl_connecting = Curl_https_connecting; + conn->curl_proto_fdset = Curl_https_proto_fdset; #else /* USE_SS */ failf(data, LIBCURL_NAME -- cgit v1.2.1 From 4d33cf739da2649d3a8c363572cdb386b0f743b9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 Apr 2006 11:47:21 +0000 Subject: added typedefed function pointers and typecast the NULL assignments in an attempt to silence picky compilers when assigning data pointers to a function pointer variable --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 38a2a27da..3b5eb97b3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2970,7 +2970,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; - conn->curl_do_more = NULL; + conn->curl_do_more = (Curl_do_more_func)NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; #else @@ -2987,7 +2987,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; conn->curl_do = Curl_http; - conn->curl_do_more = NULL; + conn->curl_do_more = (Curl_do_more_func)NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; conn->curl_connecting = Curl_https_connecting; @@ -3100,7 +3100,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = PORT_DICT; conn->remote_port = PORT_DICT; conn->curl_do = Curl_dict; - conn->curl_done = NULL; /* no DICT-specific done */ + conn->curl_done = (Curl_done_func)NULL; /* no DICT-specific done */ #else failf(data, LIBCURL_NAME " was built with DICT disabled!"); @@ -3112,7 +3112,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = PORT_LDAP; conn->remote_port = PORT_LDAP; conn->curl_do = Curl_ldap; - conn->curl_done = NULL; /* no LDAP-specific done */ + conn->curl_done = (Curl_done_func)NULL; /* no LDAP-specific done */ #else failf(data, LIBCURL_NAME " was built with LDAP disabled!"); -- cgit v1.2.1 From 5a4b43848ac21b3d831f00ce11136e20f820f0a0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 Apr 2006 21:50:47 +0000 Subject: First commit of David McCreedy's EBCDIC and TPF changes. --- lib/url.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3b5eb97b3..a21ef5ba6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -265,6 +265,19 @@ CURLcode Curl_close(struct SessionHandle *data) ares_destroy(data->state.areschannel); #endif +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + /* close iconv conversion descriptors */ + if (data->inbound_cd != (iconv_t)-1) { + iconv_close(data->inbound_cd); + } + if (data->outbound_cd != (iconv_t)-1) { + iconv_close(data->outbound_cd); + } + if (data->utf8_cd != (iconv_t)-1) { + iconv_close(data->utf8_cd); + } +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + /* No longer a dirty share, if it exists */ if (data->share) data->share->dirty--; @@ -318,6 +331,18 @@ CURLcode Curl_open(struct SessionHandle **curl) /* use fread as default function to read input */ data->set.fread = (curl_read_callback)fread; + /* conversion callbacks for non-ASCII hosts */ + data->set.convfromnetwork = (curl_conv_callback)NULL; + data->set.convtonetwork = (curl_conv_callback)NULL; + data->set.convfromutf8 = (curl_conv_callback)NULL; + +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + /* conversion descriptors for iconv calls */ + data->outbound_cd = (iconv_t)-1; + data->inbound_cd = (iconv_t)-1; + data->utf8_cd = (iconv_t)-1; +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + data->set.infilesize = -1; /* we don't know any size */ data->set.postfieldsize = -1; data->set.maxredirs = -1; /* allow any amount by default */ @@ -1167,6 +1192,24 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* When set to NULL, reset to our internal default function */ data->set.fread = (curl_read_callback)fread; break; + case CURLOPT_CONV_FROM_NETWORK_FUNCTION: + /* + * "Convert from network encoding" callback + */ + data->set.convfromnetwork = va_arg(param, curl_conv_callback); + break; + case CURLOPT_CONV_TO_NETWORK_FUNCTION: + /* + * "Convert to network encoding" callback + */ + data->set.convtonetwork = va_arg(param, curl_conv_callback); + break; + case CURLOPT_CONV_FROM_UTF8_FUNCTION: + /* + * "Convert from UTF-8 encoding" callback + */ + data->set.convfromutf8 = va_arg(param, curl_conv_callback); + break; case CURLOPT_IOCTLFUNCTION: /* * I/O control callback. Might be NULL. @@ -2795,11 +2838,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", proxyuser, proxypasswd); - conn->proxyuser = curl_unescape(proxyuser,0); + conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); if(!conn->proxyuser) return CURLE_OUT_OF_MEMORY; - conn->proxypasswd = curl_unescape(proxypasswd,0); + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); if(!conn->proxypasswd) return CURLE_OUT_OF_MEMORY; } @@ -3236,13 +3279,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, username or password with reserved characters like ':' in them. */ Curl_safefree(conn->proxyuser); - conn->proxyuser = curl_unescape(proxyuser,0); + conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); if(!conn->proxyuser) res = CURLE_OUT_OF_MEMORY; else { Curl_safefree(conn->proxypasswd); - conn->proxypasswd = curl_unescape(proxypasswd,0); + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); if(!conn->proxypasswd) res = CURLE_OUT_OF_MEMORY; @@ -3378,7 +3421,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); if(user[0]) { - char *newname=curl_unescape(user, 0); + char *newname=curl_easy_unescape(data, user, 0, NULL); if(!newname) return CURLE_OUT_OF_MEMORY; if(strlen(newname) < sizeof(user)) @@ -3390,7 +3433,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if (passwd[0]) { /* we have a password found in the URL, decode it! */ - char *newpasswd=curl_unescape(passwd, 0); + char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); if(!newpasswd) return CURLE_OUT_OF_MEMORY; if(strlen(newpasswd) < sizeof(passwd)) -- cgit v1.2.1 From 686d90745be4417127050ad4b36d0a5403def200 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 Apr 2006 15:00:53 +0000 Subject: First curl_multi_socket() commit. Should primarily be considered as an internal code rearrange to fit the future better. --- lib/url.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a21ef5ba6..690b3f302 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1552,6 +1552,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) NULL, Curl_scan_cache_used); #endif + Curl_expire(data, 0); /* shut off timers */ Curl_hostcache_prune(data); /* kill old DNS cache entries */ /* @@ -2318,26 +2319,22 @@ static void verboseconnect(struct connectdata *conn) conn->ip_addr_str, conn->port); } -CURLcode Curl_protocol_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - int *max_fdp) +int Curl_protocol_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) { - CURLcode res = CURLE_OK; - if(conn->curl_proto_fdset) - res = conn->curl_proto_fdset(conn, read_fd_set, write_fd_set, max_fdp); - return res; + if(conn->curl_proto_getsock) + return conn->curl_proto_getsock(conn, socks, numsocks); + return GETSOCK_BLANK; } -CURLcode Curl_doing_fdset(struct connectdata *conn, - fd_set *read_fd_set, - fd_set *write_fd_set, - int *max_fdp) +int Curl_doing_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) { - CURLcode res = CURLE_OK; - if(conn && conn->curl_doing_fdset) - res = conn->curl_doing_fdset(conn, read_fd_set, write_fd_set, max_fdp); - return res; + if(conn && conn->curl_doing_getsock) + return conn->curl_doing_getsock(conn, socks, numsocks); + return GETSOCK_BLANK; } /* @@ -3034,7 +3031,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; conn->curl_connecting = Curl_https_connecting; - conn->curl_proto_fdset = Curl_https_proto_fdset; + conn->curl_proto_getsock = Curl_https_getsock; #else /* USE_SS */ failf(data, LIBCURL_NAME @@ -3086,8 +3083,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_ftp_connect; conn->curl_connecting = Curl_ftp_multi_statemach; conn->curl_doing = Curl_ftp_doing; - conn->curl_proto_fdset = Curl_ftp_fdset; - conn->curl_doing_fdset = Curl_ftp_fdset; + conn->curl_proto_getsock = Curl_ftp_getsock; + conn->curl_doing_getsock = Curl_ftp_getsock; conn->curl_disconnect = Curl_ftp_disconnect; } @@ -4027,6 +4024,8 @@ CURLcode Curl_done(struct connectdata **connp, struct connectdata *conn = *connp; struct SessionHandle *data=conn->data; + Curl_expire(data, 0); /* stop timer */ + if(conn->bits.done) return CURLE_OK; /* Curl_done() has already been called */ -- cgit v1.2.1 From 606562aa7ea28ee0fdd5bf2cd6febada9594ad19 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 May 2006 22:46:38 +0000 Subject: Michael Wallner provided a patch that allows "SESS" to be set with CURLOPT_COOKIELIST, which then makes all session cookies get cleared. (slightly edited by me, and the re-indent in cookie.c was also done by me) --- lib/url.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 690b3f302..e9fa81168 100644 --- a/lib/url.c +++ b/lib/url.c @@ -829,12 +829,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; if(strequal(argptr, "ALL")) { - if(data->cookies) { - /* clear all cookies */ - Curl_cookie_freelist(data->cookies->cookies); - data->cookies->cookies = NULL; - data->cookies->numcookies = 0; - } + /* clear all cookies */ + Curl_cookie_clearall(data->cookies); + break; + } + else if(strequal(argptr, "SESS")) { + /* clear session cookies */ + Curl_cookie_clearsess(data->cookies); break; } @@ -2299,7 +2300,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, break; case CURLPROXY_SOCKS4: return handleSock4Proxy(conn->proxyuser, conn) ? - CURLE_COULDNT_CONNECT : CURLE_OK; + CURLE_COULDNT_CONNECT : CURLE_OK; default: failf(conn->data, "unknown proxytype option given"); return CURLE_COULDNT_CONNECT; -- cgit v1.2.1 From 482b3ba70273f2f3cde02e7e57907e1dcc5d9d31 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 26 May 2006 11:26:42 +0000 Subject: long/int cleanup to silence picky compiler warnings --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e9fa81168..be6c99dc2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1950,7 +1950,8 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) { ssize_t actualread; ssize_t written; - int packetsize = 9 + strlen((char*)socksreq + 8); /* size including NUL */ + int packetsize = 9 + + (int)strlen((char*)socksreq + 8); /* size including NUL */ /* Send request */ code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); -- cgit v1.2.1 From 990e56fb13e1e538415a69c69754b21609a14ed6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 8 Jun 2006 06:12:30 +0000 Subject: Brian Dessent's fixes for cygwin builds --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index be6c99dc2..985ade1c5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -157,7 +157,7 @@ static long ConnectionStore(struct SessionHandle *data, #ifndef USE_ARES /* not for Win32, unless it is cygwin not for ares builds */ -#if !defined(WIN32) || defined(__CYGWIN32__) +#if !defined(WIN32) || defined(__CYGWIN__) #ifndef RETSIGTYPE #define RETSIGTYPE void -- cgit v1.2.1 From dfe1884c2529d728750d0824f73055627673cd72 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 22 Jun 2006 21:36:53 +0000 Subject: Peter Silva introduced CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE that limit tha maximum rate libcurl is allowed to send or receive data. This kind of adds the the command line tool's option --limit-rate to the library. The rate limiting logic in the curl app is now removed and is instead provided by libcurl itself. Transfer rate limiting will now also work for -d and -F, which it didn't before. --- lib/url.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 985ade1c5..85537b2ce 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1039,6 +1039,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.low_speed_limit=va_arg(param, long); break; + case CURLOPT_MAX_SEND_SPEED_LARGE: + /* + * The max speed limit that sends transfer more than + * CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is + * throttled.. + */ + data->set.max_send_speed=va_arg(param, curl_off_t); + break; + case CURLOPT_MAX_RECV_SPEED_LARGE: + /* + * The max speed limit that sends transfer more than + * CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is + * throttled.. + */ + data->set.max_recv_speed=va_arg(param, curl_off_t); + break; case CURLOPT_LOW_SPEED_TIME: /* * The low speed time that if transfers are below the set -- cgit v1.2.1 From ca319f63ad757a69f14105ab4a8bbf10987b8ad0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 Jul 2006 22:58:06 +0000 Subject: Ingmar Runge provided a source snippet that caused a crash. The reason for the crash was that libcurl internally was a bit confused about who owned the DNS cache at all times so if you created an easy handle that uses a shared DNS cache and added that to a multi handle it would crash. Now we keep more careful internal track of exactly what kind of DNS cache each easy handle uses: None, Private (allocated for and used only by this single handle), Shared (points to a cache held by a shared object), Global (points to the global cache) or Multi (points to the cache within the multi handle that is automatically shared between all easy handles that are added with private caches). --- lib/url.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 85537b2ce..6e50e7a03 100644 --- a/lib/url.c +++ b/lib/url.c @@ -205,7 +205,7 @@ CURLcode Curl_close(struct SessionHandle *data) if ( ! (data->share && data->share->hostcache) ) { if ( !Curl_global_host_cache_use(data)) { - Curl_hash_destroy(data->hostcache); + Curl_hash_destroy(data->dns.hostcache); } } @@ -1392,8 +1392,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(data->share) { Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - if(data->share->hostcache == data->hostcache) - data->hostcache = NULL; + if(data->dns.hostcachetype == HCACHE_SHARED) { + data->dns.hostcache = NULL; + data->dns.hostcachetype = HCACHE_NONE; + } if(data->share->cookies == data->cookies) data->cookies = NULL; @@ -1413,11 +1415,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->share->dirty++; if(data->share->hostcache) { - /* use shared host cache, first free own one if any */ - if(data->hostcache) - Curl_hash_destroy(data->hostcache); + /* use shared host cache, first free the private one if any */ + if(data->dns.hostcachetype == HCACHE_PRIVATE) + Curl_hash_destroy(data->dns.hostcache); - data->hostcache = data->share->hostcache; + data->dns.hostcache = data->share->hostcache; + data->dns.hostcachetype = HCACHE_SHARED; } #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(data->share->cookies) { -- cgit v1.2.1 From daef1cf34d6df8b199cf2081bda4b1b4d1916b97 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 14 Jul 2006 18:58:42 +0000 Subject: David McCreedy fixed a flaw where the CRLF counter wasn't properly cleared for FTP ASCII transfers. --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6e50e7a03..e7537c6ec 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3930,6 +3930,9 @@ static CURLcode SetupConnection(struct connectdata *conn, conn->bytecount = 0; conn->headerbytecount = 0; +#ifdef CURL_DO_LINEEND_CONV + data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ +#endif /* CURL_DO_LINEEND_CONV */ if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { bool connected = FALSE; -- cgit v1.2.1 From 9c83a20a278e69170f24abff36623471ec53071d Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 17 Jul 2006 14:52:31 +0000 Subject: Fix compiler warning "enumerated type mixed with another type" --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e7537c6ec..7c0ebc7e6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2486,7 +2486,7 @@ static bool tld_check_name(struct SessionHandle *data, if (rc == TLD_INVALID) infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", #ifdef HAVE_TLD_STRERROR - tld_strerror(rc), + tld_strerror((Tld_rc)rc), #else "", #endif @@ -2496,7 +2496,7 @@ static bool tld_check_name(struct SessionHandle *data, infof(data, "WARNING: TLD check for %s failed; %s\n", uc_name, #ifdef HAVE_TLD_STRERROR - tld_strerror(rc) + tld_strerror((Tld_rc)rc) #else "" #endif -- cgit v1.2.1 From d157c292693972658d138475276dca85df77539b Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 19 Jul 2006 21:14:02 +0000 Subject: Fix compiler warnings --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7c0ebc7e6..85fef52c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2927,7 +2927,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Now, build _proxy and check for such a one to use */ while(*protop) - *envp++ = tolower((int)*protop++); + *envp++ = (char)tolower((int)*protop++); /* append _proxy */ strcpy(envp, "_proxy"); @@ -2950,7 +2950,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(!prox && !strequal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ for(envp = proxy_env; *envp; envp++) - *envp = toupper((int)*envp); + *envp = (char)toupper((int)*envp); prox=curl_getenv(proxy_env); } @@ -3080,7 +3080,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } conn->port = port; - conn->remote_port = port; + conn->remote_port = (unsigned short)port; conn->protocol |= PROT_FTP; if(data->change.proxy && @@ -3120,7 +3120,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(type) { char command; *type=0; /* it was in the middle of the hostname */ - command = toupper((int)type[6]); + command = (char)toupper((int)type[6]); switch(command) { case 'A': /* ASCII mode */ data->set.ftp_ascii = 1; @@ -3222,7 +3222,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(type) { char command; *type=0; /* it was in the middle of the hostname */ - command = toupper((int)type[6]); + command = (char)toupper((int)type[6]); switch(command) { case 'A': /* ASCII mode */ case 'N': /* NETASCII mode */ -- cgit v1.2.1 From e40641bf7c15f8f4b850d52153b4cca9fd56810f Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Fri, 21 Jul 2006 04:19:44 +0000 Subject: Use calloc() instead. --- lib/url.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 85fef52c0..894f07802 100644 --- a/lib/url.c +++ b/lib/url.c @@ -369,13 +369,10 @@ CURLcode Curl_open(struct SessionHandle **curl) /* create an array with connection data struct pointers */ data->state.numconnects = 5; /* hard-coded right now */ data->state.connects = (struct connectdata **) - malloc(sizeof(struct connectdata *) * data->state.numconnects); + calloc(sizeof(struct connectdata *) * data->state.numconnects, 1); if(!data->state.connects) res = CURLE_OUT_OF_MEMORY; - else - memset(data->state.connects, 0, - sizeof(struct connectdata *)*data->state.numconnects); /* most recent connection is not yet defined */ data->state.lastconnect = -1; -- cgit v1.2.1 From 385db0e97d901f7308ebe92318d6e5a05891cd54 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Mon, 24 Jul 2006 15:56:40 +0000 Subject: Fix typo. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 894f07802..17e3a7f57 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3808,7 +3808,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * there, thus overriding any defaults that might have been set above. */ conn->port = conn->remote_port; /* it is the same port */ - /* Resolve target host right on */ + /* Resolve target host right now */ rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr); if(rc == CURLRESOLV_PENDING) *async = TRUE; -- cgit v1.2.1 From 2527b5301946539363754a390974cdd3a3d34485 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Jul 2006 22:45:21 +0000 Subject: Dan Nelson added the CURLOPT_FTP_ALTERNATIVE_TO_USER libcurl option and curl tool option named --ftp-alternative-to-user. It provides a mean to send a particular command if the normal USER/PASS approach fails. --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 17e3a7f57..b25d02be8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1546,6 +1546,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.connect_only = va_arg(param, long)?TRUE:FALSE; break; + case CURLOPT_FTP_ALTERNATIVE_TO_USER: + data->set.ftp_alternative_to_user = va_arg(param, char *); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 9dde0b54a3e834d2c33a00a8c3d15a716086ed9e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 31 Jul 2006 17:46:28 +0000 Subject: Silence warning: empty body in an if-statement --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b25d02be8..6b376faf7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -228,10 +228,11 @@ CURLcode Curl_close(struct SessionHandle *data) #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); if(data->set.cookiejar) { - if(data->change.cookielist) + if(data->change.cookielist) { /* If there is a list of cookie files to read, do it first so that we have all the told files read before we write the new jar */ Curl_cookie_loadfiles(data); + } /* we have a "destination" for all the cookies to get dumped to */ if(Curl_cookie_output(data->cookies, data->set.cookiejar)) -- cgit v1.2.1 From cfdcae4bc75fba04b9864cae18e0bbe66b8655b9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 19 Aug 2006 21:18:36 +0000 Subject: Based on a patch by Armel Asselin, the FTP code no longer re-issues the TYPE command on subsequent requests on a re-used connection unless it has to. --- lib/url.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6b376faf7..c0641c78b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -612,7 +612,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * * Transfer using ASCII (instead of BINARY). */ - data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE; + data->set.prefer_ascii = va_arg(param, long)?TRUE:FALSE; break; case CURLOPT_TIMECONDITION: /* @@ -3125,15 +3125,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, command = (char)toupper((int)type[6]); switch(command) { case 'A': /* ASCII mode */ - data->set.ftp_ascii = 1; + data->set.prefer_ascii = TRUE; break; case 'D': /* directory mode */ - data->set.ftp_list_only = 1; + data->set.ftp_list_only = TRUE; break; case 'I': /* binary mode */ default: /* switch off ASCII */ - data->set.ftp_ascii = 0; + data->set.prefer_ascii = FALSE; break; } } @@ -3228,13 +3228,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, switch(command) { case 'A': /* ASCII mode */ case 'N': /* NETASCII mode */ - data->set.ftp_ascii = 1; + data->set.prefer_ascii = TRUE; break; case 'O': /* octet mode */ case 'I': /* binary mode */ default: /* switch off ASCII */ - data->set.ftp_ascii = 0; + data->set.prefer_ascii = FALSE; break; } } -- cgit v1.2.1 From 5acadc9cd7a1ff40ffa8d57214c90d8c788b2b03 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 29 Aug 2006 14:39:33 +0000 Subject: David McCreedy added CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA to allow applications to set their own socket options. --- lib/url.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c0641c78b..17f543615 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1551,6 +1551,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ftp_alternative_to_user = va_arg(param, char *); break; + case CURLOPT_SOCKOPTFUNCTION: + /* + * socket callback function: called after socket() but before connect() + */ + data->set.fsockopt = va_arg(param, curl_sockopt_callback); + break; + + case CURLOPT_SOCKOPTDATA: + /* + * socket callback data pointer. Might be NULL. + */ + data->set.sockopt_client = va_arg(param, void *); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 59cf6fd4f058917839a407f5a206f5f1c1a004a6 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Tue, 29 Aug 2006 18:45:55 +0000 Subject: Watcom lacks . --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 17f543615..8bb429ba4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -46,7 +46,9 @@ #include #endif #include +#ifndef __WATCOMC__ #include +#endif #ifdef HAVE_UNISTD_H #include #endif -- cgit v1.2.1 From c7aae1030004da71c7c046fd6af259f91bbfa991 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Wed, 30 Aug 2006 16:17:06 +0000 Subject: Removed "#ifndef__WATCOMC__". Use "#ifdef HAVE_SYS_TIME_H" instead. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8bb429ba4..bc6e3f2b8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -46,7 +46,7 @@ #include #endif #include -#ifndef __WATCOMC__ +#ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H -- cgit v1.2.1 From 4f4277d9c73b876d0054474d1f696a555c5c9966 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Sun, 3 Sep 2006 13:52:07 +0000 Subject: Simplified #ifdef on WIN32; the statement " !defined(__GNUC__) || defined(__MINGW32__)" implies CygWin. --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bc6e3f2b8..aaf59132a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -38,7 +38,7 @@ #endif #include -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) +#if defined(WIN32) && !defined(__CYGWIN__) #include #include #else @@ -78,8 +78,8 @@ #ifndef HAVE_SOCKET #error "We can't compile without socket() support!" #endif - #endif + #ifdef USE_LIBIDN #include #include @@ -95,7 +95,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by instead */ #define idn_free(x) (free)(x) #endif -#endif +#endif /* USE_LIBIDN */ #include "urldata.h" #include "netrc.h" -- cgit v1.2.1 From 466d093a92f3e8ccbb8af026e786bc41708caba6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 3 Sep 2006 22:52:42 +0000 Subject: - "Dortik" (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a patch that while not fixing things very nicely, it does make the SOCKS5 proxy connection slightly better as it now acknowledges the timeout for connection and it no longer segfaults in the case when SOCKS requires authentication and you did not specify username:password. --- lib/url.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index aaf59132a..68339790b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2115,14 +2115,49 @@ static int handleSock5Proxy(const char *proxy_name, int result; CURLcode code; curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct SessionHandle *data = conn->data; + long timeout; - Curl_nonblock(sock, FALSE); + /* get timeout */ + if(data->set.timeout && data->set.connecttimeout) { + if (data->set.timeout < data->set.connecttimeout) + timeout = data->set.timeout*1000; + else + timeout = data->set.connecttimeout*1000; + } + else if(data->set.timeout) + timeout = data->set.timeout*1000; + else if(data->set.connecttimeout) + timeout = data->set.connecttimeout*1000; + else + timeout = DEFAULT_CONNECT_TIMEOUT; + + Curl_nonblock(sock, TRUE); + + /* wait until socket gets connected */ + result = Curl_select(CURL_SOCKET_BAD, sock, timeout); + + if(-1 == result) { + failf(conn->data, "SOCKS5: no connection here"); + return 1; + } + else if(0 == result) { + failf(conn->data, "SOCKS5: connection timeout"); + return 1; + } + + if(result & CSELECT_ERR) { + failf(conn->data, "SOCKS5: error occured during connection"); + return 1; + } socksreq[0] = 5; /* version */ socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */ socksreq[2] = 0; /* no authentication */ socksreq[3] = 2; /* username/password */ + Curl_nonblock(sock, FALSE); + code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), &written); if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) { @@ -2130,6 +2165,26 @@ static int handleSock5Proxy(const char *proxy_name, return 1; } + Curl_nonblock(sock, TRUE); + + result = Curl_select(sock, CURL_SOCKET_BAD, timeout); + + if(-1 == result) { + failf(conn->data, "SOCKS5 nothing to read"); + return 1; + } + else if(0 == result) { + failf(conn->data, "SOCKS5 read timeout"); + return 1; + } + + if(result & CSELECT_ERR) { + failf(conn->data, "SOCKS5 read error occured"); + return 1; + } + + Curl_nonblock(sock, FALSE); + result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); if ((result != CURLE_OK) || (actualread != 2)) { failf(conn->data, "Unable to receive initial SOCKS5 response."); @@ -2146,10 +2201,16 @@ static int handleSock5Proxy(const char *proxy_name, } else if (socksreq[1] == 2) { /* Needs user name and password */ - int userlen, pwlen, len; - - userlen = (int)strlen(proxy_name); - pwlen = proxy_password?(int)strlen(proxy_password):0; + size_t userlen, pwlen; + int len; + if(proxy_name && proxy_password) { + userlen = strlen(proxy_name); + pwlen = proxy_password?strlen(proxy_password):0; + } + else { + userlen = 0; + pwlen = 0; + } /* username/password request looks like * +----+------+----------+------+----------+ @@ -4209,4 +4270,3 @@ CURLcode Curl_do_more(struct connectdata *conn) return result; } - -- cgit v1.2.1 From 7e4193b538a517eb27e4cb5b2b7973bae967add8 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 7 Sep 2006 01:18:46 +0000 Subject: Fix compiler warning --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 68339790b..dc14e4704 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2135,7 +2135,7 @@ static int handleSock5Proxy(const char *proxy_name, Curl_nonblock(sock, TRUE); /* wait until socket gets connected */ - result = Curl_select(CURL_SOCKET_BAD, sock, timeout); + result = Curl_select(CURL_SOCKET_BAD, sock, (int)timeout); if(-1 == result) { failf(conn->data, "SOCKS5: no connection here"); @@ -2167,7 +2167,7 @@ static int handleSock5Proxy(const char *proxy_name, Curl_nonblock(sock, TRUE); - result = Curl_select(sock, CURL_SOCKET_BAD, timeout); + result = Curl_select(sock, CURL_SOCKET_BAD, (int)timeout); if(-1 == result) { failf(conn->data, "SOCKS5 nothing to read"); -- cgit v1.2.1 From b7eeb6e67fca686f840eacd6b8394edb58b07482 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 7 Sep 2006 21:49:20 +0000 Subject: Major overhaul introducing http pipelining support and shared connection cache within the multi handle. --- lib/url.c | 936 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 592 insertions(+), 344 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dc14e4704..b5e987725 100644 --- a/lib/url.c +++ b/lib/url.c @@ -118,6 +118,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "http_negotiate.h" #include "select.h" #include "multiif.h" +#include "easyif.h" /* And now for the protocols */ #include "ftp.h" @@ -155,6 +156,10 @@ static bool ConnectionExists(struct SessionHandle *data, struct connectdata **usethis); static long ConnectionStore(struct SessionHandle *data, struct connectdata *conn); +static bool IsPipeliningPossible(struct SessionHandle *handle); +static void conn_free(struct connectdata *conn); + +#define MAX_PIPELINE_LENGTH 5 #ifndef USE_ARES /* not for Win32, unless it is cygwin @@ -186,6 +191,13 @@ void Curl_safefree(void *ptr) free(ptr); } +static void close_connections(struct SessionHandle *data) +{ + /* Loop through all open connections and kill them one by one */ + while(-1 != ConnectionKillOne(data)) + ; /* empty loop */ +} + /* * This is the internal function curl_easy_cleanup() calls. This should * cleanup and free all resources associated with this sessionhandle. @@ -197,13 +209,21 @@ void Curl_safefree(void *ptr) CURLcode Curl_close(struct SessionHandle *data) { - if(data->multi) { - /* this handle is still part of a multi handle, take care of this first */ + struct Curl_multi *m = data->multi; + + if(m) + /* This handle is still part of a multi handle, take care of this first + and detach this handle from there. */ Curl_multi_rmeasy(data->multi, data); + + if(data->state.connc && (data->state.connc->type == CONNCACHE_PRIVATE)) { + /* close all connections still alive that are in the private connection + cache, as we no longer have the pointer left to the shared one. */ + close_connections(data); + + /* free the connection cache if allocated privately */ + Curl_rm_connc(data->state.connc); } - /* Loop through all open connections and kill them one by one */ - while(-1 != ConnectionKillOne(data)) - ; /* empty loop */ if ( ! (data->share && data->share->hostcache) ) { if ( !Curl_global_host_cache_use(data)) { @@ -211,6 +231,18 @@ CURLcode Curl_close(struct SessionHandle *data) } } + if(data->state.shared_conn) { + /* this handle is still being used by a shared connection cache and thus + we leave it around for now */ + Curl_multi_add_closure(data->state.shared_conn, data); + + return CURLE_OK; + } + + /* Free the pathbuffer */ + Curl_safefree(data->reqdata.pathbuffer); + Curl_safefree(data->reqdata.proto.generic); + /* Close down all open SSL info and sessions */ Curl_ssl_close_all(data); Curl_safefree(data->state.first_host); @@ -254,19 +286,12 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); #endif -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) Curl_digest_cleanup(data); -#endif - - /* free the connection cache */ - free(data->state.connects); Curl_safefree(data->info.contenttype); -#ifdef USE_ARES /* this destroys the channel and we cannot use it anymore after this */ ares_destroy(data->state.areschannel); -#endif #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) /* close iconv conversion descriptors */ @@ -289,6 +314,44 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } +/* create a connection cache of a private or multi type */ +struct conncache *Curl_mk_connc(int type) +{ + /* It is subject for debate how many default connections to have for a multi + connection cache... */ + int default_amount = (type == CONNCACHE_PRIVATE)?5:10; + struct conncache *c; + + c= calloc(sizeof(struct conncache), 1); + if(!c) + return NULL; + + c->connects = calloc(sizeof(struct connectdata *), default_amount); + if(!c->connects) { + free(c); + return NULL; + } + + c->num = default_amount; + + return c; +} + +/* Free a connection cache. This is called from Curl_close() and + curl_multi_cleanup(). */ +void Curl_rm_connc(struct conncache *c) +{ + if(c->connects) { + int i; + for(i = 0; i < c->num; ++i) + conn_free(c->connects[i]); + + free(c->connects); + } + + free(c); +} + /** * Curl_open() * @@ -301,6 +364,7 @@ CURLcode Curl_open(struct SessionHandle **curl) { CURLcode res = CURLE_OK; struct SessionHandle *data; + /* Very simple start-up: alloc the struct, init it with zeroes and return */ data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle)); if(!data) @@ -369,17 +433,15 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */ data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */ - /* create an array with connection data struct pointers */ - data->state.numconnects = 5; /* hard-coded right now */ - data->state.connects = (struct connectdata **) - calloc(sizeof(struct connectdata *) * data->state.numconnects, 1); - - if(!data->state.connects) - res = CURLE_OUT_OF_MEMORY; + /* This no longer creates a connection cache here. It is instead made on + the first call to curl_easy_perform() or when the handle is added to a + multi stack. */ /* most recent connection is not yet defined */ data->state.lastconnect = -1; + Curl_easy_initHandleData(data); + /* * libcurl 7.10 introduced SSL verification *by default*! This needs to be * switched off unless wanted. @@ -393,9 +455,7 @@ CURLcode Curl_open(struct SessionHandle **curl) } if(res) { -#ifdef USE_ARES ares_destroy(data->state.areschannel); -#endif if(data->state.headerbuff) free(data->state.headerbuff); free(data); @@ -454,41 +514,39 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, struct connectdata **newptr; long i; - if(newconnects < data->state.numconnects) { + if(newconnects < data->state.connc->num) { /* 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! */ - for(i=newconnects; i< data->state.numconnects; i++) - Curl_disconnect(data->state.connects[i]); + are being removed! + + NOTE: for conncache_multi cases we must make sure that we only + close handles not in use. + */ + for(i=newconnects; i< data->state.connc->num; i++) + Curl_disconnect(data->state.connc->connects[i]); - /* If the most recent connection is no longer valid, mark it invalid. */ + /* If the most recent connection is no longer valid, mark it + invalid. */ if(data->state.lastconnect <= newconnects) data->state.lastconnect = -1; } - if(newconnects) { + if(newconnects > 0) { newptr= (struct connectdata **) - realloc(data->state.connects, + realloc(data->state.connc->connects, sizeof(struct connectdata *) * newconnects); if(!newptr) /* we closed a few connections in vain, but so what? */ return CURLE_OUT_OF_MEMORY; /* nullify the newly added pointers */ - for(i=data->state.numconnects; istate.connc->num; istate.connects = newptr; - data->state.numconnects = newconnects; - } - else { - /* zero makes NO cache at all */ - if(data->state.connects) - free(data->state.connects); - data->state.connects = NULL; - data->state.numconnects = 0; - data->state.lastconnect = -1; + data->state.connc->connects = newptr; + data->state.connc->num = newconnects; } + /* we no longer support less than 1 as size for the connection cache, + and I'm not sure it ever worked to set it to zero */ } break; case CURLOPT_FORBID_REUSE: @@ -1576,14 +1634,57 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, return result; } +static void conn_free(struct connectdata *conn) +{ + if (!conn) + return; + + /* close possibly still open sockets */ + if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) + sclose(conn->sock[SECONDARYSOCKET]); + if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) + sclose(conn->sock[FIRSTSOCKET]); + + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + Curl_safefree(conn->proxyuser); + Curl_safefree(conn->proxypasswd); + Curl_safefree(conn->allocptr.proxyuserpwd); + Curl_safefree(conn->allocptr.uagent); + Curl_safefree(conn->allocptr.userpwd); + Curl_safefree(conn->allocptr.accept_encoding); + Curl_safefree(conn->allocptr.rangeline); + Curl_safefree(conn->allocptr.ref); + Curl_safefree(conn->allocptr.host); + Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->ip_addr_str); + Curl_safefree(conn->trailer); + Curl_safefree(conn->sec_pathbuffer); + Curl_safefree(conn->host.rawalloc); /* host name buffer */ + Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ + + Curl_llist_destroy(conn->send_pipe, NULL); + Curl_llist_destroy(conn->recv_pipe, NULL); + + /* possible left-overs from the async name resolvers */ +#if defined(USE_ARES) + Curl_safefree(conn->async.hostname); + Curl_safefree(conn->async.os_specific); +#elif defined(CURLRES_THREADED) + Curl_destroy_thread_data(&conn->async); +#endif + + Curl_free_ssl_config(&conn->ssl_config); + + free(conn); /* free all the connection oriented data */ +} + CURLcode Curl_disconnect(struct connectdata *conn) { - struct SessionHandle *data; + struct SessionHandle *data = conn->data; if(!conn) return CURLE_OK; /* this is closed and fine already */ - data = conn->data; - #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, @@ -1598,9 +1699,9 @@ CURLcode Curl_disconnect(struct connectdata *conn) * get here *instead* if we fail prematurely. Thus we need to be able * to free this resource here as well. */ - if(conn->bits.rangestringalloc) { - free(conn->range); - conn->bits.rangestringalloc = FALSE; + if(data->reqdata.rangestringalloc) { + free(data->reqdata.range); + data->reqdata.rangestringalloc = FALSE; } if((conn->ntlm.state != NTLMSTATE_NONE) || @@ -1628,15 +1729,9 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(-1 != conn->connectindex) { /* unlink ourselves! */ infof(data, "Closing connection #%ld\n", conn->connectindex); - data->state.connects[conn->connectindex] = NULL; + data->state.connc->connects[conn->connectindex] = NULL; } - Curl_safefree(conn->proto.generic); - Curl_safefree(conn->newurl); - Curl_safefree(conn->pathbuffer); /* the URL path buffer */ - - Curl_safefree(conn->host.rawalloc); /* host name buffer */ - Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ #ifdef USE_LIBIDN if(conn->host.encalloc) idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed @@ -1647,40 +1742,14 @@ CURLcode Curl_disconnect(struct connectdata *conn) freed with idn_free() since this was allocated by libidn */ #endif - Curl_ssl_close(conn); - - /* close possibly still open sockets */ - if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) - sclose(conn->sock[SECONDARYSOCKET]); - if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) - sclose(conn->sock[FIRSTSOCKET]); - Curl_safefree(conn->user); - Curl_safefree(conn->passwd); - Curl_safefree(conn->proxyuser); - Curl_safefree(conn->proxypasswd); - Curl_safefree(conn->allocptr.proxyuserpwd); - Curl_safefree(conn->allocptr.uagent); - Curl_safefree(conn->allocptr.userpwd); - Curl_safefree(conn->allocptr.accept_encoding); - Curl_safefree(conn->allocptr.rangeline); - Curl_safefree(conn->allocptr.ref); - Curl_safefree(conn->allocptr.host); - Curl_safefree(conn->allocptr.cookiehost); - Curl_safefree(conn->ip_addr_str); - Curl_safefree(conn->trailer); - - /* possible left-overs from the async name resolvers */ -#if defined(USE_ARES) - Curl_safefree(conn->async.hostname); - Curl_safefree(conn->async.os_specific); -#elif defined(CURLRES_THREADED) - Curl_destroy_thread_data(&conn->async); -#endif + Curl_ssl_close(conn); - Curl_free_ssl_config(&conn->ssl_config); + /* Indicate to all handles on the pipe that we're dead */ + Curl_signalPipeClose(conn->send_pipe); + Curl_signalPipeClose(conn->recv_pipe); - free(conn); /* free all the connection oriented data */ + conn_free(conn); return CURLE_OK; } @@ -1703,10 +1772,92 @@ static bool SocketIsDead(curl_socket_t sock) return ret_val; } +static bool IsPipeliningPossible(struct SessionHandle *handle) +{ + if (handle->multi && Curl_multi_canPipeline(handle->multi) && + (handle->set.httpreq == HTTPREQ_GET || + handle->set.httpreq == HTTPREQ_HEAD) && + handle->set.httpversion != CURL_HTTP_VERSION_1_0) + return TRUE; + + return FALSE; +} + +void Curl_addHandleToPipeline(struct SessionHandle *handle, + struct curl_llist *pipe) +{ + Curl_llist_insert_next(pipe, + pipe->tail, + handle); +} + + +void Curl_removeHandleFromPipeline(struct SessionHandle *handle, + struct curl_llist *pipe) +{ + struct curl_llist_element *curr; + + curr = pipe->head; + while (curr) { + if (curr->ptr == handle) { + Curl_llist_remove(pipe, curr, NULL); + break; + } + curr = curr->next; + } +} + +#if 0 +static void Curl_printPipeline(struct curl_llist *pipe) +{ + struct curl_llist_element *curr; + + curr = pipe->head; + while (curr) { + struct SessionHandle *data = (struct SessionHandle *) curr->ptr; + infof(data, "Handle in pipeline: %s\n", + data->reqdata.path); + curr = curr->next; + } +} +#endif + +bool Curl_isHandleAtHead(struct SessionHandle *handle, + struct curl_llist *pipe) +{ + struct curl_llist_element *curr = pipe->head; + if (curr) { + return curr->ptr == handle ? TRUE : FALSE; + } + + return FALSE; +} + +void Curl_signalPipeClose(struct curl_llist *pipe) +{ + struct curl_llist_element *curr; + + curr = pipe->head; + while (curr) { + struct curl_llist_element *next = curr->next; + struct SessionHandle *data = (struct SessionHandle *) curr->ptr; + + data->state.pipe_broke = TRUE; + + Curl_llist_remove(pipe, curr, NULL); + curr = next; + } +} + + /* * Given one filled in connection struct (named needle), this function should - * detect if there already is one that have all the significant details + * detect if there already is one that has all the significant details * exactly the same and thus should be used instead. + * + * If there is a match, this function returns TRUE - and has marked the + * connection as 'in-use'. It must later be called with ConnectionDone() to + * return back to 'idle' (unused) state. */ static bool ConnectionExists(struct SessionHandle *data, @@ -1715,18 +1866,28 @@ ConnectionExists(struct SessionHandle *data, { long i; struct connectdata *check; + bool canPipeline = IsPipeliningPossible(data); - for(i=0; i< data->state.numconnects; i++) { + for(i=0; i< data->state.connc->num; i++) { bool match = FALSE; /* * Note that if we use a HTTP proxy, we check connections to that * proxy and not to the actual remote server. */ - check = data->state.connects[i]; + check = data->state.connc->connects[i]; if(!check) /* NULL pointer means not filled-in entry */ continue; + if(check->inuse && !canPipeline) + /* can only happen within multi handles, and means that another easy + handle is using this connection */ + continue; + + if (check->send_pipe->size >= MAX_PIPELINE_LENGTH || + check->recv_pipe->size >= MAX_PIPELINE_LENGTH) + continue; + if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) /* don't do mixed SSL and non-SSL connections */ continue; @@ -1753,7 +1914,7 @@ ConnectionExists(struct SessionHandle *data, } if((needle->protocol & PROT_FTP) || ((needle->protocol & PROT_HTTP) && - (needle->data->state.authhost.want==CURLAUTH_NTLM))) { + (data->state.authhost.want==CURLAUTH_NTLM))) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ if(!strequal(needle->user, check->user) || @@ -1780,15 +1941,24 @@ ConnectionExists(struct SessionHandle *data, if(dead) { /* */ + check->data = data; infof(data, "Connection %d seems to be dead!\n", i); Curl_disconnect(check); /* disconnect resources */ - data->state.connects[i]=NULL; /* nothing here */ + data->state.connc->connects[i]=NULL; /* nothing here */ /* There's no need to continue searching, because we only store one connection for each unique set of identifiers */ return FALSE; } + check->inuse = TRUE; /* mark this as being in use so that no other + handle in a multi stack may nick it */ + + if (canPipeline) { + /* Mark the connection as being in a pipeline */ + check->is_in_pipeline = TRUE; + } + *usethis = check; return TRUE; /* yes, we found one to use! */ } @@ -1796,6 +1966,7 @@ ConnectionExists(struct SessionHandle *data, return FALSE; /* no matching connecting exists */ } + /* * This function frees/closes a connection in the connection cache. This * should take the previously set policy into account when deciding which @@ -1813,8 +1984,8 @@ ConnectionKillOne(struct SessionHandle *data) now = Curl_tvnow(); - for(i=0; i< data->state.numconnects; i++) { - conn = data->state.connects[i]; + for(i=0; data->state.connc && (i< data->state.connc->num); i++) { + conn = data->state.connc->connects[i]; if(!conn) continue; @@ -1846,17 +2017,32 @@ ConnectionKillOne(struct SessionHandle *data) } } if(connindex >= 0) { + /* Set the connection's owner correctly */ + conn = data->state.connc->connects[connindex]; + conn->data = data; /* the winner gets the honour of being disconnected */ - (void) Curl_disconnect(data->state.connects[connindex]); + (void)Curl_disconnect(conn); /* clean the array entry */ - data->state.connects[connindex] = NULL; + data->state.connc->connects[connindex] = NULL; } return connindex; /* return the available index or -1 */ } +/* this connection can now be marked 'idle' */ +static void +ConnectionDone(struct connectdata *conn) +{ + conn->inuse = FALSE; + conn->data = NULL; + + if (conn->send_pipe == 0 && + conn->recv_pipe == 0) + conn->is_in_pipeline = FALSE; +} + /* * The given input connection struct pointer is to be stored. If the "cache" * is already full, we must clean out the most suitable using the previously @@ -1870,24 +2056,34 @@ ConnectionStore(struct SessionHandle *data, struct connectdata *conn) { long i; - for(i=0; i< data->state.numconnects; i++) { - if(!data->state.connects[i]) + for(i=0; i< data->state.connc->num; i++) { + if(!data->state.connc->connects[i]) break; } - if(i == data->state.numconnects) { + if(i == data->state.connc->num) { /* there was no room available, kill one */ i = ConnectionKillOne(data); infof(data, "Connection (#%d) was killed to make room\n", i); } + conn->connectindex = i; /* Make the child know where the pointer to this + particular data is stored. But note that this -1 + if this is not within the cache and this is + probably not checked for everywhere (yet). */ + conn->inuse = TRUE; if(-1 != i) { - /* only do this if a true index was returned, if -1 was returned there + /* Only do this if a true index was returned, if -1 was returned there is no room in the cache for an unknown reason and we cannot store - this there. */ - data->state.connects[i] = conn; /* fill in this */ - conn->connectindex = i; /* make the child know where the pointer to this - particular data is stored */ + this there. + + TODO: make sure we really can work with more handles than positions in + the cache, or possibly we should (allow to automatically) resize the + connection cache when we add more easy handles to a multi handle! + */ + data->state.connc->connects[i] = conn; /* fill in this */ + conn->data = data; } + return i; } @@ -1902,13 +2098,14 @@ ConnectionStore(struct SessionHandle *data, * Nonsupport "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" * Nonsupport "Identification Protocol (RFC1413)" */ -static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) +static int handleSock4Proxy(const char *proxy_name, + struct SessionHandle *data, + struct connectdata *conn) { unsigned char socksreq[262]; /* room for SOCKS4 request incl. user id */ int result; CURLcode code; curl_socket_t sock = conn->sock[FIRSTSOCKET]; - struct SessionHandle *data = conn->data; Curl_nonblock(sock, FALSE); @@ -1964,11 +2161,11 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) else hp = NULL; /* fail! */ - Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ + Curl_resolv_unlock(data, dns); /* not used anymore from now on */ } if(!hp) { - failf(conn->data, "Failed to resolve \"%s\" for SOCKS4 connect.", + failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", conn->host.name); return 1; } @@ -1993,7 +2190,7 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) /* Send request */ code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); if ((code != CURLE_OK) || (written != packetsize)) { - failf(conn->data, "Failed to send SOCKS4 connect request."); + failf(data, "Failed to send SOCKS4 connect request."); return 1; } @@ -2002,7 +2199,7 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) /* Receive response */ result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); if ((result != CURLE_OK) || (actualread != packetsize)) { - failf(conn->data, "Failed to receive SOCKS4 connect request ack."); + failf(data, "Failed to receive SOCKS4 connect request ack."); return 1; } @@ -2027,7 +2224,7 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) /* wrong version ? */ if (socksreq[0] != 0) { - failf(conn->data, + failf(data, "SOCKS4 reply has wrong version, version should be 4."); return 1; } @@ -2039,7 +2236,7 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) infof(data, "SOCKS4 request granted.\n"); break; case 91: - failf(conn->data, + failf(data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", request rejected or failed.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], @@ -2048,7 +2245,7 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) socksreq[1]); return 1; case 92: - failf(conn->data, + failf(data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", request rejected because SOCKS server cannot connect to " "identd on the client.", @@ -2058,7 +2255,7 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) socksreq[1]); return 1; case 93: - failf(conn->data, + failf(data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", request rejected because the client program and identd " "report different user-ids.", @@ -2068,7 +2265,7 @@ static int handleSock4Proxy(const char *proxy_name, struct connectdata *conn) socksreq[1]); return 1; default : - failf(conn->data, + failf(data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" ", Unknown.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], @@ -2161,7 +2358,7 @@ static int handleSock5Proxy(const char *proxy_name, code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), &written); if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) { - failf(conn->data, "Unable to send initial SOCKS5 request."); + failf(data, "Unable to send initial SOCKS5 request."); return 1; } @@ -2187,12 +2384,12 @@ static int handleSock5Proxy(const char *proxy_name, result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); if ((result != CURLE_OK) || (actualread != 2)) { - failf(conn->data, "Unable to receive initial SOCKS5 response."); + failf(data, "Unable to receive initial SOCKS5 response."); return 1; } if (socksreq[0] != 5) { - failf(conn->data, "Received invalid version in initial SOCKS5 response."); + failf(data, "Received invalid version in initial SOCKS5 response."); return 1; } if (socksreq[1] == 0) { @@ -2230,19 +2427,19 @@ static int handleSock5Proxy(const char *proxy_name, code = Curl_write(conn, sock, (char *)socksreq, len, &written); if ((code != CURLE_OK) || (len != written)) { - failf(conn->data, "Failed to send SOCKS5 sub-negotiation request."); + failf(data, "Failed to send SOCKS5 sub-negotiation request."); return 1; } result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); if ((result != CURLE_OK) || (actualread != 2)) { - failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response."); + failf(data, "Unable to receive SOCKS5 sub-negotiation response."); return 1; } /* ignore the first (VER) byte */ if (socksreq[1] != 0) { /* status */ - failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", + failf(data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); return 1; } @@ -2252,24 +2449,24 @@ static int handleSock5Proxy(const char *proxy_name, else { /* error */ if (socksreq[1] == 1) { - failf(conn->data, + failf(data, "SOCKS5 GSSAPI per-message authentication is not supported."); return 1; } else if (socksreq[1] == 255) { if (!proxy_name || !*proxy_name) { - failf(conn->data, + failf(data, "No authentication method was acceptable. (It is quite likely" " that the SOCKS5 server wanted a username/password, since none" " was supplied to the server on this connection.)"); } else { - failf(conn->data, "No authentication method was acceptable."); + failf(data, "No authentication method was acceptable."); } return 1; } else { - failf(conn->data, + failf(data, "Undocumented SOCKS5 mode attempted to be used by server."); return 1; } @@ -2314,10 +2511,10 @@ static int handleSock5Proxy(const char *proxy_name, else hp = NULL; /* fail! */ - Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ + Curl_resolv_unlock(data, dns); /* not used anymore from now on */ } if(!hp) { - failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", + failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", conn->host.name); return 1; } @@ -2330,23 +2527,23 @@ static int handleSock5Proxy(const char *proxy_name, code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); if ((code != CURLE_OK) || (written != packetsize)) { - failf(conn->data, "Failed to send SOCKS5 connect request."); + failf(data, "Failed to send SOCKS5 connect request."); return 1; } result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); if ((result != CURLE_OK) || (actualread != packetsize)) { - failf(conn->data, "Failed to receive SOCKS5 connect request ack."); + failf(data, "Failed to receive SOCKS5 connect request ack."); return 1; } if (socksreq[0] != 5) { /* version */ - failf(conn->data, + failf(data, "SOCKS5 reply has wrong version, version should be 5."); return 1; } if (socksreq[1] != 0) { /* Anything besides 0 is an error */ - failf(conn->data, + failf(data, "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], @@ -2360,13 +2557,13 @@ static int handleSock5Proxy(const char *proxy_name, return 0; /* Proxy was successful! */ } -static CURLcode ConnectPlease(struct connectdata *conn, +static CURLcode ConnectPlease(struct SessionHandle *data, + struct connectdata *conn, struct Curl_dns_entry *hostaddr, bool *connected) { CURLcode result; Curl_addrinfo *addr; - struct SessionHandle *data = conn->data; char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; infof(data, "About to connect() to %s%s port %d\n", @@ -2388,7 +2585,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, Curl_store_ip_addr(conn); - switch(conn->data->set.proxytype) { + switch(data->set.proxytype) { case CURLPROXY_SOCKS5: return handleSock5Proxy(conn->proxyuser, conn->proxypasswd, @@ -2398,10 +2595,10 @@ static CURLcode ConnectPlease(struct connectdata *conn, /* do nothing here. handled later. */ break; case CURLPROXY_SOCKS4: - return handleSock4Proxy(conn->proxyuser, conn) ? + return handleSock4Proxy(conn->proxyuser, data, conn) ? CURLE_COULDNT_CONNECT : CURLE_OK; default: - failf(conn->data, "unknown proxytype option given"); + failf(data, "unknown proxytype option given"); return CURLE_COULDNT_CONNECT; } } @@ -2443,7 +2640,8 @@ int Curl_doing_getsock(struct connectdata *conn, * protocol layer. */ -CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done) +CURLcode Curl_protocol_connecting(struct connectdata *conn, + bool *done) { CURLcode result=CURLE_OK; @@ -2481,10 +2679,11 @@ CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) * proceed with some action. * */ -CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done) +CURLcode Curl_protocol_connect(struct connectdata *conn, + bool *protocol_done) { - struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; + struct SessionHandle *data = conn->data; *protocol_done = FALSE; @@ -2586,7 +2785,8 @@ static bool tld_check_name(struct SessionHandle *data, } #endif -static void fix_hostname(struct connectdata *conn, struct hostname *host) +static void fix_hostname(struct SessionHandle *data, + struct connectdata *conn, struct hostname *host) { /* set the name we use to display the host name */ host->dispname = host->name; @@ -2598,7 +2798,6 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) if (!is_ASCII_name(host->name) && stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { char *ace_hostname = NULL; - struct SessionHandle *data = conn->data; int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); infof (data, "Input domain encoded as `%s'\n", stringprep_locale_charset ()); @@ -2616,147 +2815,21 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) } } #else + (void)data; /* never used */ (void)conn; /* never used */ #endif } - -/** - * CreateConnection() sets up a new connectdata struct, or re-uses an already - * existing one, and resolves host name. - * - * if this function returns CURLE_OK and *async is set to TRUE, the resolve - * response will be coming asynchronously. If *async is FALSE, the name is - * already resolved. - * - * @param data The sessionhandle pointer - * @param in_connect is set to the next connection data pointer - * @param addr is set to the new dns entry for this connection. If this - * connection is re-used it will be NULL. - * @param async is set TRUE/FALSE depending on the nature of this lookup - * @return CURLcode - * @see SetupConnection() +/* + * Parse URL and fill in the relevant members of the connection struct. */ - -static CURLcode CreateConnection(struct SessionHandle *data, - struct connectdata **in_connect, - struct Curl_dns_entry **addr, - bool *async) +static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, + struct connectdata *conn) { - char *tmp; char *at; - CURLcode result=CURLE_OK; - struct connectdata *conn; - struct connectdata *conn_temp = NULL; - size_t urllen; - struct Curl_dns_entry *hostaddr; -#if defined(HAVE_ALARM) && !defined(USE_ARES) - unsigned int prev_alarm=0; -#endif - char endbracket; - char user[MAX_CURL_USER_LENGTH]; - char passwd[MAX_CURL_PASSWORD_LENGTH]; - int rc; - bool reuse; - -#ifndef USE_ARES -#ifdef SIGALRM -#ifdef HAVE_SIGACTION - struct sigaction keep_sigact; /* store the old struct here */ - bool keep_copysig=FALSE; /* did copy it? */ -#else -#ifdef HAVE_SIGNAL - void *keep_sigact; /* store the old handler here */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ -#endif /* SIGALRM */ -#endif /* USE_ARES */ - - *addr = NULL; /* nothing yet */ - *async = FALSE; - - /************************************************************* - * Check input data - *************************************************************/ - - if(!data->change.url) - return CURLE_URL_MALFORMAT; - - /* First, split up the current URL in parts so that we can use the - parts for checking against the already present connections. In order - to not have to modify everything at once, we allocate a temporary - connection data struct and fill in for comparison purposes. */ - - conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1); - if(!conn) { - *in_connect = NULL; /* clear the pointer */ - return CURLE_OUT_OF_MEMORY; - } - /* We must set the return variable as soon as possible, so that our - parent can cleanup any possible allocs we may have done before - any failure */ - *in_connect = conn; - - /* and we setup a few fields in case we end up actually using this struct */ - conn->data = data; /* remember our daddy */ - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->connectindex = -1; /* no index */ - conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && - (data->set.proxytype == CURLPROXY_HTTP))? - TRUE:FALSE; /* http proxy or not */ - - /* Default protocol-independent behavior doesn't support persistent - connections, so we set this to force-close. Protocols that support - this need to set this to FALSE in their "curl_do" functions. */ - conn->bits.close = TRUE; - - /* maxdownload must be -1 on init, as 0 is a valid value! */ - conn->maxdownload = -1; /* might have been used previously! */ - - /* Store creation time to help future close decision making */ - conn->created = Curl_tvnow(); - - 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; /* inherit resume_from */ - - conn->bits.user_passwd = data->set.userpwd?1:0; - conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; - conn->bits.no_body = data->set.opt_no_body; - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; - conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; - conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; - - /* This initing continues below, see the comment "Continue connectdata - * initialization here" */ - - /*********************************************************** - * We need to allocate memory to store the path in. We get the size of the - * full URL to be sure, and we need to make it at least 256 bytes since - * other parts of the code will rely on this fact - ***********************************************************/ -#define LEAST_PATH_ALLOC 256 - urllen=strlen(data->change.url); - if(urllen < LEAST_PATH_ALLOC) - urllen=LEAST_PATH_ALLOC; - - /* - * We malloc() the buffers below urllen+2 to make room for to possibilities: - * 1 - an extra terminating zero - * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) - */ + char *tmp; - conn->pathbuffer=(char *)malloc(urllen+2); - if(NULL == conn->pathbuffer) - return CURLE_OUT_OF_MEMORY; /* really bad error */ - conn->path = conn->pathbuffer; - - conn->host.rawalloc=(char *)malloc(urllen+2); - if(NULL == conn->host.rawalloc) - return CURLE_OUT_OF_MEMORY; - conn->host.name = conn->host.rawalloc; - conn->host.name[0] = 0; + char *path = data->reqdata.path; /************************************************************* * Parse the URL. @@ -2768,8 +2841,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, ************************************************************/ if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", conn->protostr, - conn->path)) && strequal(conn->protostr, "file")) { - if(conn->path[0] == '/' && conn->path[1] == '/') { + path)) && strequal(conn->protostr, "file")) { + if(path[0] == '/' && path[1] == '/') { /* Allow omitted hostname (e.g. file:/). This is not strictly * speaking a valid file: URL by RFC 1738, but treating file:/ as * file://localhost/ is similar to how other schemes treat missing @@ -2777,17 +2850,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* This cannot be done with strcpy() in a portable manner, since the memory areas overlap! */ - memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1); + memmove(path, path + 2, strlen(path + 2)+1); } /* * we deal with file:/// differently since it supports no * hostname other than "localhost" and "127.0.0.1", which is unique among * the URL protocols specified in RFC 1738 */ - if(conn->path[0] != '/') { + if(path[0] != '/') { /* the URL included a host name, we ignore host names in file:// URLs as the standards don't define what to do with them */ - char *ptr=strchr(conn->path, '/'); + char *ptr=strchr(path, '/'); if(ptr) { /* there was a slash present @@ -2810,7 +2883,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, ptr++; /* This cannot be made with strcpy, as the memory chunks overlap! */ - memmove(conn->path, ptr, strlen(ptr)+1); + memmove(path, ptr, strlen(ptr)+1); } } @@ -2818,19 +2891,19 @@ static CURLcode CreateConnection(struct SessionHandle *data, } else { /* clear path */ - conn->path[0]=0; + path[0]=0; if (2 > sscanf(data->change.url, "%15[^\n:]://%[^\n/]%[^\n]", conn->protostr, - conn->host.name, conn->path)) { + conn->host.name, path)) { /* * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]", - conn->host.name, conn->path)) ) { + conn->host.name, path)) ) { /* * We couldn't even get this format. */ @@ -2886,43 +2959,213 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ size_t hostlen = strlen(tmp); - size_t pathlen = strlen(conn->path); + size_t pathlen = strlen(path); /* move the existing path plus the zero byte forward, to make room for the host-name part */ - memmove(conn->path+hostlen+1, conn->path, pathlen+1); + memmove(path+hostlen+1, path, pathlen+1); /* now copy the trailing host part in front of the existing path */ - memcpy(conn->path+1, tmp, hostlen); + memcpy(path+1, tmp, hostlen); - conn->path[0]='/'; /* prepend the missing slash */ + path[0]='/'; /* prepend the missing slash */ *tmp=0; /* now cut off the hostname at the ? */ } - else if(!conn->path[0]) { + else if(!path[0]) { /* if there's no path set, use a single slash */ - strcpy(conn->path, "/"); + strcpy(path, "/"); } /* If the URL is malformatted (missing a '/' after hostname before path) we * insert a slash here. The only letter except '/' we accept to start a path * is '?'. */ - if(conn->path[0] == '?') { + if(path[0] == '?') { /* We need this function to deal with overlapping memory areas. We know that the memory area 'path' points to is 'urllen' bytes big and that is bigger than the path. Use +1 to move the zero byte too. */ - memmove(&conn->path[1], conn->path, strlen(conn->path)+1); - conn->path[0] = '/'; + memmove(&path[1], path, strlen(path)+1); + path[0] = '/'; } /* * So if the URL was A://B/C, * conn->protostr is A * conn->host.name is B - * conn->path is /C + * data->reqdata.path is /C + */ + + return CURLE_OK; +} + +static void llist_dtor(void *user, void *element) +{ + (void)user; + (void)element; + /* Do nothing */ +} + + +/** + * CreateConnection() sets up a new connectdata struct, or re-uses an already + * existing one, and resolves host name. + * + * if this function returns CURLE_OK and *async is set to TRUE, the resolve + * response will be coming asynchronously. If *async is FALSE, the name is + * already resolved. + * + * @param data The sessionhandle pointer + * @param in_connect is set to the next connection data pointer + * @param addr is set to the new dns entry for this connection. If this + * connection is re-used it will be NULL. + * @param async is set TRUE/FALSE depending on the nature of this lookup + * @return CURLcode + * @see SetupConnection() + * + * *NOTE* this function assigns the conn->data pointer! + */ + +static CURLcode CreateConnection(struct SessionHandle *data, + struct connectdata **in_connect, + struct Curl_dns_entry **addr, + bool *async) +{ + + char *tmp; + CURLcode result=CURLE_OK; + struct connectdata *conn; + struct connectdata *conn_temp = NULL; + size_t urllen; + struct Curl_dns_entry *hostaddr; +#if defined(HAVE_ALARM) && !defined(USE_ARES) + unsigned int prev_alarm=0; +#endif + char endbracket; + char user[MAX_CURL_USER_LENGTH]; + char passwd[MAX_CURL_PASSWORD_LENGTH]; + int rc; + bool reuse; + +#ifndef USE_ARES +#ifdef SIGALRM +#ifdef HAVE_SIGACTION + struct sigaction keep_sigact; /* store the old struct here */ + bool keep_copysig=FALSE; /* did copy it? */ +#else +#ifdef HAVE_SIGNAL + void *keep_sigact; /* store the old handler here */ +#endif /* HAVE_SIGNAL */ +#endif /* HAVE_SIGACTION */ +#endif /* SIGALRM */ +#endif /* USE_ARES */ + + *addr = NULL; /* nothing yet */ + *async = FALSE; + + /************************************************************* + * Check input data + *************************************************************/ + + if(!data->change.url) + return CURLE_URL_MALFORMAT; + + /* First, split up the current URL in parts so that we can use the + parts for checking against the already present connections. In order + to not have to modify everything at once, we allocate a temporary + connection data struct and fill in for comparison purposes. */ + + conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1); + if(!conn) { + *in_connect = NULL; /* clear the pointer */ + return CURLE_OUT_OF_MEMORY; + } + /* We must set the return variable as soon as possible, so that our + parent can cleanup any possible allocs we may have done before + any failure */ + *in_connect = conn; + + /* and we setup a few fields in case we end up actually using this struct */ + + conn->data = data; /* Setup the association between this connection + and the SessionHandle */ + + conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->connectindex = -1; /* no index */ + conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && + (data->set.proxytype == CURLPROXY_HTTP))? + TRUE:FALSE; /* http proxy or not */ + + /* Default protocol-independent behavior doesn't support persistent + connections, so we set this to force-close. Protocols that support + this need to set this to FALSE in their "curl_do" functions. */ + conn->bits.close = TRUE; + + conn->readchannel_inuse = FALSE; + conn->writechannel_inuse = FALSE; + + /* Initialize the pipeline lists */ + conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + + /* Store creation time to help future close decision making */ + conn->created = Curl_tvnow(); + + data->reqdata.use_range = data->set.set_range?TRUE:FALSE; /* range status */ + + data->reqdata.range = data->set.set_range; /* clone the range setting */ + data->reqdata.resume_from = data->set.set_resume_from; + + conn->bits.user_passwd = data->set.userpwd?1:0; + conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; + conn->bits.no_body = data->set.opt_no_body; + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; + conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; + conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + + /* This initing continues below, see the comment "Continue connectdata + * initialization here" */ + + /*********************************************************** + * We need to allocate memory to store the path in. We get the size of the + * full URL to be sure, and we need to make it at least 256 bytes since + * other parts of the code will rely on this fact + ***********************************************************/ +#define LEAST_PATH_ALLOC 256 + urllen=strlen(data->change.url); + if(urllen < LEAST_PATH_ALLOC) + urllen=LEAST_PATH_ALLOC; + + if (!data->set.source_url /* 3rd party FTP */ + && data->reqdata.pathbuffer) { + /* Free the old buffer */ + free(data->reqdata.pathbuffer); + } + + /* + * We malloc() the buffers below urllen+2 to make room for to possibilities: + * 1 - an extra terminating zero + * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) */ + data->reqdata.pathbuffer=(char *)malloc(urllen+2); + if(NULL == data->reqdata.pathbuffer) + return CURLE_OUT_OF_MEMORY; /* really bad error */ + data->reqdata.path = data->reqdata.pathbuffer; + + conn->host.rawalloc=(char *)malloc(urllen+2); + if(NULL == conn->host.rawalloc) + return CURLE_OUT_OF_MEMORY; + + conn->host.name = conn->host.rawalloc; + conn->host.name[0] = 0; + + result = ParseURLAndFillConnection(data, conn); + if (result != CURLE_OK) { + return result; + } + /************************************************************* * Take care of proxy authentication stuff *************************************************************/ @@ -3087,14 +3330,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, * server, we just fail since we can't rewind the file writing from within * this function. ***********************************************************/ - if(conn->resume_from) { - if(!conn->bits.use_range) { + if(data->reqdata.resume_from) { + if(!data->reqdata.use_range) { /* if it already was in use, we just skip this */ - conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from); - if(!conn->range) + data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", data->reqdata.resume_from); + if(!data->reqdata.range) return CURLE_OUT_OF_MEMORY; - conn->bits.rangestringalloc = TRUE; /* mark as allocated */ - conn->bits.use_range = 1; /* switch on range usage */ + data->reqdata.rangestringalloc = TRUE; /* mark as allocated */ + data->reqdata.use_range = 1; /* switch on range usage */ } } #endif @@ -3160,7 +3403,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = port; conn->remote_port = (unsigned short)port; - conn->protocol |= PROT_FTP; + conn->protocol |= PROT_FTP|PROT_CLOSEACTION; if(data->change.proxy && *data->change.proxy && @@ -3188,11 +3431,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_disconnect = Curl_ftp_disconnect; } - conn->path++; /* don't include the initial slash */ + data->reqdata.path++; /* don't include the initial slash */ /* FTP URLs support an extension like ";type=" that * we'll try to get now! */ - type=strstr(conn->path, ";type="); + type=strstr(data->reqdata.path, ";type="); if(!type) { type=strstr(conn->host.rawalloc, ";type="); } @@ -3272,8 +3515,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Setup a "faked" transfer that'll do nothing */ if(CURLE_OK == result) { conn->bits.tcpconnect = TRUE; /* we are "connected */ - result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ + result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ + -1, NULL); /* no upload */ } return result; @@ -3294,7 +3537,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_done = Curl_tftp_done; /* TFTP URLs support an extension like ";mode=" that * we'll try to get now! */ - type=strstr(conn->path, ";mode="); + type=strstr(data->reqdata.path, ";mode="); if(!type) { type=strstr(conn->host.rawalloc, ";mode="); } @@ -3580,7 +3823,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, char *url; url = aprintf("http://%s:%d%s", conn->host.name, conn->remote_port, - conn->path); + data->reqdata.path); if(!url) return CURLE_OUT_OF_MEMORY; @@ -3704,6 +3947,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn = conn_temp; /* use this connection from now on */ + conn->data = old_conn->data; + /* get the user+password information from the old_conn struct since it may * be new for this request even when we re-use an existing connection */ conn->bits.user_passwd = old_conn->bits.user_passwd; @@ -3740,23 +3985,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (!conn->bits.httpproxy) free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ - 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 */ conn->bits.chunk = FALSE; /* always assume not chunked unless told otherwise */ - conn->maxdownload = -1; /* might have been used previously! */ Curl_safefree(old_conn->user); Curl_safefree(old_conn->passwd); Curl_safefree(old_conn->proxyuser); Curl_safefree(old_conn->proxypasswd); - - if(old_conn->bits.rangestringalloc) - free(old_conn->range); + Curl_llist_destroy(old_conn->send_pipe, NULL); + Curl_llist_destroy(old_conn->recv_pipe, NULL); free(old_conn); /* we don't need this anymore */ @@ -3764,28 +4003,29 @@ static CURLcode CreateConnection(struct SessionHandle *data, * If we're doing a resumed transfer, we need to setup our stuff * properly. */ - conn->resume_from = data->set.set_resume_from; - if (conn->resume_from) { - if (conn->bits.rangestringalloc == TRUE) - free(conn->range); - conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from); - if(!conn->range) + data->reqdata.resume_from = data->set.set_resume_from; + if (data->reqdata.resume_from) { + if (data->reqdata.rangestringalloc == TRUE) + free(data->reqdata.range); + data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", + data->reqdata.resume_from); + if(!data->reqdata.range) return CURLE_OUT_OF_MEMORY; /* tell ourselves to fetch this range */ - conn->bits.use_range = TRUE; /* enable range download */ - conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ + data->reqdata.use_range = TRUE; /* enable range download */ + data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */ } 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.set_range); - if(!conn->range) + data->reqdata.range = strdup(data->set.set_range); + if(!data->reqdata.range) return CURLE_OUT_OF_MEMORY; - conn->bits.rangestringalloc = TRUE; /* mark range string allocated */ - conn->bits.use_range = TRUE; /* enable range download */ + data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */ + data->reqdata.use_range = TRUE; /* enable range download */ } else - conn->bits.use_range = FALSE; /* disable range download */ + data->reqdata.use_range = FALSE; /* disable range download */ *in_connect = conn; /* return this instead! */ @@ -3801,7 +4041,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, ConnectionStore(data, conn); } - /* Continue connectdata initialization here. + /* Continue connectdata initialization here. */ + + /* * * Inherit the proper values from the urldata struct AFTER we have arranged * the persistent connection stuff */ @@ -3877,20 +4119,20 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* we'll need to clear conn->dns_entry later in Curl_disconnect() */ if (conn->bits.httpproxy) - fix_hostname(conn, &conn->host); + fix_hostname(data, conn, &conn->host); } else { /* this is a fresh connect */ /* set a pointer to the hostname we display */ - fix_hostname(conn, &conn->host); + fix_hostname(data, conn, &conn->host); if(!data->change.proxy || !*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 */ - /* Resolve target host right now */ + /* Resolve target host right on */ rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr); if(rc == CURLRESOLV_PENDING) *async = TRUE; @@ -3905,7 +4147,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* This is a proxy that hasn't been resolved yet. */ /* IDN-fix the proxy name */ - fix_hostname(conn, &conn->proxy); + fix_hostname(data, conn, &conn->proxy); /* resolve proxy */ rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr); @@ -3973,14 +4215,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, * * NOTE: the argument 'hostaddr' is NULL when this function is called for a * re-used connection. + * + * conn->data MUST already have been setup fine (in CreateConnection) */ static CURLcode SetupConnection(struct connectdata *conn, struct Curl_dns_entry *hostaddr, bool *protocol_done) { - struct SessionHandle *data = conn->data; CURLcode result=CURLE_OK; + struct SessionHandle *data = conn->data; Curl_pgrsTime(data, TIMER_NAMELOOKUP); @@ -4007,8 +4251,6 @@ static CURLcode SetupConnection(struct connectdata *conn, } } - conn->bytecount = 0; - conn->headerbytecount = 0; #ifdef CURL_DO_LINEEND_CONV data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ #endif /* CURL_DO_LINEEND_CONV */ @@ -4017,7 +4259,7 @@ static CURLcode SetupConnection(struct connectdata *conn, bool connected = FALSE; /* Connect only if not already connected! */ - result = ConnectPlease(conn, hostaddr, &connected); + result = ConnectPlease(data, conn, hostaddr, &connected); if(connected) { result = Curl_protocol_connect(conn, protocol_done); @@ -4088,6 +4330,9 @@ CURLcode Curl_connect(struct SessionHandle *data, Curl_disconnect(*in_connect); /* close the connection */ *in_connect = NULL; /* return a NULL */ } + } else { + if ((*in_connect)->is_in_pipeline) + data->state.is_in_pipeline = TRUE; } return code; @@ -4125,7 +4370,7 @@ CURLcode Curl_done(struct connectdata **connp, { CURLcode result; struct connectdata *conn = *connp; - struct SessionHandle *data=conn->data; + struct SessionHandle *data = conn->data; Curl_expire(data, 0); /* stop timer */ @@ -4135,9 +4380,16 @@ CURLcode Curl_done(struct connectdata **connp, conn->bits.done = TRUE; /* called just now! */ /* cleanups done even if the connection is re-used */ - if(conn->bits.rangestringalloc) { - free(conn->range); - conn->bits.rangestringalloc = FALSE; + + if(data->reqdata.rangestringalloc) { + free(data->reqdata.range); + data->reqdata.rangestringalloc = FALSE; + } + + /* Cleanup possible redirect junk */ + if(data->reqdata.newurl) { + free(data->reqdata.newurl); + data->reqdata.newurl = NULL; } if(conn->dns_entry) { @@ -4145,12 +4397,6 @@ CURLcode Curl_done(struct connectdata **connp, conn->dns_entry = NULL; } - /* Cleanup possible redirect junk */ - if(conn->newurl) { - free(conn->newurl); - conn->newurl = NULL; - } - /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) result = conn->curl_done(conn, status); @@ -4188,6 +4434,8 @@ CURLcode Curl_done(struct connectdata **connp, infof(data, "Connection #%ld to host %s left intact\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); + + ConnectionDone(conn); /* the connection is no longer in use */ } return result; @@ -4197,7 +4445,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) { CURLcode result=CURLE_OK; struct connectdata *conn = *connp; - struct SessionHandle *data=conn->data; + struct SessionHandle *data = conn->data; conn->bits.done = FALSE; /* Curl_done() is not called yet */ conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ -- cgit v1.2.1 From 1dec17562f6527f2a5ed9fe8958911d87ea6879c Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Fri, 8 Sep 2006 13:06:41 +0000 Subject: signal() returns 'void (*)(int)'. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b5e987725..e26e47503 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3054,7 +3054,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, bool keep_copysig=FALSE; /* did copy it? */ #else #ifdef HAVE_SIGNAL - void *keep_sigact; /* store the old handler here */ + void (*keep_sigact)(int); /* store the old handler here */ #endif /* HAVE_SIGNAL */ #endif /* HAVE_SIGACTION */ #endif /* SIGALRM */ -- cgit v1.2.1 From fb8d9b6645a38aee05b4aa459ce931e623a41b50 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Sat, 9 Sep 2006 19:11:54 +0000 Subject: #ifdef around alarmfunc() to supress warning. --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e26e47503..3f3852497 100644 --- a/lib/url.c +++ b/lib/url.c @@ -172,6 +172,8 @@ static void conn_free(struct connectdata *conn); #ifdef HAVE_SIGSETJMP extern sigjmp_buf curl_jmpenv; #endif + +#ifdef SIGALARM static RETSIGTYPE alarmfunc(int sig) { @@ -183,6 +185,7 @@ RETSIGTYPE alarmfunc(int sig) return; } #endif +#endif /* SIGALRM */ #endif /* USE_ARES */ void Curl_safefree(void *ptr) -- cgit v1.2.1 From 690888cfc107c16980785195ca9e05acba51593a Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Sat, 9 Sep 2006 19:13:13 +0000 Subject: SIGALARM -> SIGALRM. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f3852497..7f42474c4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -173,7 +173,7 @@ static void conn_free(struct connectdata *conn); extern sigjmp_buf curl_jmpenv; #endif -#ifdef SIGALARM +#ifdef SIGALRM static RETSIGTYPE alarmfunc(int sig) { -- cgit v1.2.1 From 8240cea628cfcfdd962d1dfa4ae40e27ed2e9bfb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 10 Sep 2006 22:15:32 +0000 Subject: Jeff Pohlmeyer presented a *multi_socket()-using program that exposed a problem with it (SIGSEGV-style). It clearly showed that the existing socket-state and state-difference function wasn't good enough so I rewrote it and could then re-run Jeff's program without any crash. The previous version clearly could miss to tell the application when a handle changed from using one socket to using another. While I was at it (as I could use this as a means to track this problem down), I've now added a 'magic' number to the easy handle struct that is inited at curl_easy_init() time and cleared at curl_easy_cleanup() time that we can use internally to detect that an easy handle seems to be fine, or at least not closed or freed (freeing in debug builds fill the area with 0x13 bytes but in normal builds we can of course not assume any particular data in the freed areas). --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7f42474c4..46aee6650 100644 --- a/lib/url.c +++ b/lib/url.c @@ -214,6 +214,8 @@ CURLcode Curl_close(struct SessionHandle *data) { struct Curl_multi *m = data->multi; + data->magic = 0; /* force a clear */ + if(m) /* This handle is still part of a multi handle, take care of this first and detach this handle from there. */ @@ -374,6 +376,8 @@ CURLcode Curl_open(struct SessionHandle **curl) /* this is a very serious error */ return CURLE_OUT_OF_MEMORY; + data->magic = CURLEASY_MAGIC_NUMBER; + #ifdef USE_ARES if(ARES_SUCCESS != ares_init(&data->state.areschannel)) { free(data); -- cgit v1.2.1 From c30e908034dec008990d58759dd28d3cdbef536b Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 10 Sep 2006 23:37:42 +0000 Subject: Compiler warning fix --- lib/url.c | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 46aee6650..6e170d3ef 100644 --- a/lib/url.c +++ b/lib/url.c @@ -490,7 +490,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, Curl_global_host_cache_init(); } - data->set.global_dns_cache = use_cache; + data->set.global_dns_cache = (bool)(0 != use_cache); } break; case CURLOPT_SSL_CIPHER_LIST: @@ -561,33 +561,33 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * When this transfer is done, it must not be left to be reused by a * subsequent transfer but shall be closed immediately. */ - data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE; + data->set.reuse_forbid = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FRESH_CONNECT: /* * This transfer shall not use a previously cached connection but * should be made with a fresh new connect! */ - data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE; + data->set.reuse_fresh = (bool)(0 != va_arg(param, long)); 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->set.verbose = va_arg(param, long)?TRUE:FALSE; + data->set.verbose = = (bool)(0 != va_arg(param, long)); break; case CURLOPT_HEADER: /* * Set to include the header in the general data output stream. */ - data->set.include_header = va_arg(param, long)?TRUE:FALSE; + data->set.include_header = (bool)(0 != va_arg(param, long)); break; case CURLOPT_NOPROGRESS: /* * Shut off the internal supported progress meter */ - data->set.hide_progress = va_arg(param, long)?TRUE:FALSE; + data->set.hide_progress = (bool)(0 != va_arg(param, long)); if(data->set.hide_progress) data->progress.flags |= PGRS_HIDE; else @@ -597,7 +597,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Do not include the body part in the output data stream. */ - data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE; + data->set.opt_no_body = (bool)(0 != va_arg(param, long)); if(data->set.opt_no_body) /* in HTTP lingo, this means using the HEAD request */ data->set.httpreq = HTTPREQ_HEAD; @@ -607,7 +607,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Don't output the >=300 error code HTML-page, but instead only * return error. */ - data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE; + data->set.http_fail_on_error = (bool)(0 != va_arg(param, long)); break; case CURLOPT_UPLOAD: case CURLOPT_PUT: @@ -615,7 +615,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * We want to sent data to the remote host. If this is HTTP, that equals * using the PUT request. */ - data->set.upload = va_arg(param, long)?TRUE:FALSE; + data->set.upload = (bool)(0 != va_arg(param, long)); if(data->set.upload) /* If this is HTTP, PUT is what's needed to "upload" */ data->set.httpreq = HTTPREQ_PUT; @@ -625,14 +625,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Try to get the file time of the remote document. The time will * later (possibly) become available using curl_easy_getinfo(). */ - data->set.get_filetime = va_arg(param, long)?TRUE:FALSE; + data->set.get_filetime = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FTP_CREATE_MISSING_DIRS: /* * An FTP option that modifies an upload to create missing directories on * the server. */ - data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE; + data->set.ftp_create_missing_dirs = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FTP_RESPONSE_TIMEOUT: /* @@ -646,13 +646,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * An FTP option that changes the command to one that asks for a list * only, no file info details. */ - data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE; + data->set.ftp_list_only = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FTPAPPEND: /* * We want to upload and append to an existing (FTP) file. */ - data->set.ftp_append = va_arg(param, long)?TRUE:FALSE; + data->set.ftp_append = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FTP_FILEMETHOD: /* @@ -679,7 +679,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * * Transfer using ASCII (instead of BINARY). */ - data->set.prefer_ascii = va_arg(param, long)?TRUE:FALSE; + data->set.prefer_ascii = (bool)(0 != va_arg(param, long)); break; case CURLOPT_TIMECONDITION: /* @@ -708,7 +708,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Switch on automatic referer that gets set if curl follows locations. */ - data->set.http_auto_referer = va_arg(param, long)?1:0; + data->set.http_auto_referer = (bool)(0 != va_arg(param, long)); break; case CURLOPT_ENCODING: @@ -730,7 +730,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Follow Location: header hints on a HTTP-server. */ - data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE; + data->set.http_follow_location = (bool)(0 != va_arg(param, long)); break; case CURLOPT_UNRESTRICTED_AUTH: @@ -739,7 +739,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * hostname changed. */ data->set.http_disable_hostname_check_before_authentication = - va_arg(param, long)?TRUE:FALSE; + (bool)(0 != va_arg(param, long)); break; case CURLOPT_MAXREDIRS: @@ -884,7 +884,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * We run mostly with the original cookie spec, as hardly anyone implements * anything else. */ - data->set.cookiesession = (bool)va_arg(param, long); + data->set.cookiesession = (bool)(0 != va_arg(param, long)); break; case CURLOPT_COOKIELIST: @@ -949,7 +949,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Tunnel operations through the proxy instead of normal proxy use */ - data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE; + data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long)); break; case CURLOPT_CUSTOMREQUEST: @@ -1061,11 +1061,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_FTP_USE_EPRT: - data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE; + data->set.ftp_use_eprt = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FTP_USE_EPSV: - data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE; + data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FTP_SKIP_PASV_IP: @@ -1073,7 +1073,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the * bypass of the IP address in PASV responses. */ - data->set.ftp_skip_ip = (bool)va_arg(param, long); + data->set.ftp_skip_ip = (bool)(0 != va_arg(param, long)); break; case CURLOPT_INFILE: @@ -1353,7 +1353,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Kludgy option to enable CRLF conversions. Subject for removal. */ - data->set.crlf = va_arg(param, long)?TRUE:FALSE; + data->set.crlf = (bool)(0 != va_arg(param, long)); break; case CURLOPT_INTERFACE: @@ -1445,7 +1445,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * The application asks not to set any signal() or alarm() handlers, * even when using a timeout. */ - data->set.no_signal = va_arg(param, long) ? TRUE : FALSE; + data->set.no_signal = (bool)(0 != va_arg(param, long)); break; case CURLOPT_SHARE: @@ -1559,7 +1559,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Enable or disable TCP_NODELAY, which will disable/enable the Nagle * algorithm */ - data->set.tcp_nodelay = (bool)va_arg(param, long); + data->set.tcp_nodelay = (bool)(0 != va_arg(param, long)); break; /*********** 3rd party transfer options ***********/ @@ -1604,14 +1604,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_IGNORE_CONTENT_LENGTH: - data->set.ignorecl = va_arg(param, long)?TRUE:FALSE; + data->set.ignorecl = (bool)(0 != va_arg(param, long)); break; case CURLOPT_CONNECT_ONLY: /* * No data transfer, set up connection and let application use the socket */ - data->set.connect_only = va_arg(param, long)?TRUE:FALSE; + data->set.connect_only = (bool)(0 != va_arg(param, long)); break; case CURLOPT_FTP_ALTERNATIVE_TO_USER: @@ -2788,7 +2788,7 @@ static bool tld_check_name(struct SessionHandle *data, ); if (uc_name) idn_free(uc_name); - return (rc == TLD_SUCCESS); + return (bool)(rc == TLD_SUCCESS); } #endif -- cgit v1.2.1 From 055022a55fedb0a1a5c299d4ba59ed5620025928 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 10 Sep 2006 23:45:54 +0000 Subject: Compiler warning fix --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6e170d3ef..3f479ed22 100644 --- a/lib/url.c +++ b/lib/url.c @@ -575,7 +575,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Verbose means infof() calls that give a lot of information about * the connection and transfer procedures as well as internal choices. */ - data->set.verbose = = (bool)(0 != va_arg(param, long)); + data->set.verbose = (bool)(0 != va_arg(param, long)); break; case CURLOPT_HEADER: /* -- cgit v1.2.1 From 5c184cfc0d71a928b28ace2778bbe5064917f4da Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Sep 2006 11:25:47 +0000 Subject: stupid mistake rectified by Jeff Pohlmeyer --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f479ed22..e9c4e5f9f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1688,9 +1688,10 @@ static void conn_free(struct connectdata *conn) CURLcode Curl_disconnect(struct connectdata *conn) { - struct SessionHandle *data = conn->data; + struct SessionHandle *data; if(!conn) return CURLE_OK; /* this is closed and fine already */ + data = conn->data; #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ -- cgit v1.2.1 From 29dc39fce1126265d8526be15beec3e3fdc1c11d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Sep 2006 17:18:18 +0000 Subject: - Fixed my breakage from earlier today so that doing curl_easy_cleanup() on a handle that is part of a multi handle first removes the handle from the stack. - Added CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid to disable SSL session-ID re-use on demand since there obviously are broken servers out there that misbehave with session-IDs used. --- lib/url.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e9c4e5f9f..14def325a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -214,13 +214,15 @@ CURLcode Curl_close(struct SessionHandle *data) { struct Curl_multi *m = data->multi; - data->magic = 0; /* force a clear */ - if(m) /* This handle is still part of a multi handle, take care of this first and detach this handle from there. */ Curl_multi_rmeasy(data->multi, data); + data->magic = 0; /* force a clear AFTER the possibly enforced removal from + the multi handle, since that function uses the magic + field! */ + if(data->state.connc && (data->state.connc->type == CONNCACHE_PRIVATE)) { /* close all connections still alive that are in the private connection cache, as we no longer have the pointer left to the shared one. */ @@ -455,6 +457,7 @@ CURLcode Curl_open(struct SessionHandle **curl) */ data->set.ssl.verifypeer = TRUE; data->set.ssl.verifyhost = 2; + data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */ #ifdef CURL_CA_BUNDLE /* This is our preferred CA cert bundle since install time */ data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; @@ -1632,6 +1635,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.sockopt_client = va_arg(param, void *); break; + case CURLOPT_SSL_SESSIONID_CACHE: + data->set.ssl.sessionid = va_arg(param, long)?TRUE:FALSE; + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 7c5745720aca27f38dc875a39d43cc3aba189471 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Sep 2006 20:50:58 +0000 Subject: If the current connection doesn't fit to get added to the connection cache, we certainly MUST NOT kill an active connection... Problem tracked down thanks to Michael Wallner's excellent test program. --- lib/url.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 14def325a..e014c8ee4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2002,7 +2002,7 @@ ConnectionKillOne(struct SessionHandle *data) for(i=0; data->state.connc && (i< data->state.connc->num); i++) { conn = data->state.connc->connects[i]; - if(!conn) + if(!conn || conn->inuse) continue; /* @@ -2078,7 +2078,10 @@ ConnectionStore(struct SessionHandle *data, if(i == data->state.connc->num) { /* there was no room available, kill one */ i = ConnectionKillOne(data); - infof(data, "Connection (#%d) was killed to make room\n", i); + if(-1 != i) + infof(data, "Connection (#%d) was killed to make room\n", i); + else + infof(data, "This connection did not fit in the connection cache\n"); } conn->connectindex = i; /* Make the child know where the pointer to this -- cgit v1.2.1 From 733a184ce0747c65fbc634e066cfac0ffae43d80 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 12 Sep 2006 23:51:01 +0000 Subject: Compiler warning fix --- lib/url.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e014c8ee4..641d3bf30 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1060,7 +1060,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Use FTP PORT, this also specifies which IP address to use */ data->set.ftpport = va_arg(param, char *); - data->set.ftp_use_port = data->set.ftpport?1:0; + data->set.ftp_use_port = (bool)(NULL != data->set.ftpport); break; case CURLOPT_FTP_USE_EPRT: @@ -1383,7 +1383,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * A string that defines the krb4 security level. */ data->set.krb4_level = va_arg(param, char *); - data->set.krb4=data->set.krb4_level?TRUE:FALSE; + data->set.krb4 = (bool)(NULL != data->set.krb4_level); break; case CURLOPT_SSL_VERIFYPEER: /* @@ -1571,7 +1571,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * SOURCE URL */ data->set.source_url = va_arg(param, char *); - data->set.printhost = (data->set.source_url != NULL); + data->set.printhost = (bool)(NULL != data->set.source_url); break; case CURLOPT_SOURCE_USERPWD: @@ -1636,7 +1636,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_SSL_SESSIONID_CACHE: - data->set.ssl.sessionid = va_arg(param, long)?TRUE:FALSE; + data->set.ssl.sessionid = (bool)(0 != va_arg(param, long)); break; default: @@ -1842,7 +1842,7 @@ bool Curl_isHandleAtHead(struct SessionHandle *handle, { struct curl_llist_element *curr = pipe->head; if (curr) { - return curr->ptr == handle ? TRUE : FALSE; + return (bool)(curr->ptr == handle); } return FALSE; @@ -3111,9 +3111,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->connectindex = -1; /* no index */ - conn->bits.httpproxy = (data->change.proxy && *data->change.proxy && - (data->set.proxytype == CURLPROXY_HTTP))? - TRUE:FALSE; /* http proxy or not */ + + conn->bits.httpproxy = (bool)(data->change.proxy /* http proxy or not */ + && *data->change.proxy + && (data->set.proxytype == CURLPROXY_HTTP)); /* Default protocol-independent behavior doesn't support persistent connections, so we set this to force-close. Protocols that support @@ -3130,13 +3131,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); - data->reqdata.use_range = data->set.set_range?TRUE:FALSE; /* range status */ + /* range status */ + data->reqdata.use_range = (bool)(NULL != data->set.set_range); data->reqdata.range = data->set.set_range; /* clone the range setting */ data->reqdata.resume_from = data->set.set_resume_from; - conn->bits.user_passwd = data->set.userpwd?1:0; - conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0; + conn->bits.user_passwd = (bool)(NULL != data->set.userpwd); + conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd); conn->bits.no_body = data->set.opt_no_body; conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; -- cgit v1.2.1 From 7d3e719a2ccdaeb79a62aaf2243f93c9855008ef Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 13 Sep 2006 12:42:12 +0000 Subject: Compiler warning fix --- lib/url.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 641d3bf30..3b677f7fd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4070,15 +4070,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->fread = data->set.fread; conn->fread_in = data->set.in; - conn->bits.upload_chunky = - ((conn->protocol&PROT_HTTP) && - data->set.upload && - (data->set.infilesize == -1) && - (data->set.httpversion != CURL_HTTP_VERSION_1_0))? + if ((conn->protocol&PROT_HTTP) && + data->set.upload && + (data->set.infilesize == -1) && + (data->set.httpversion != CURL_HTTP_VERSION_1_0)) { /* HTTP, upload, unknown file size and not HTTP 1.0 */ - TRUE: - /* else, no chunky upload */ - FALSE; + conn->bits.upload_chunky = TRUE; + } + else { + /* else, no chunky upload */ + conn->bits.upload_chunky = FALSE; + } #ifndef USE_ARES /************************************************************* -- cgit v1.2.1 From 39e01e9349c0ea9c9a4f0938d97ba301ef543439 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 15 Sep 2006 08:47:55 +0000 Subject: file-local function should be static and not use Curl_ prefix! Curl_signalPipeClose is now signalPipeClose(). --- lib/url.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3b677f7fd..f3d21e869 100644 --- a/lib/url.c +++ b/lib/url.c @@ -159,6 +159,8 @@ static long ConnectionStore(struct SessionHandle *data, static bool IsPipeliningPossible(struct SessionHandle *handle); static void conn_free(struct connectdata *conn); +static void signalPipeClose(struct curl_llist *pipe); + #define MAX_PIPELINE_LENGTH 5 #ifndef USE_ARES @@ -1761,8 +1763,8 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_ssl_close(conn); /* Indicate to all handles on the pipe that we're dead */ - Curl_signalPipeClose(conn->send_pipe); - Curl_signalPipeClose(conn->recv_pipe); + signalPipeClose(conn->send_pipe); + signalPipeClose(conn->recv_pipe); conn_free(conn); @@ -1848,7 +1850,7 @@ bool Curl_isHandleAtHead(struct SessionHandle *handle, return FALSE; } -void Curl_signalPipeClose(struct curl_llist *pipe) +static void signalPipeClose(struct curl_llist *pipe) { struct curl_llist_element *curr; -- cgit v1.2.1 From 2d5fc39d3573c10a460cdeb2139631da62b8e391 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 16 Sep 2006 21:50:29 +0000 Subject: Resize the connection cache upwards when adding more handles than what currently fits in the cache, to make the cache work better especially for pipelining cases but also for "mere" (persistent) connection re-use. --- lib/url.c | 85 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 40 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f3d21e869..3f59299be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -346,6 +346,49 @@ struct conncache *Curl_mk_connc(int type) return c; } +/* Change number of entries of a connection cache */ +CURLcode Curl_ch_connc(struct SessionHandle *data, + struct conncache *c, + long newamount) +{ + int i; + struct connectdata **newptr; + + if(newamount < c->num) { + /* 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! + + NOTE: for conncache_multi cases we must make sure that we only + close handles not in use. + */ + for(i=newamount; i< c->num; i++) + Curl_disconnect(c->connects[i]); + + /* If the most recent connection is no longer valid, mark it + invalid. */ + if(data->state.lastconnect <= newamount) + data->state.lastconnect = -1; + } + if(newamount > 0) { + newptr= (struct connectdata **) + realloc(c->connects, sizeof(struct connectdata *) * newamount); + if(!newptr) + /* we closed a few connections in vain, but so what? */ + return CURLE_OUT_OF_MEMORY; + + /* nullify the newly added pointers */ + for(i=c->num; iconnects = newptr; + c->num = newamount; + } + /* we no longer support less than 1 as size for the connection cache, and + I'm not sure it ever worked to set it to zero */ + return CURLE_OK; +} + /* Free a connection cache. This is called from Curl_close() and curl_multi_cleanup(). */ void Curl_rm_connc(struct conncache *c) @@ -521,45 +564,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set the absolute number of maximum simultaneous alive connection that * libcurl is allowed to have. */ - { - long newconnects= va_arg(param, long); - struct connectdata **newptr; - long i; - - if(newconnects < data->state.connc->num) { - /* 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! - - NOTE: for conncache_multi cases we must make sure that we only - close handles not in use. - */ - for(i=newconnects; i< data->state.connc->num; i++) - Curl_disconnect(data->state.connc->connects[i]); - - /* If the most recent connection is no longer valid, mark it - invalid. */ - if(data->state.lastconnect <= newconnects) - data->state.lastconnect = -1; - } - if(newconnects > 0) { - newptr= (struct connectdata **) - realloc(data->state.connc->connects, - sizeof(struct connectdata *) * newconnects); - if(!newptr) - /* we closed a few connections in vain, but so what? */ - return CURLE_OUT_OF_MEMORY; - - /* nullify the newly added pointers */ - for(i=data->state.connc->num; istate.connc->connects = newptr; - data->state.connc->num = newconnects; - } - /* we no longer support less than 1 as size for the connection cache, - and I'm not sure it ever worked to set it to zero */ - } + result = Curl_ch_connc(data, data->state.connc, va_arg(param, long)); break; case CURLOPT_FORBID_REUSE: /* @@ -3115,7 +3120,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->connectindex = -1; /* no index */ conn->bits.httpproxy = (bool)(data->change.proxy /* http proxy or not */ - && *data->change.proxy + && *data->change.proxy && (data->set.proxytype == CURLPROXY_HTTP)); /* Default protocol-independent behavior doesn't support persistent -- cgit v1.2.1 From 71920d61e6c0f38f91a7ba471505de031d568ff7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Sep 2006 12:03:50 +0000 Subject: Michael Wallner's test program again help me track down a problem. This time it basically was that we didn't remove the current connection from the pipe list when following a redirect. Also in this commit: several cases of additional debug code for debug builds helping to check and track down some signs of run-time trouble. --- lib/url.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f59299be..71a827e7a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -216,6 +216,49 @@ CURLcode Curl_close(struct SessionHandle *data) { struct Curl_multi *m = data->multi; +#ifdef CURLDEBUG + /* only for debugging, scan through all connections and see if there's a + pipe reference still identifying this handle */ + + if(data->state.is_in_pipeline) + fprintf(stderr, "CLOSED when in pipeline!\n"); + + if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) { + struct conncache *c = data->state.connc; + int i; + struct curl_llist *pipe; + struct curl_llist_element *curr; + struct connectdata *connptr; + + for(i=0; i< c->num; i++) { + connptr = c->connects[i]; + if(!connptr) + continue; + + pipe = connptr->send_pipe; + if(pipe) { + for (curr = pipe->head; curr; curr=curr->next) { + if(data == (struct SessionHandle *) curr->ptr) { + fprintf(stderr, + "MAJOR problem we %p are still in send pipe for %p done %d\n", + data, connptr, connptr->bits.done); + } + } + } + pipe = connptr->recv_pipe; + if(pipe) { + for (curr = pipe->head; curr; curr=curr->next) { + if(data == (struct SessionHandle *) curr->ptr) { + fprintf(stderr, + "MAJOR problem we %p are still in recv pipe for %p done %d\n", + data, connptr, connptr->bits.done); + } + } + } + } + } +#endif + if(m) /* This handle is still part of a multi handle, take care of this first and detach this handle from there. */ @@ -1707,6 +1750,11 @@ CURLcode Curl_disconnect(struct connectdata *conn) return CURLE_OK; /* this is closed and fine already */ data = conn->data; + if(!data) { + DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n")); + return CURLE_OK; + } + #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, @@ -1805,12 +1853,17 @@ static bool IsPipeliningPossible(struct SessionHandle *handle) return FALSE; } -void Curl_addHandleToPipeline(struct SessionHandle *handle, +void Curl_addHandleToPipeline(struct SessionHandle *data, struct curl_llist *pipe) { - Curl_llist_insert_next(pipe, - pipe->tail, - handle); +#ifdef CURLDEBUG + if(!IsPipeliningPossible(data)) { + /* when not pipelined, there MUST be no handle in the list already */ + if(pipe->head) + infof(data, "PIPE when no PIPE supposed!\n"); + } +#endif + Curl_llist_insert_next(pipe, pipe->tail, data); } @@ -1864,7 +1917,14 @@ static void signalPipeClose(struct curl_llist *pipe) struct curl_llist_element *next = curr->next; struct SessionHandle *data = (struct SessionHandle *) curr->ptr; - data->state.pipe_broke = TRUE; +#ifdef CURLDEBUG /* debug-only code */ + if(data->magic != CURLEASY_MAGIC_NUMBER) { + /* MAJOR BADNESS */ + fprintf(stderr, "signalPipeClose() found BAAD easy handle\n"); + } + else +#endif + data->state.pipe_broke = TRUE; Curl_llist_remove(pipe, curr, NULL); curr = next; @@ -2062,7 +2122,7 @@ ConnectionDone(struct connectdata *conn) if (conn->send_pipe == 0 && conn->recv_pipe == 0) - conn->is_in_pipeline = FALSE; + conn->is_in_pipeline = FALSE; } /* @@ -2086,7 +2146,8 @@ ConnectionStore(struct SessionHandle *data, /* there was no room available, kill one */ i = ConnectionKillOne(data); if(-1 != i) - infof(data, "Connection (#%d) was killed to make room\n", i); + infof(data, "Connection (#%d) was killed to make room (holds %d)\n", + i, data->state.connc->num); else infof(data, "This connection did not fit in the connection cache\n"); } @@ -3541,7 +3602,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Setup a "faked" transfer that'll do nothing */ if(CURLE_OK == result) { + conn->data = data; conn->bits.tcpconnect = TRUE; /* we are "connected */ + ConnectionStore(data, conn); + result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ -1, NULL); /* no upload */ } @@ -4438,6 +4502,8 @@ CURLcode Curl_done(struct connectdata **connp, cancelled before we proceed */ ares_cancel(data->state.areschannel); + ConnectionDone(conn); /* the connection is no longer in use */ + /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this no matter what we think. @@ -4463,8 +4529,6 @@ CURLcode Curl_done(struct connectdata **connp, infof(data, "Connection #%ld to host %s left intact\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); - - ConnectionDone(conn); /* the connection is no longer in use */ } return result; -- cgit v1.2.1 From ec4a16f2e01b0b92e16fc841bc676394f37022f1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Sep 2006 21:49:41 +0000 Subject: Armel Asselin fixed problems when you gave a proxy URL with user name and empty password or no password at all. Test case 278 and 279 were added to verify. --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 71a827e7a..20f546900 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3698,8 +3698,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(atsign) { char proxyuser[MAX_CURL_USER_LENGTH]; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; + proxypasswd[0] = 0; - if(2 == sscanf(proxyptr, + if(1 <= sscanf(proxyptr, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", proxyuser, proxypasswd)) { -- cgit v1.2.1 From 3ea8a4d220067e27ab3b988f35b3ac7b9c27efd4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 23 Sep 2006 19:07:20 +0000 Subject: Dmitriy Sergeyev provided a patch that made the SOCKS[45] code work better as it now will read the full data sent from servers. The SOCKS-related code was also moved to the new lib/socks.c source file. --- lib/url.c | 484 +------------------------------------------------------------- 1 file changed, 7 insertions(+), 477 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 20f546900..6e5fefe10 100644 --- a/lib/url.c +++ b/lib/url.c @@ -132,6 +132,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "connect.h" #include "inet_ntop.h" #include "http_ntlm.h" +#include "socks.h" #include #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) @@ -2173,476 +2174,6 @@ ConnectionStore(struct SessionHandle *data, return i; } -/* -* This function logs in to a SOCKS4 proxy and sends the specifics to the final -* destination server. -* -* Reference : -* http://socks.permeo.com/protocol/socks4.protocol -* -* Note : -* Nonsupport "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" -* Nonsupport "Identification Protocol (RFC1413)" -*/ -static int handleSock4Proxy(const char *proxy_name, - struct SessionHandle *data, - struct connectdata *conn) -{ - unsigned char socksreq[262]; /* room for SOCKS4 request incl. user id */ - int result; - CURLcode code; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - - Curl_nonblock(sock, FALSE); - - /* - * Compose socks4 request - * - * Request format - * - * +----+----+----+----+----+----+----+----+----+----+....+----+ - * | VN | CD | DSTPORT | DSTIP | USERID |NULL| - * +----+----+----+----+----+----+----+----+----+----+....+----+ - * # of bytes: 1 1 2 4 variable 1 - */ - - socksreq[0] = 4; /* version (SOCKS4) */ - socksreq[1] = 1; /* connect */ - *((unsigned short*)&socksreq[2]) = htons(conn->remote_port); - - /* DNS resolve */ - { - struct Curl_dns_entry *dns; - Curl_addrinfo *hp=NULL; - int rc; - - rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns); - - if(rc == CURLRESOLV_ERROR) - return 1; - - if(rc == CURLRESOLV_PENDING) - /* this requires that we're in "wait for resolve" state */ - rc = Curl_wait_for_resolv(conn, &dns); - - /* - * We cannot use 'hostent' as a struct that Curl_resolv() returns. It - * returns a Curl_addrinfo pointer that may not always look the same. - */ - if(dns) - hp=dns->addr; - if (hp) { - char buf[64]; - unsigned short ip[4]; - Curl_printable_address(hp, buf, sizeof(buf)); - - if(4 == sscanf( buf, "%hu.%hu.%hu.%hu", - &ip[0], &ip[1], &ip[2], &ip[3])) { - /* Set DSTIP */ - socksreq[4] = (unsigned char)ip[0]; - socksreq[5] = (unsigned char)ip[1]; - socksreq[6] = (unsigned char)ip[2]; - socksreq[7] = (unsigned char)ip[3]; - } - else - hp = NULL; /* fail! */ - - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ - - } - if(!hp) { - failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", - conn->host.name); - return 1; - } - } - - /* - * This is currently not supporting "Identification Protocol (RFC1413)". - */ - socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ - if (proxy_name) - strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8); - - /* - * Make connection - */ - { - ssize_t actualread; - ssize_t written; - int packetsize = 9 + - (int)strlen((char*)socksreq + 8); /* size including NUL */ - - /* Send request */ - code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); - if ((code != CURLE_OK) || (written != packetsize)) { - failf(data, "Failed to send SOCKS4 connect request."); - return 1; - } - - packetsize = 8; /* receive data size */ - - /* Receive response */ - result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); - if ((result != CURLE_OK) || (actualread != packetsize)) { - failf(data, "Failed to receive SOCKS4 connect request ack."); - return 1; - } - - /* - * Response format - * - * +----+----+----+----+----+----+----+----+ - * | VN | CD | DSTPORT | DSTIP | - * +----+----+----+----+----+----+----+----+ - * # of bytes: 1 1 2 4 - * - * VN is the version of the reply code and should be 0. CD is the result - * code with one of the following values: - * - * 90: request granted - * 91: request rejected or failed - * 92: request rejected because SOCKS server cannot connect to - * identd on the client - * 93: request rejected because the client program and identd - * report different user-ids - */ - - /* wrong version ? */ - if (socksreq[0] != 0) { - failf(data, - "SOCKS4 reply has wrong version, version should be 4."); - return 1; - } - - /* Result */ - switch(socksreq[1]) - { - case 90: - infof(data, "SOCKS4 request granted.\n"); - break; - case 91: - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected or failed.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), - socksreq[1]); - return 1; - case 92: - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected because SOCKS server cannot connect to " - "identd on the client.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), - socksreq[1]); - return 1; - case 93: - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected because the client program and identd " - "report different user-ids.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), - socksreq[1]); - return 1; - default : - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", Unknown.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), - socksreq[1]); - return 1; - } - } - - Curl_nonblock(sock, TRUE); - - return 0; /* Proxy was successful! */ -} - -/* - * This function logs in to a SOCKS5 proxy and sends the specifics to the final - * destination server. - */ -static int handleSock5Proxy(const char *proxy_name, - const char *proxy_password, - struct connectdata *conn) -{ - /* - According to the RFC1928, section "6. Replies". This is what a SOCK5 - replies: - - +----+-----+-------+------+----------+----------+ - |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | - +----+-----+-------+------+----------+----------+ - | 1 | 1 | X'00' | 1 | Variable | 2 | - +----+-----+-------+------+----------+----------+ - - Where: - - o VER protocol version: X'05' - o REP Reply field: - o X'00' succeeded - */ - - unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ - ssize_t actualread; - ssize_t written; - int result; - CURLcode code; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - struct SessionHandle *data = conn->data; - long timeout; - - /* get timeout */ - if(data->set.timeout && data->set.connecttimeout) { - if (data->set.timeout < data->set.connecttimeout) - timeout = data->set.timeout*1000; - else - timeout = data->set.connecttimeout*1000; - } - else if(data->set.timeout) - timeout = data->set.timeout*1000; - else if(data->set.connecttimeout) - timeout = data->set.connecttimeout*1000; - else - timeout = DEFAULT_CONNECT_TIMEOUT; - - Curl_nonblock(sock, TRUE); - - /* wait until socket gets connected */ - result = Curl_select(CURL_SOCKET_BAD, sock, (int)timeout); - - if(-1 == result) { - failf(conn->data, "SOCKS5: no connection here"); - return 1; - } - else if(0 == result) { - failf(conn->data, "SOCKS5: connection timeout"); - return 1; - } - - if(result & CSELECT_ERR) { - failf(conn->data, "SOCKS5: error occured during connection"); - return 1; - } - - socksreq[0] = 5; /* version */ - socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */ - socksreq[2] = 0; /* no authentication */ - socksreq[3] = 2; /* username/password */ - - Curl_nonblock(sock, FALSE); - - code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), - &written); - if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) { - failf(data, "Unable to send initial SOCKS5 request."); - return 1; - } - - Curl_nonblock(sock, TRUE); - - result = Curl_select(sock, CURL_SOCKET_BAD, (int)timeout); - - if(-1 == result) { - failf(conn->data, "SOCKS5 nothing to read"); - return 1; - } - else if(0 == result) { - failf(conn->data, "SOCKS5 read timeout"); - return 1; - } - - if(result & CSELECT_ERR) { - failf(conn->data, "SOCKS5 read error occured"); - return 1; - } - - Curl_nonblock(sock, FALSE); - - result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); - if ((result != CURLE_OK) || (actualread != 2)) { - failf(data, "Unable to receive initial SOCKS5 response."); - return 1; - } - - if (socksreq[0] != 5) { - failf(data, "Received invalid version in initial SOCKS5 response."); - return 1; - } - if (socksreq[1] == 0) { - /* Nothing to do, no authentication needed */ - ; - } - else if (socksreq[1] == 2) { - /* Needs user name and password */ - size_t userlen, pwlen; - int len; - if(proxy_name && proxy_password) { - userlen = strlen(proxy_name); - pwlen = proxy_password?strlen(proxy_password):0; - } - else { - userlen = 0; - pwlen = 0; - } - - /* username/password request looks like - * +----+------+----------+------+----------+ - * |VER | ULEN | UNAME | PLEN | PASSWD | - * +----+------+----------+------+----------+ - * | 1 | 1 | 1 to 255 | 1 | 1 to 255 | - * +----+------+----------+------+----------+ - */ - len = 0; - socksreq[len++] = 1; /* username/pw subnegotiation version */ - socksreq[len++] = (char) userlen; - memcpy(socksreq + len, proxy_name, (int) userlen); - len += userlen; - socksreq[len++] = (char) pwlen; - memcpy(socksreq + len, proxy_password, (int) pwlen); - len += pwlen; - - code = Curl_write(conn, sock, (char *)socksreq, len, &written); - if ((code != CURLE_OK) || (len != written)) { - failf(data, "Failed to send SOCKS5 sub-negotiation request."); - return 1; - } - - result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread); - if ((result != CURLE_OK) || (actualread != 2)) { - failf(data, "Unable to receive SOCKS5 sub-negotiation response."); - return 1; - } - - /* ignore the first (VER) byte */ - if (socksreq[1] != 0) { /* status */ - failf(data, "User was rejected by the SOCKS5 server (%d %d).", - socksreq[0], socksreq[1]); - return 1; - } - - /* Everything is good so far, user was authenticated! */ - } - else { - /* error */ - if (socksreq[1] == 1) { - failf(data, - "SOCKS5 GSSAPI per-message authentication is not supported."); - return 1; - } - else if (socksreq[1] == 255) { - if (!proxy_name || !*proxy_name) { - failf(data, - "No authentication method was acceptable. (It is quite likely" - " that the SOCKS5 server wanted a username/password, since none" - " was supplied to the server on this connection.)"); - } - else { - failf(data, "No authentication method was acceptable."); - } - return 1; - } - else { - failf(data, - "Undocumented SOCKS5 mode attempted to be used by server."); - return 1; - } - } - - /* Authentication is complete, now specify destination to the proxy */ - socksreq[0] = 5; /* version (SOCKS5) */ - socksreq[1] = 1; /* connect */ - socksreq[2] = 0; /* must be zero */ - socksreq[3] = 1; /* IPv4 = 1 */ - - { - struct Curl_dns_entry *dns; - Curl_addrinfo *hp=NULL; - int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns); - - if(rc == CURLRESOLV_ERROR) - return 1; - - if(rc == CURLRESOLV_PENDING) - /* this requires that we're in "wait for resolve" state */ - rc = Curl_wait_for_resolv(conn, &dns); - - /* - * We cannot use 'hostent' as a struct that Curl_resolv() returns. It - * returns a Curl_addrinfo pointer that may not always look the same. - */ - if(dns) - hp=dns->addr; - if (hp) { - char buf[64]; - unsigned short ip[4]; - Curl_printable_address(hp, buf, sizeof(buf)); - - if(4 == sscanf( buf, "%hu.%hu.%hu.%hu", - &ip[0], &ip[1], &ip[2], &ip[3])) { - socksreq[4] = (unsigned char)ip[0]; - socksreq[5] = (unsigned char)ip[1]; - socksreq[6] = (unsigned char)ip[2]; - socksreq[7] = (unsigned char)ip[3]; - } - else - hp = NULL; /* fail! */ - - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ - } - if(!hp) { - failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", - conn->host.name); - return 1; - } - } - - *((unsigned short*)&socksreq[8]) = htons(conn->remote_port); - - { - const int packetsize = 10; - - code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); - if ((code != CURLE_OK) || (written != packetsize)) { - failf(data, "Failed to send SOCKS5 connect request."); - return 1; - } - - result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread); - if ((result != CURLE_OK) || (actualread != packetsize)) { - failf(data, "Failed to receive SOCKS5 connect request ack."); - return 1; - } - - if (socksreq[0] != 5) { /* version */ - failf(data, - "SOCKS5 reply has wrong version, version should be 5."); - return 1; - } - if (socksreq[1] != 0) { /* Anything besides 0 is an error */ - failf(data, - "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])), - socksreq[1]); - return 1; - } - } - - Curl_nonblock(sock, TRUE); - return 0; /* Proxy was successful! */ -} - static CURLcode ConnectPlease(struct SessionHandle *data, struct connectdata *conn, struct Curl_dns_entry *hostaddr, @@ -2673,19 +2204,18 @@ static CURLcode ConnectPlease(struct SessionHandle *data, switch(data->set.proxytype) { case CURLPROXY_SOCKS5: - return handleSock5Proxy(conn->proxyuser, - conn->proxypasswd, - conn) ? - CURLE_COULDNT_CONNECT : CURLE_OK; + result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn); + break; case CURLPROXY_HTTP: /* do nothing here. handled later. */ break; case CURLPROXY_SOCKS4: - return handleSock4Proxy(conn->proxyuser, data, conn) ? - CURLE_COULDNT_CONNECT : CURLE_OK; + result = Curl_SOCKS4(conn->proxyuser, conn); + break; default: failf(data, "unknown proxytype option given"); - return CURLE_COULDNT_CONNECT; + result = CURLE_COULDNT_CONNECT; + break; } } -- cgit v1.2.1 From ba01198e6c687337fc601f1ec7489d75e91c80ca Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 25 Sep 2006 00:05:39 +0000 Subject: Compiler warning fix --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6e5fefe10..50390108f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -395,7 +395,7 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, struct conncache *c, long newamount) { - int i; + long i; struct connectdata **newptr; if(newamount < c->num) { -- cgit v1.2.1 From ae13c93b7db9f9c68eaf95150ed551b3b649d8c4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Sep 2006 21:26:06 +0000 Subject: Reported in #1561470 (http://curl.haxx.se/bug/view.cgi?id=1561470), libcurl would crash if a bad function sequence was used when shutting down after using the multi interface (i.e using easy_cleanup after multi_cleanup) so precautions have been added to make sure it doesn't any more - test case 529 was added to verify. --- lib/url.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 50390108f..968421079 100644 --- a/lib/url.c +++ b/lib/url.c @@ -269,29 +269,31 @@ CURLcode Curl_close(struct SessionHandle *data) the multi handle, since that function uses the magic field! */ - if(data->state.connc && (data->state.connc->type == CONNCACHE_PRIVATE)) { - /* close all connections still alive that are in the private connection - cache, as we no longer have the pointer left to the shared one. */ - close_connections(data); + if(data->state.connc) { - /* free the connection cache if allocated privately */ - Curl_rm_connc(data->state.connc); - } + if(data->state.connc->type == CONNCACHE_PRIVATE) { + /* close all connections still alive that are in the private connection + cache, as we no longer have the pointer left to the shared one. */ + close_connections(data); - if ( ! (data->share && data->share->hostcache) ) { - if ( !Curl_global_host_cache_use(data)) { - Curl_hash_destroy(data->dns.hostcache); + /* free the connection cache if allocated privately */ + Curl_rm_connc(data->state.connc); } } if(data->state.shared_conn) { - /* this handle is still being used by a shared connection cache and thus - we leave it around for now */ - Curl_multi_add_closure(data->state.shared_conn, data); - + /* marked to be used by a pending connection so we can't kill this handle + just yet */ + data->state.closed = TRUE; return CURLE_OK; } + if ( ! (data->share && data->share->hostcache) ) { + if ( !Curl_global_host_cache_use(data)) { + Curl_hash_destroy(data->dns.hostcache); + } + } + /* Free the pathbuffer */ Curl_safefree(data->reqdata.pathbuffer); Curl_safefree(data->reqdata.proto.generic); -- cgit v1.2.1 From 5e0d9aea322ba3abfc05c937f91b5751768f2310 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 30 Sep 2006 20:31:11 +0000 Subject: Support for FTP third party transfers is now dropped --- lib/url.c | 42 ++++++------------------------------------ 1 file changed, 6 insertions(+), 36 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 968421079..7bcb9822c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1618,42 +1618,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.tcp_nodelay = (bool)(0 != va_arg(param, long)); break; - /*********** 3rd party transfer options ***********/ - case CURLOPT_SOURCE_URL: /* - * SOURCE URL - */ - data->set.source_url = va_arg(param, char *); - data->set.printhost = (bool)(NULL != data->set.source_url); - break; - - case CURLOPT_SOURCE_USERPWD: - /* - * Use SOURCE USER[:PASSWORD] - */ - data->set.source_userpwd = va_arg(param, char *); - break; - - case CURLOPT_SOURCE_QUOTE: - /* - * List of RAW FTP commands to use after a connect - */ - data->set.source_quote = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_SOURCE_PREQUOTE: - /* - * List of RAW FTP commands to use before a transfer on the source host - */ - data->set.source_prequote = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_SOURCE_POSTQUOTE: - /* - * List of RAW FTP commands to use after a transfer on the source host - */ - data->set.source_postquote = va_arg(param, struct curl_slist *); - break; + case CURLOPT_SOURCE_URL: + case CURLOPT_SOURCE_USERPWD: + case CURLOPT_SOURCE_QUOTE: + case CURLOPT_SOURCE_PREQUOTE: + case CURLOPT_SOURCE_POSTQUOTE: + These former 3rd party transfer options are deprecated */ case CURLOPT_FTP_ACCOUNT: data->set.ftp_account = va_arg(param, char *); @@ -1726,7 +1697,6 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->ip_addr_str); Curl_safefree(conn->trailer); - Curl_safefree(conn->sec_pathbuffer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ -- cgit v1.2.1 From a1de9367ecc17ae1d77e46b76fb1aba6c9f3ccb2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Oct 2006 06:58:05 +0000 Subject: Bogdan Nicula's second test case (posted Sun, 08 Oct 2006) converted to test case 535 and it now runs fine. Again a problem with the pipelining code not taking all possible (error) conditions into account. --- lib/url.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7bcb9822c..3e2e37179 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1840,7 +1840,7 @@ void Curl_addHandleToPipeline(struct SessionHandle *data, } -void Curl_removeHandleFromPipeline(struct SessionHandle *handle, +int Curl_removeHandleFromPipeline(struct SessionHandle *handle, struct curl_llist *pipe) { struct curl_llist_element *curr; @@ -1849,10 +1849,11 @@ void Curl_removeHandleFromPipeline(struct SessionHandle *handle, while (curr) { if (curr->ptr == handle) { Curl_llist_remove(pipe, curr, NULL); - break; + return 1; /* we removed a handle */ } curr = curr->next; } + return 0; } #if 0 @@ -3975,8 +3976,14 @@ CURLcode Curl_done(struct connectdata **connp, conn->bits.done = TRUE; /* called just now! */ - /* cleanups done even if the connection is re-used */ + if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && + conn->readchannel_inuse) + conn->readchannel_inuse--; + if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && + conn->writechannel_inuse) + conn->writechannel_inuse--; + /* cleanups done even if the connection is re-used */ if(data->reqdata.rangestringalloc) { free(data->reqdata.range); data->reqdata.rangestringalloc = FALSE; -- cgit v1.2.1 From d390039873cc7a8c22177f177511ed5dec72ee07 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Oct 2006 21:24:50 +0000 Subject: minor indent fix --- lib/url.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3e2e37179..fefab252f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3917,7 +3917,7 @@ CURLcode Curl_connect(struct SessionHandle *data, will be NULL here. Continue connecting from here */ code = SetupConnection(*in_connect, dns, protocol_done); /* else - response will be received and treated async wise */ + response will be received and treated async wise */ } if(CURLE_OK != code) { @@ -3927,9 +3927,10 @@ CURLcode Curl_connect(struct SessionHandle *data, Curl_disconnect(*in_connect); /* close the connection */ *in_connect = NULL; /* return a NULL */ } - } else { - if ((*in_connect)->is_in_pipeline) - data->state.is_in_pipeline = TRUE; + } + else { + if ((*in_connect)->is_in_pipeline) + data->state.is_in_pipeline = TRUE; } return code; -- cgit v1.2.1 From e150150d9f1e0578c85af05de15ab6336066cec1 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 11 Oct 2006 16:01:16 +0000 Subject: Remove redundant __CYGWIN__ symbol check --- lib/url.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fefab252f..dee4b40b9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -38,7 +38,7 @@ #endif #include -#if defined(WIN32) && !defined(__CYGWIN__) +#ifdef WIN32 #include #include #else @@ -165,9 +165,10 @@ static void signalPipeClose(struct curl_llist *pipe); #define MAX_PIPELINE_LENGTH 5 #ifndef USE_ARES -/* not for Win32, unless it is cygwin - not for ares builds */ -#if !defined(WIN32) || defined(__CYGWIN__) +/* not for ares builds */ + +#ifndef WIN32 +/* not for WIN32 builds */ #ifndef RETSIGTYPE #define RETSIGTYPE void @@ -187,8 +188,8 @@ RETSIGTYPE alarmfunc(int sig) #endif return; } -#endif #endif /* SIGALRM */ +#endif /* WIN32 */ #endif /* USE_ARES */ void Curl_safefree(void *ptr) -- cgit v1.2.1 From 2260c8aa11ef1bb0d7e119ad523ee0387647d9e7 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Sun, 15 Oct 2006 20:28:03 +0000 Subject: Replace ";;" with ";". --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dee4b40b9..1b6f0bb7c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1083,7 +1083,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * The already set string is allocated, free that first */ - data->change.proxy_alloc=FALSE;; + data->change.proxy_alloc = FALSE; free(data->change.proxy); } data->set.set_proxy = va_arg(param, char *); -- cgit v1.2.1 From 0bb20cc61184c92eb75d92d452ab8298a8281b8b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 17 Oct 2006 08:05:41 +0000 Subject: fix the name resolve abort timeout calculation (when signals are used) --- lib/url.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1b6f0bb7c..13670cf0b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3668,6 +3668,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Set signal handler to catch SIGALRM * Store the old value to be able to set it back later! *************************************************************/ + long shortest = data->set.timeout; /* default to this timeout value */ + + if(shortest && data->set.connecttimeout && + (data->set.connecttimeout < shortest)) + /* if both are set, pick the shortest */ + shortest = data->set.connecttimeout; + else if(!shortest) + /* if timeout is not set, use the connect timeout */ + shortest = data->set.connecttimeout #ifdef SIGALRM #ifdef HAVE_SIGACTION @@ -3697,9 +3706,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifdef HAVE_ALARM /* alarm() makes a signal get sent when the timeout fires off, and that will abort system calls */ - prev_alarm = alarm((unsigned int) (data->set.connecttimeout? - data->set.connecttimeout: - data->set.timeout)); + prev_alarm = alarm((unsigned int) shortest); /* We can expect the conn->created time to be "now", as that was just recently set in the beginning of this function and nothing slow has been done since then until now. */ -- cgit v1.2.1 From 44ffe0dc796a580c20b7dfaa84b9cc8ee3dd3944 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 17 Oct 2006 09:07:38 +0000 Subject: Typo --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 13670cf0b..312862dcb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3676,7 +3676,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, shortest = data->set.connecttimeout; else if(!shortest) /* if timeout is not set, use the connect timeout */ - shortest = data->set.connecttimeout + shortest = data->set.connecttimeout; #ifdef SIGALRM #ifdef HAVE_SIGACTION -- cgit v1.2.1 From 44d84ac1646cf04ccc2c1a736f3c9d1644ccacec Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 17 Oct 2006 21:32:56 +0000 Subject: Avoid typecasting a signed char to an int when using is*() functions, as that could very well cause a negate number get passed in and thus cause reading outside of the array usually used for this purpose. We avoid this by using the uppercase macro versions introduced just now that does some extra crazy typecasts to avoid byte codes > 127 to cause negative int values. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 312862dcb..d23660515 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3252,7 +3252,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* detect and extract RFC2732-style IPv6-addresses */ if(*proxyptr == '[') { char *ptr = ++proxyptr; /* advance beyond the initial bracket */ - while(*ptr && (isxdigit((int)*ptr) || (*ptr == ':'))) + while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':'))) ptr++; if(*ptr == ']') { /* yeps, it ended nicely with a bracket as well */ -- cgit v1.2.1 From 8c38ea4ebcff4960b531a6f6fbac6b412609c986 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 17 Oct 2006 21:45:37 +0000 Subject: Fixed compile error in HAVE_SIGACTION case. --- lib/url.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d23660515..ac0702ab7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3668,17 +3668,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Set signal handler to catch SIGALRM * Store the old value to be able to set it back later! *************************************************************/ - long shortest = data->set.timeout; /* default to this timeout value */ - - if(shortest && data->set.connecttimeout && - (data->set.connecttimeout < shortest)) - /* if both are set, pick the shortest */ - shortest = data->set.connecttimeout; - else if(!shortest) - /* if timeout is not set, use the connect timeout */ - shortest = data->set.connecttimeout; #ifdef SIGALRM +#ifdef HAVE_ALARM + long shortest; +#endif #ifdef HAVE_SIGACTION struct sigaction sigact; sigaction(SIGALRM, NULL, &sigact); @@ -3704,6 +3698,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, * multi-threaded environments. */ #ifdef HAVE_ALARM + shortest = data->set.timeout; /* default to this timeout value */ + if(shortest && data->set.connecttimeout && + (data->set.connecttimeout < shortest)) + /* if both are set, pick the shortest */ + shortest = data->set.connecttimeout; + else if(!shortest) + /* if timeout is not set, use the connect timeout */ + shortest = data->set.connecttimeout; + /* alarm() makes a signal get sent when the timeout fires off, and that will abort system calls */ prev_alarm = alarm((unsigned int) shortest); -- cgit v1.2.1 From 5b8d5fdf2f7af5a7a055788a4782d4cae2078572 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 18 Oct 2006 11:13:39 +0000 Subject: cut out matching host names starting with telnet or ftps, since they hardly ever actually are used --- lib/url.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ac0702ab7..1a5ae15e7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2511,12 +2511,6 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, if(checkprefix("FTP.", conn->host.name)) strcpy(conn->protostr, "ftp"); -#ifdef USE_SSL - else if(checkprefix("FTPS", conn->host.name)) - strcpy(conn->protostr, "ftps"); -#endif /* USE_SSL */ - else if(checkprefix("TELNET.", conn->host.name)) - strcpy(conn->protostr, "telnet"); else if (checkprefix("DICT.", conn->host.name)) strcpy(conn->protostr, "DICT"); else if (checkprefix("LDAP.", conn->host.name)) -- cgit v1.2.1 From 18aae320151b0c0912b6569762aa3f2f9b17140c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 18 Oct 2006 15:10:49 +0000 Subject: When a connection is re-used, it can be flagged for re-use before the name resolving is completed so we must make sure to survive it and mark the connection as async (ie not yet connected completely). --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1a5ae15e7..850a9451f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3622,6 +3622,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); + if(!conn->dns_entry) { + infof(data, "... but it is not resolved yet!\n"); + *async = TRUE; + } } else { /* -- cgit v1.2.1 From 83884180ac5d4b55abc525099e99a7e1f0879559 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 19 Oct 2006 02:30:02 +0000 Subject: Builds using synchronous name resolver dislike marking the connection as async. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 850a9451f..4bb4234f7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3622,10 +3622,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); +#ifdef CURLRES_ASYNCH if(!conn->dns_entry) { infof(data, "... but it is not resolved yet!\n"); *async = TRUE; } +#endif } else { /* -- cgit v1.2.1 From bd5d21aaf23cd20b74ad13e9d8ca16e81a4aea48 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 20 Oct 2006 12:25:39 +0000 Subject: When a resolve is made on a pipelined connection we need to detect it properly (when the resoling isn't completede yet) and not confuse it with a simple connection re-use (non-pipelined). --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4bb4234f7..65453155c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3623,7 +3623,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); #ifdef CURLRES_ASYNCH - if(!conn->dns_entry) { + if(!conn->ip_addr_str) { infof(data, "... but it is not resolved yet!\n"); *async = TRUE; } -- cgit v1.2.1 From e1edd41e1b9357cec2d42762e8ae67e356693941 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Oct 2006 20:34:56 +0000 Subject: Ravi Pratap provided a major update with pipelining fixes. We also no longer re-use connections (for pipelining) before the name resolving is done. --- lib/url.c | 58 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 18 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 65453155c..4ca5d56a7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1854,6 +1854,7 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle, } curr = curr->next; } + return 0; } @@ -1899,8 +1900,8 @@ static void signalPipeClose(struct curl_llist *pipe) } else #endif - data->state.pipe_broke = TRUE; + data->state.pipe_broke = TRUE; Curl_llist_remove(pipe, curr, NULL); curr = next; } @@ -1936,12 +1937,19 @@ ConnectionExists(struct SessionHandle *data, /* NULL pointer means not filled-in entry */ continue; +#ifdef USE_ARES + /* ip_addr_str is NULL only if the resolving of the name hasn't completed + yet and until then we don't re-use this connection */ + if (!check->ip_addr_str) + continue; +#endif + if(check->inuse && !canPipeline) /* can only happen within multi handles, and means that another easy handle is using this connection */ continue; - if (check->send_pipe->size >= MAX_PIPELINE_LENGTH || + if (check->send_pipe->size + check->recv_pipe->size >= MAX_PIPELINE_LENGTH) continue; @@ -1994,14 +2002,28 @@ ConnectionExists(struct SessionHandle *data, } if(match) { + bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); if(dead) { - /* - */ - check->data = data; - infof(data, "Connection %d seems to be dead!\n", i); - Curl_disconnect(check); /* disconnect resources */ - data->state.connc->connects[i]=NULL; /* nothing here */ + if (!check->is_in_pipeline) { + check->data = data; + infof(data, "Connection %d seems to be dead!\n", i); + + Curl_disconnect(check); /* disconnect resources */ + data->state.connc->connects[i]=NULL; /* nothing here */ + } + else { + /* In the pipelining case, freeing the connection right away + * doesn't work. Instead, we mark the connection for close + * so that the handles will detect this automatically when + * they try to do something and deal with it there. + * Prematurely freeing this connection prevents handles that + * have already finished with their transfers to shut down + * cleanly. + */ + infof(data, "Connection %d seems dead - marking for close\n", i); + check->bits.close = TRUE; + } /* There's no need to continue searching, because we only store one connection for each unique set of identifiers */ @@ -2012,10 +2034,13 @@ ConnectionExists(struct SessionHandle *data, handle in a multi stack may nick it */ if (canPipeline) { - /* Mark the connection as being in a pipeline */ - check->is_in_pipeline = TRUE; + /* Mark the connection as being in a pipeline */ + check->is_in_pipeline = TRUE; } + check->connectindex = i; /* Set this appropriately since it might have + been set to -1 when the easy was removed + from the multi */ *usethis = check; return TRUE; /* yes, we found one to use! */ } @@ -2690,6 +2715,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->readchannel_inuse = FALSE; conn->writechannel_inuse = FALSE; + conn->read_pos = 0; + conn->buf_len = 0; + /* Initialize the pipeline lists */ conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); @@ -3622,12 +3650,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); -#ifdef CURLRES_ASYNCH - if(!conn->ip_addr_str) { - infof(data, "... but it is not resolved yet!\n"); - *async = TRUE; - } -#endif } else { /* @@ -3990,10 +4012,10 @@ CURLcode Curl_done(struct connectdata **connp, if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && conn->readchannel_inuse) - conn->readchannel_inuse--; + conn->readchannel_inuse = FALSE; if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && conn->writechannel_inuse) - conn->writechannel_inuse--; + conn->writechannel_inuse = FALSE; /* cleanups done even if the connection is re-used */ if(data->reqdata.rangestringalloc) { -- cgit v1.2.1 From 36a3514225d610de64f089c36c39615de1139fcc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Oct 2006 20:41:50 +0000 Subject: the check in ConnectionExists() for not re-using a non-resolved connection now applies for asynch name resolves in general and not only ares --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4ca5d56a7..2cfbc9d4e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1937,7 +1937,7 @@ ConnectionExists(struct SessionHandle *data, /* NULL pointer means not filled-in entry */ continue; -#ifdef USE_ARES +#ifdef CURLRES_ASYNCH /* ip_addr_str is NULL only if the resolving of the name hasn't completed yet and until then we don't re-use this connection */ if (!check->ip_addr_str) -- cgit v1.2.1 From f44ef427a2fbe506a35548ebab2b503438d6a027 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 24 Oct 2006 21:14:40 +0000 Subject: other pipelining fixes by Ravi Pratap, that now makes pipelines get used better --- lib/url.c | 95 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 35 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2cfbc9d4e..abbcafa04 100644 --- a/lib/url.c +++ b/lib/url.c @@ -158,6 +158,7 @@ static bool ConnectionExists(struct SessionHandle *data, static long ConnectionStore(struct SessionHandle *data, struct connectdata *conn); static bool IsPipeliningPossible(struct SessionHandle *handle); +static bool IsPipeliningEnabled(struct SessionHandle *handle); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipe); @@ -1790,8 +1791,10 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_ssl_close(conn); /* Indicate to all handles on the pipe that we're dead */ - signalPipeClose(conn->send_pipe); - signalPipeClose(conn->recv_pipe); + if (IsPipeliningEnabled(data)) { + signalPipeClose(conn->send_pipe); + signalPipeClose(conn->recv_pipe); + } conn_free(conn); @@ -1827,6 +1830,14 @@ static bool IsPipeliningPossible(struct SessionHandle *handle) return FALSE; } +static bool IsPipeliningEnabled(struct SessionHandle *handle) +{ + if (handle->multi && Curl_multi_canPipeline(handle->multi)) + return TRUE; + + return FALSE; +} + void Curl_addHandleToPipeline(struct SessionHandle *data, struct curl_llist *pipe) { @@ -1937,21 +1948,44 @@ ConnectionExists(struct SessionHandle *data, /* NULL pointer means not filled-in entry */ continue; + if (check->connectindex == -1) { + check->connectindex = i; /* Set this appropriately since it might have + been set to -1 when the easy was removed + from the multi */ + } + + infof(data, "Examining connection #%ld for reuse\n", check->connectindex); + + if(check->inuse && !canPipeline) { + /* can only happen within multi handles, and means that another easy + handle is using this connection */ + continue; + } + #ifdef CURLRES_ASYNCH /* ip_addr_str is NULL only if the resolving of the name hasn't completed yet and until then we don't re-use this connection */ - if (!check->ip_addr_str) - continue; -#endif - - if(check->inuse && !canPipeline) - /* can only happen within multi handles, and means that another easy - handle is using this connection */ + if (!check->ip_addr_str) { + infof(data, + "Connection #%ld has not finished name resolve, can't reuse\n", + check->connectindex); continue; + } +#endif if (check->send_pipe->size + - check->recv_pipe->size >= MAX_PIPELINE_LENGTH) + check->recv_pipe->size >= MAX_PIPELINE_LENGTH) { + infof(data, "Connection #%ld has its pipeline full, can't reuse\n", + check->connectindex); continue; + } + + if (data->state.is_in_pipeline && check->bits.close) { + /* Don't pick a connection that is going to be closed */ + infof(data, "Connection #%ld has been marked for close, can't reuse\n", + check->connectindex); + continue; + } if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) /* don't do mixed SSL and non-SSL connections */ @@ -2002,33 +2036,22 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - - bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); - if(dead) { - if (!check->is_in_pipeline) { +#if 1 + if (!IsPipeliningEnabled(data)) { + /* The check for a dead socket makes sense only in the + non-pipelining case */ + bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); + if(dead) { check->data = data; - infof(data, "Connection %d seems to be dead!\n", i); + infof(data, "Connection #%d seems to be dead!\n", i); Curl_disconnect(check); /* disconnect resources */ data->state.connc->connects[i]=NULL; /* nothing here */ - } - else { - /* In the pipelining case, freeing the connection right away - * doesn't work. Instead, we mark the connection for close - * so that the handles will detect this automatically when - * they try to do something and deal with it there. - * Prematurely freeing this connection prevents handles that - * have already finished with their transfers to shut down - * cleanly. - */ - infof(data, "Connection %d seems dead - marking for close\n", i); - check->bits.close = TRUE; - } - /* There's no need to continue searching, because we only store - one connection for each unique set of identifiers */ - return FALSE; + return FALSE; + } } +#endif check->inuse = TRUE; /* mark this as being in use so that no other handle in a multi stack may nick it */ @@ -2045,10 +2068,12 @@ ConnectionExists(struct SessionHandle *data, return TRUE; /* yes, we found one to use! */ } } + return FALSE; /* no matching connecting exists */ } + /* * This function frees/closes a connection in the connection cache. This * should take the previously set policy into account when deciding which @@ -2182,9 +2207,9 @@ static CURLcode ConnectPlease(struct SessionHandle *data, Curl_addrinfo *addr; char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; - infof(data, "About to connect() to %s%s port %d\n", + infof(data, "About to connect() to %s%s port %d (#%d)\n", data->change.proxy?"proxy ":"", - hostname, conn->port); + hostname, conn->port, conn->connectindex); /************************************************************* * Connect to server/proxy @@ -2226,9 +2251,9 @@ static CURLcode ConnectPlease(struct SessionHandle *data, */ static void verboseconnect(struct connectdata *conn) { - infof(conn->data, "Connected to %s (%s) port %d\n", + infof(conn->data, "Connected to %s (%s) port %d (#%d)\n", conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, - conn->ip_addr_str, conn->port); + conn->ip_addr_str, conn->port, conn->connectindex); } int Curl_protocol_getsock(struct connectdata *conn, -- cgit v1.2.1 From 012d7e28789cf6299c16beb1a95710a95ea97258 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 26 Oct 2006 11:15:25 +0000 Subject: Fix Curl_open() not reporting failure when allocation of the buffer used to store headers in the SessionHandle failed. --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index abbcafa04..03a0b6edd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -564,9 +564,10 @@ CURLcode Curl_open(struct SessionHandle **curl) free(data); data = NULL; } + else + *curl = data; - *curl = data; - return CURLE_OK; + return res; } CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, -- cgit v1.2.1 From 8a8d5c784c4b8f137e2ad9aa9443c4dd3fa8626d Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 27 Oct 2006 01:04:41 +0000 Subject: Do an explicit typecast of data pointers to function pointers to avoid picky compiler warnings, since this is what we want! --- lib/url.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 03a0b6edd..aa26dd904 100644 --- a/lib/url.c +++ b/lib/url.c @@ -501,9 +501,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.fread = (curl_read_callback)fread; /* conversion callbacks for non-ASCII hosts */ - data->set.convfromnetwork = (curl_conv_callback)NULL; - data->set.convtonetwork = (curl_conv_callback)NULL; - data->set.convfromutf8 = (curl_conv_callback)NULL; + data->set.convfromnetwork = (CURLcode(*)(char *, size_t))NULL; + data->set.convtonetwork = (CURLcode(*)(char *, size_t))NULL; + data->set.convfromutf8 = (CURLcode(*)(char *, size_t))NULL; #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) /* conversion descriptors for iconv calls */ @@ -2993,7 +2993,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; - conn->curl_do_more = (Curl_do_more_func)NULL; + conn->curl_do_more = (CURLcode(*)(struct connectdata *)) NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; #else @@ -3010,7 +3010,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; conn->curl_do = Curl_http; - conn->curl_do_more = (Curl_do_more_func)NULL; + conn->curl_do_more = (CURLcode(*)(struct connectdata *))NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; conn->curl_connecting = Curl_https_connecting; @@ -3123,7 +3123,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = PORT_DICT; conn->remote_port = PORT_DICT; conn->curl_do = Curl_dict; - conn->curl_done = (Curl_done_func)NULL; /* no DICT-specific done */ + /* no DICT-specific done */ + conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))NULL; #else failf(data, LIBCURL_NAME " was built with DICT disabled!"); @@ -3135,7 +3136,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = PORT_LDAP; conn->remote_port = PORT_LDAP; conn->curl_do = Curl_ldap; - conn->curl_done = (Curl_done_func)NULL; /* no LDAP-specific done */ + /* no LDAP-specific done */ + conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))NULL; #else failf(data, LIBCURL_NAME " was built with LDAP disabled!"); -- cgit v1.2.1 From a93695a70ea273417ad6c52323d7a7d2c47b8a2b Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 27 Oct 2006 15:32:18 +0000 Subject: Compiler warning fix. Assigning the const value zero to a pointer to function results in a null pointer value assignment to the function pointer. Assignment of any nonzero value is what should result in a implementation compiler dependent result. Since what we want to do here is the first case, this should not trigger compiler warnings related with conversions from 'pointer to data' to 'pointer to function'. Our autobuild test suite will judge. --- lib/url.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index aa26dd904..9b9348fd4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -501,9 +501,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.fread = (curl_read_callback)fread; /* conversion callbacks for non-ASCII hosts */ - data->set.convfromnetwork = (CURLcode(*)(char *, size_t))NULL; - data->set.convtonetwork = (CURLcode(*)(char *, size_t))NULL; - data->set.convfromutf8 = (CURLcode(*)(char *, size_t))NULL; + data->set.convfromnetwork = (CURLcode(*)(char *, size_t))0; + data->set.convtonetwork = (CURLcode(*)(char *, size_t))0; + data->set.convfromutf8 = (CURLcode(*)(char *, size_t))0; #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) /* conversion descriptors for iconv calls */ @@ -2993,7 +2993,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; - conn->curl_do_more = (CURLcode(*)(struct connectdata *)) NULL; + conn->curl_do_more = (CURLcode(*)(struct connectdata *))0; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; #else @@ -3010,7 +3010,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; conn->curl_do = Curl_http; - conn->curl_do_more = (CURLcode(*)(struct connectdata *))NULL; + conn->curl_do_more = (CURLcode(*)(struct connectdata *))0; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; conn->curl_connecting = Curl_https_connecting; @@ -3124,7 +3124,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_DICT; conn->curl_do = Curl_dict; /* no DICT-specific done */ - conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))NULL; + conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))0; #else failf(data, LIBCURL_NAME " was built with DICT disabled!"); @@ -3137,7 +3137,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_LDAP; conn->curl_do = Curl_ldap; /* no LDAP-specific done */ - conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))NULL; + conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))0; #else failf(data, LIBCURL_NAME " was built with LDAP disabled!"); -- cgit v1.2.1 From ba481718a461731ac92f1d0602d29d056251115c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 29 Oct 2006 14:58:59 +0000 Subject: Make more human readable and maintainable previous compiler warning fix since it was Ok and actually avoids the targeted compiler warning. --- lib/url.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9b9348fd4..6b823df34 100644 --- a/lib/url.c +++ b/lib/url.c @@ -165,6 +165,13 @@ static void signalPipeClose(struct curl_llist *pipe); #define MAX_PIPELINE_LENGTH 5 +/* + * We use this ZERO_NULL to avoid picky compiler warnings, + * when assigning a NULL pointer to a function pointer var. + */ + +#define ZERO_NULL 0 + #ifndef USE_ARES /* not for ares builds */ @@ -501,9 +508,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.fread = (curl_read_callback)fread; /* conversion callbacks for non-ASCII hosts */ - data->set.convfromnetwork = (CURLcode(*)(char *, size_t))0; - data->set.convtonetwork = (CURLcode(*)(char *, size_t))0; - data->set.convfromutf8 = (CURLcode(*)(char *, size_t))0; + data->set.convfromnetwork = (curl_conv_callback)ZERO_NULL; + data->set.convtonetwork = (curl_conv_callback)ZERO_NULL; + data->set.convfromutf8 = (curl_conv_callback)ZERO_NULL; #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) /* conversion descriptors for iconv calls */ @@ -2993,7 +3000,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_HTTP; conn->protocol |= PROT_HTTP; conn->curl_do = Curl_http; - conn->curl_do_more = (CURLcode(*)(struct connectdata *))0; + conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; #else @@ -3010,7 +3017,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; conn->curl_do = Curl_http; - conn->curl_do_more = (CURLcode(*)(struct connectdata *))0; + conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; conn->curl_done = Curl_http_done; conn->curl_connect = Curl_http_connect; conn->curl_connecting = Curl_https_connecting; @@ -3124,7 +3131,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_DICT; conn->curl_do = Curl_dict; /* no DICT-specific done */ - conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))0; + conn->curl_done = (Curl_done_func)ZERO_NULL; #else failf(data, LIBCURL_NAME " was built with DICT disabled!"); @@ -3137,7 +3144,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = PORT_LDAP; conn->curl_do = Curl_ldap; /* no LDAP-specific done */ - conn->curl_done = (CURLcode(*)(struct connectdata *, CURLcode))0; + conn->curl_done = (Curl_done_func)ZERO_NULL; #else failf(data, LIBCURL_NAME " was built with LDAP disabled!"); -- cgit v1.2.1 From 2147284cad624325f5b0034c2f394db62086d9e6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 2 Nov 2006 21:56:40 +0000 Subject: James Housley brought support for SCP transfers --- lib/url.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6b823df34..92e4a3b09 100644 --- a/lib/url.c +++ b/lib/url.c @@ -128,6 +128,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "http.h" #include "file.h" #include "ldap.h" +#include "ssh.h" #include "url.h" #include "connect.h" #include "inet_ntop.h" @@ -165,7 +166,7 @@ static void signalPipeClose(struct curl_llist *pipe); #define MAX_PIPELINE_LENGTH 5 -/* +/* * We use this ZERO_NULL to avoid picky compiler warnings, * when assigning a NULL pointer to a function pointer var. */ @@ -546,6 +547,9 @@ CURLcode Curl_open(struct SessionHandle **curl) the first call to curl_easy_perform() or when the handle is added to a multi stack. */ + data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth + type */ + /* most recent connection is not yet defined */ data->state.lastconnect = -1; @@ -1673,6 +1677,24 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ssl.sessionid = (bool)(0 != va_arg(param, long)); break; + case CURLOPT_SSH_AUTH_TYPES: + data->set.ssh_auth_types = va_arg(param, long); + break; + + case CURLOPT_SSH_PUBLIC_KEYFILE: + /* + * Use this file instead of the $HOME/.ssh/id_dsa.pub file + */ + data->set.ssh_public_key = va_arg(param, char *); + break; + + case CURLOPT_SSH_PRIVATE_KEYFILE: + /* + * Use this file instead of the $HOME/.ssh/id_dsa file + */ + data->set.ssh_private_key = va_arg(param, char *); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -3023,7 +3045,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connecting = Curl_https_connecting; conn->curl_proto_getsock = Curl_https_getsock; -#else /* USE_SS */ +#else /* USE_SSL */ failf(data, LIBCURL_NAME " was built with SSL disabled, https: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; @@ -3213,6 +3235,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else failf(data, LIBCURL_NAME " was built with TFTP disabled!"); +#endif + } + else if (strequal(conn->protostr, "SCP")) { +#ifdef USE_LIBSSH2 + conn->port = PORT_SSH; + conn->remote_port = PORT_SSH; + conn->protocol = PROT_SCP; + conn->curl_connect = Curl_scp_connect; /* ssh_connect? */ + conn->curl_do = Curl_scp_do; + conn->curl_done = Curl_scp_done; + conn->curl_do_more = (Curl_do_more_func)NULL; +#else + failf(data, LIBCURL_NAME + " was built without LIBSSH2, scp: not supported!"); + return CURLE_UNSUPPORTED_PROTOCOL; #endif } else { @@ -3381,7 +3418,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, user[0] =0; /* to make everything well-defined */ passwd[0]=0; - if (conn->protocol & (PROT_FTP|PROT_HTTP)) { + if (conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP)) { /* 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 */ -- cgit v1.2.1 From a777eb3d816dbd437d9b8a9e3b7b52be91d68e3b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 3 Nov 2006 12:43:55 +0000 Subject: Olaf Stueben provided a patch that I edited slightly. It fixes the notorious KNOWN_BUGS #25, which happens when a proxy closes the connection when libcurl has sent CONNECT, as part of an authentication negotiation. Starting now, libcurl will re-connect accordingly and continue the authentication as it should. --- lib/url.c | 54 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 92e4a3b09..73b9debbe 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2394,7 +2394,8 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, /* it has started, possibly even completed but that knowledge isn't stored in this bit! */ - conn->bits.protoconnstart = TRUE; + if (!result) + conn->bits.protoconnstart = TRUE; } return result; /* pass back status */ @@ -3957,30 +3958,41 @@ static CURLcode SetupConnection(struct connectdata *conn, data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ #endif /* CURL_DO_LINEEND_CONV */ - if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { - bool connected = FALSE; + for(;;) { + /* loop for CURL_SERVER_CLOSED_CONNECTION */ - /* Connect only if not already connected! */ - result = ConnectPlease(data, conn, hostaddr, &connected); + if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { + bool connected = FALSE; - if(connected) { - result = Curl_protocol_connect(conn, protocol_done); - if(CURLE_OK == result) - conn->bits.tcpconnect = TRUE; - } - else - conn->bits.tcpconnect = FALSE; + /* Connect only if not already connected! */ + result = ConnectPlease(data, conn, hostaddr, &connected); + if(connected) { + result = Curl_protocol_connect(conn, protocol_done); + if(CURLE_OK == result) + conn->bits.tcpconnect = TRUE; + } + else + conn->bits.tcpconnect = FALSE; - if(CURLE_OK != result) - return result; - } - else { - Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ - conn->bits.tcpconnect = TRUE; - *protocol_done = TRUE; - if(data->set.verbose) - verboseconnect(conn); + /* if the connection was closed by the server while exchanging + authentication informations, retry with the new set + authentication information */ + if(conn->bits.proxy_connect_closed) + continue; + + if(CURLE_OK != result) + return result; + } + else { + Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ + conn->bits.tcpconnect = TRUE; + *protocol_done = TRUE; + if(data->set.verbose) + verboseconnect(conn); + } + /* Stop the loop now */ + break; } conn->now = Curl_tvnow(); /* time this *after* the connect is done, we -- cgit v1.2.1 From 69f7d0a0ce2a50f8a69781f526aed48bbc4f04af Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 6 Nov 2006 18:27:25 +0000 Subject: compiler warning fix --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 73b9debbe..2791c718c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3246,7 +3246,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_scp_connect; /* ssh_connect? */ conn->curl_do = Curl_scp_do; conn->curl_done = Curl_scp_done; - conn->curl_do_more = (Curl_do_more_func)NULL; + conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME " was built without LIBSSH2, scp: not supported!"); -- cgit v1.2.1 From b5b3d9e5c7f88f6586d31a84028ff07fba658ee8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 7 Nov 2006 14:07:02 +0000 Subject: Olaf fixed a leftover problem with the CONNECT fix of his that would leave a wrong error message in the error message buffer. --- lib/url.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2791c718c..c5ce746c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3978,8 +3978,13 @@ static CURLcode SetupConnection(struct connectdata *conn, /* if the connection was closed by the server while exchanging authentication informations, retry with the new set authentication information */ - if(conn->bits.proxy_connect_closed) + if(conn->bits.proxy_connect_closed) { + /* reset the error buffer */ + if (data->set.errorbuffer) + data->set.errorbuffer[0] = '\0'; + data->state.errorbuf = FALSE; continue; + } if(CURLE_OK != result) return result; -- cgit v1.2.1 From 624745ab20a7826e18f300cc19ef496f0224dad0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 9 Nov 2006 21:54:33 +0000 Subject: Dmitriy Sergeyev found a SIGSEGV with his test04.c example posted on 7 Nov 2006. It turned out we wrongly assumed that the connection cache was present when tearing down a connection. --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c5ce746c0..cc3c87eb9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1804,7 +1804,10 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(-1 != conn->connectindex) { /* unlink ourselves! */ infof(data, "Closing connection #%ld\n", conn->connectindex); - data->state.connc->connects[conn->connectindex] = NULL; + if(data->state.connc) + /* only clear the table entry if we still know in which cache we + used to be in */ + data->state.connc->connects[conn->connectindex] = NULL; } #ifdef USE_LIBIDN -- cgit v1.2.1 From a634f644005cbe2b3dea2b84328d605ec3474054 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 24 Nov 2006 22:14:39 +0000 Subject: James Housley did lots of work and introduced SFTP downloads. --- lib/url.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cc3c87eb9..b7f06cc5b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3246,7 +3246,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = PORT_SSH; conn->remote_port = PORT_SSH; conn->protocol = PROT_SCP; - conn->curl_connect = Curl_scp_connect; /* ssh_connect? */ + conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_do = Curl_scp_do; conn->curl_done = Curl_scp_done; conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; @@ -3256,7 +3256,22 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } - else { + else if (strequal(conn->protostr, "SFTP")) { +#ifdef USE_LIBSSH2 + conn->port = PORT_SSH; + conn->remote_port = PORT_SSH; + conn->protocol = PROT_SFTP; + conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ + conn->curl_do = Curl_sftp_do; + conn->curl_done = Curl_sftp_done; + conn->curl_do_more = (Curl_do_more_func)NULL; +#else + failf(data, LIBCURL_NAME + " was built without LIBSSH2, scp: not supported!"); + return CURLE_UNSUPPORTED_PROTOCOL; +#endif +} +else { /* We fell through all checks and thus we don't support the specified protocol */ failf(data, "Unsupported protocol: %s", conn->protostr); @@ -3422,9 +3437,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, user[0] =0; /* to make everything well-defined */ passwd[0]=0; - if (conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP)) { - /* This is a FTP or HTTP URL, we will now try to extract the possible - * user+password pair in a string like: + if (conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) { + /* This is a FTP, HTTP, SCP or SFTP 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->host.name, '@'); char *userpass = conn->host.name; -- cgit v1.2.1 From a46f55b9de423b4084982467d6f28f69a64ab8f3 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 25 Nov 2006 01:02:52 +0000 Subject: Make sure RETSIGTYPE is properly defined --- lib/url.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b7f06cc5b..bf67b9c1b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -179,9 +179,6 @@ static void signalPipeClose(struct curl_llist *pipe); #ifndef WIN32 /* not for WIN32 builds */ -#ifndef RETSIGTYPE -#define RETSIGTYPE void -#endif #ifdef HAVE_SIGSETJMP extern sigjmp_buf curl_jmpenv; #endif -- cgit v1.2.1 From 4c65eb0af841d95de24622e1b8212bf1c30c0c48 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Dec 2006 15:17:32 +0000 Subject: CURLOPT_FORBID_REUSE works again with a cleaned up order of doing things in Curl_done() --- lib/url.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bf67b9c1b..71463164a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4150,8 +4150,6 @@ CURLcode Curl_done(struct connectdata **connp, cancelled before we proceed */ ares_cancel(data->state.areschannel); - ConnectionDone(conn); /* the connection is no longer in use */ - /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this no matter what we think. @@ -4159,8 +4157,7 @@ CURLcode Curl_done(struct connectdata **connp, closed in spite of all our efforts to be nice, due to protocol restrictions in our or the server's end */ if(data->set.reuse_forbid || conn->bits.close) { - CURLcode res2; - res2 = Curl_disconnect(conn); /* close the connection */ + CURLcode res2 = Curl_disconnect(conn); /* close the connection */ *connp = NULL; /* to make the caller of this function better detect that this was actually killed here */ @@ -4171,6 +4168,8 @@ CURLcode Curl_done(struct connectdata **connp, result = res2; } else { + ConnectionDone(conn); /* the connection is no longer in use */ + /* remember the most recently used connection */ data->state.lastconnect = conn->connectindex; -- cgit v1.2.1 From e4505aefd9dc81eb2c51f2739f8dc626f7c3ce93 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Dec 2006 15:36:26 +0000 Subject: Jared Lundell filed bug report #1604956 (http://curl.haxx.se/bug/view.cgi?id=1604956) which identified setting CURLOPT_MAXCONNECTS to zero caused libcurl to SIGSEGV. Starting now, libcurl will always internally use no less than 1 entry in the connection cache. --- lib/url.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 71463164a..4f9969dcf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -377,11 +377,13 @@ CURLcode Curl_close(struct SessionHandle *data) } /* create a connection cache of a private or multi type */ -struct conncache *Curl_mk_connc(int type) +struct conncache *Curl_mk_connc(int type, + int amount) /* set -1 to use default */ { /* It is subject for debate how many default connections to have for a multi connection cache... */ - int default_amount = (type == CONNCACHE_PRIVATE)?5:10; + int default_amount = amount == -1? + ((type == CONNCACHE_PRIVATE)?5:10):amount; struct conncache *c; c= calloc(sizeof(struct conncache), 1); @@ -407,6 +409,20 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, long i; struct connectdata **newptr; + if(newamount < 1) + newamount = 1; /* we better have at least one entry */ + + if(!c) { + /* we get a NULL pointer passed in as connection cache, which means that + there is no cache created for this SessionHandle just yet, we create a + brand new with the requested size. + */ + data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, newamount); + if(!data->state.connc) + return CURLE_OUT_OF_MEMORY; + return CURLE_OK; + } + if(newamount < c->num) { /* Since this number is *decreased* from the existing number, we must close the possibly open connections that live on the indexes that -- cgit v1.2.1 From eb29c5c2851ffde4f72a3f3d75942796fee60c32 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Dec 2006 21:39:24 +0000 Subject: removed the final traces of the closepolicy option --- lib/url.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4f9969dcf..a028857e8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2143,26 +2143,8 @@ ConnectionKillOne(struct SessionHandle *data) if(!conn || conn->inuse) continue; - /* - * By using the set policy, we score each connection. - */ - switch(data->set.closepolicy) { - case CURLCLOSEPOLICY_LEAST_RECENTLY_USED: - default: - /* - * Set higher score for the age passed since the connection - * was used. - */ - score = Curl_tvdiff(now, conn->now); - break; - case CURLCLOSEPOLICY_OLDEST: - /* - * Set higher score for the age passed since the connection - * was created. - */ - score = Curl_tvdiff(now, conn->created); - break; - } + /* Set higher score for the age passed since the connection was used */ + score = Curl_tvdiff(now, conn->now); if(score > highscore) { highscore = score; -- cgit v1.2.1 From 88c8d72a214864952b6d1c2347b6c3f5b7d69e84 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Dec 2006 09:32:58 +0000 Subject: Alexey Simak found out that when doing FTP with the multi interface and something went wrong like it got a bad response code back from the server, libcurl would leak memory. Added test case 538 to verify the fix. I also noted that the connection would get cached in that case, which doesn't make sense since it cannot be re-use when the authentication has failed. I fixed that issue too at the same time, and also that the path would be "remembered" in vain for cases where the connection was about to get closed. --- lib/url.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a028857e8..9a3c68d0b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2171,10 +2171,7 @@ static void ConnectionDone(struct connectdata *conn) { conn->inuse = FALSE; - conn->data = NULL; - - if (conn->send_pipe == 0 && - conn->recv_pipe == 0) + if (!conn->send_pipe && !conn->recv_pipe) conn->is_in_pipeline = FALSE; } @@ -3071,7 +3068,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->port = port; conn->remote_port = (unsigned short)port; - conn->protocol |= PROT_FTP|PROT_CLOSEACTION; + conn->protocol |= PROT_FTP; if(data->change.proxy && *data->change.proxy && -- cgit v1.2.1 From 89ab5f4380b9fd6507e0bc365310d88c82dd3de1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 21 Dec 2006 10:15:38 +0000 Subject: Robson Braga Araujo reported bug #1618359 (http://curl.haxx.se/bug/view.cgi?id=1618359) and subsequently provided a patch for it: when downloading 2 zero byte files in a row, curl 7.16.0 enters an infinite loop, while curl 7.16.1-20061218 does one additional unnecessary request. Fix: During the "Major overhaul introducing http pipelining support and shared connection cache within the multi handle." change, headerbytecount was moved to live in the Curl_transfer_keeper structure. But that structure is reset in the Transfer method, losing the information that we had about the header size. This patch moves it back to the connectdata struct. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9a3c68d0b..7b87a92c4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3964,6 +3964,8 @@ static CURLcode SetupConnection(struct connectdata *conn, } } + conn->headerbytecount = 0; + #ifdef CURL_DO_LINEEND_CONV data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ #endif /* CURL_DO_LINEEND_CONV */ -- cgit v1.2.1 From b2f8de571fb10f58bc3c8411bb4bbed2aa14dc52 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Dec 2006 07:30:21 +0000 Subject: When setting a proxy with environment variables and (for example) running 'curl [URL]' with a URL without a protocol prefix, curl would not send a correct request as it failed to add the protocol prefix. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7b87a92c4..65ec4f1e2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2951,7 +2951,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if(proxy && *proxy) { - long bits = conn->protocol & (PROT_HTTPS|PROT_SSL); + long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); data->change.proxy = proxy; data->change.proxy_alloc=TRUE; /* this needs to be freed later */ conn->bits.httpproxy = TRUE; -- cgit v1.2.1 From bedc61ac45394eec850edfdae43a55c8586c3017 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Dec 2006 15:04:59 +0000 Subject: - Robert Foreman provided a prime example snippet showing how libcurl would get confused and not acknowledge the 'no_proxy' variable properly once it had used the proxy and you re-used the same easy handle. I made sure the proxy name is properly stored in the connect struct rather than the sessionhandle/easy struct. --- lib/url.c | 56 +++++++++++++++++++++----------------------------------- 1 file changed, 21 insertions(+), 35 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 65ec4f1e2..c988506b0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -310,9 +310,6 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.first_host); Curl_safefree(data->state.scratch); - if(data->change.proxy_alloc) - free(data->change.proxy); - if(data->change.referer_alloc) free(data->change.referer); @@ -1105,15 +1102,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Setting it to NULL, means no proxy but allows the environment variables * to decide for us. */ - if(data->change.proxy_alloc) { - /* - * The already set string is allocated, free that first - */ - data->change.proxy_alloc = FALSE; - free(data->change.proxy); - } - data->set.set_proxy = va_arg(param, char *); - data->change.proxy = data->set.set_proxy; + data->set.proxy = va_arg(param, char *); break; case CURLOPT_WRITEHEADER: @@ -1915,7 +1904,7 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle, return 0; } -#if 0 +#if 0 /* this code is saved here as it is useful for debugging purposes */ static void Curl_printPipeline(struct curl_llist *pipe) { struct curl_llist_element *curr; @@ -2082,7 +2071,6 @@ ConnectionExists(struct SessionHandle *data, } if(match) { -#if 1 if (!IsPipeliningEnabled(data)) { /* The check for a dead socket makes sense only in the non-pipelining case */ @@ -2097,7 +2085,6 @@ ConnectionExists(struct SessionHandle *data, return FALSE; } } -#endif check->inuse = TRUE; /* mark this as being in use so that no other handle in a multi stack may nick it */ @@ -2230,10 +2217,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data, { CURLcode result; Curl_addrinfo *addr; - char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; + char *hostname = conn->bits.httpproxy?conn->proxy.name:conn->host.name; infof(data, "About to connect() to %s%s port %d (#%d)\n", - data->change.proxy?"proxy ":"", + conn->bits.httpproxy?"proxy ":"", hostname, conn->port, conn->connectindex); /************************************************************* @@ -2706,6 +2693,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, char passwd[MAX_CURL_PASSWORD_LENGTH]; int rc; bool reuse; + char *proxy; + bool proxy_alloc = FALSE; #ifndef USE_ARES #ifdef SIGALRM @@ -2754,9 +2743,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->connectindex = -1; /* no index */ - conn->bits.httpproxy = (bool)(data->change.proxy /* http proxy or not */ - && *data->change.proxy - && (data->set.proxytype == CURLPROXY_HTTP)); + conn->bits.httpproxy = (bool)(data->set.proxy /* http proxy or not */ + && *data->set.proxy + && (data->set.proxytype == CURLPROXY_HTTP)); + proxy = data->set.proxy; /* if global proxy is set, this is it */ /* Default protocol-independent behavior doesn't support persistent connections, so we set this to force-close. Protocols that support @@ -2856,7 +2846,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /************************************************************* * Detect what (if any) proxy to use *************************************************************/ - if(!data->change.proxy) { + if(!conn->bits.httpproxy) { /* If proxy was not specified, we check for default proxy environment * variables, to enable i.e Lynx compliance: * @@ -2876,7 +2866,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ char *no_proxy=NULL; char *no_proxy_tok_buf; - char *proxy=NULL; char proxy_env[128]; no_proxy=curl_getenv("no_proxy"); @@ -2952,12 +2941,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(proxy && *proxy) { long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); - data->change.proxy = proxy; - data->change.proxy_alloc=TRUE; /* this needs to be freed later */ - conn->bits.httpproxy = TRUE; - /* force this to become HTTP */ conn->protocol = PROT_HTTP | bits; + + proxy_alloc=TRUE; /* this needs to be freed later */ + conn->bits.httpproxy = TRUE; } } /* if (!nope) - it wasn't specified non-proxy */ } /* NO_PROXY wasn't specified or '*' */ @@ -3070,9 +3058,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = (unsigned short)port; conn->protocol |= PROT_FTP; - if(data->change.proxy && - *data->change.proxy && - !data->set.tunnel_thru_httpproxy) { + if(proxy && *proxy && !data->set.tunnel_thru_httpproxy) { /* Unless we have asked to tunnel ftp operations through the proxy, we switch and use HTTP operations only */ #ifndef CURL_DISABLE_HTTP @@ -3270,7 +3256,7 @@ else { return CURLE_UNSUPPORTED_PROTOCOL; } - if(data->change.proxy && *data->change.proxy) { + if(proxy && *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. */ @@ -3279,8 +3265,9 @@ else { char *endofprot; /* We need to make a duplicate of the proxy so that we can modify the - string safely. */ - char *proxydup=strdup(data->change.proxy); + string safely. If 'proxy_alloc' is TRUE, the string is already + allocated and we can treat it as duplicated. */ + char *proxydup=proxy_alloc?proxy:strdup(proxy); /* We use 'proxyptr' to point to the proxy name from now on... */ char *proxyptr=proxydup; @@ -3840,7 +3827,7 @@ else { /* set a pointer to the hostname we display */ fix_hostname(data, conn, &conn->host); - if(!data->change.proxy || !*data->change.proxy) { + if(!proxy || !*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 */ @@ -3953,8 +3940,7 @@ static CURLcode SetupConnection(struct connectdata *conn, * Send user-agent to HTTP proxies even if the target protocol * isn't HTTP. *************************************************************/ - if((conn->protocol&PROT_HTTP) || - (data->change.proxy && *data->change.proxy)) { + if((conn->protocol&PROT_HTTP) || conn->bits.httpproxy) { if(data->set.useragent) { Curl_safefree(conn->allocptr.uagent); conn->allocptr.uagent = -- cgit v1.2.1 From 4750e6f3c5fd42e19998242ddb63d7d5506b9fd9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Jan 2007 23:11:14 +0000 Subject: - Linus Nielsen Feltzing introduced the --ftp-ssl-ccc command line option to curl that uses the new CURLOPT_FTP_SSL_CCC option in libcurl. If enabled, it will make libcurl shutdown SSL/TLS after the authentication is done on a FTP-SSL operation. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c988506b0..0f3f85a5f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1140,6 +1140,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long)); break; + case CURLOPT_FTP_SSL_CCC: + data->set.ftp_use_ccc = (bool)(0 != va_arg(param, long)); + break; + case CURLOPT_FTP_SKIP_PASV_IP: /* * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the -- cgit v1.2.1 From 0fb5a65a58130da7882f0a8d396e24b95c25064f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 14 Jan 2007 14:57:51 +0000 Subject: - David McCreedy provided libcurl changes for doing HTTP communication on non-ASCII platforms. It does add some complexity, most notably with more #ifdefs, but I want to see this supported added and I can't see how we can add it without the extra stuff added. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0f3f85a5f..123d75b67 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3948,7 +3948,7 @@ static CURLcode SetupConnection(struct connectdata *conn, if(data->set.useragent) { Curl_safefree(conn->allocptr.uagent); conn->allocptr.uagent = - aprintf("User-Agent: %s\015\012", data->set.useragent); + aprintf("User-Agent: %s\r\n", data->set.useragent); if(!conn->allocptr.uagent) return CURLE_OUT_OF_MEMORY; } -- cgit v1.2.1 From 385e612fa5b7663fc2bc815677b8c27bec2f0fe4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 16 Jan 2007 22:22:10 +0000 Subject: - Armel Asselin improved libcurl to behave a lot better when an easy handle doing an FTP transfer is removed from a multi handle before completion. The fix also fixed the "alive counter" to be correct on "premature removal" for all protocols. --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 123d75b67..91cb57e2e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4087,7 +4087,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, CURLcode Curl_done(struct connectdata **connp, - CURLcode status) /* an error if this is called after an + CURLcode status, bool premature) /* an error if this is called after an error was detected */ { CURLcode result; @@ -4127,7 +4127,7 @@ CURLcode Curl_done(struct connectdata **connp, /* this calls the protocol-specific function pointer previously set */ if(conn->curl_done) - result = conn->curl_done(conn, status); + result = conn->curl_done(conn, status, premature); else result = CURLE_OK; @@ -4193,7 +4193,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) infof(data, "Re-used connection seems dead, get a new one\n"); conn->bits.close = TRUE; /* enforce close of this connection */ - result = Curl_done(&conn, result); /* we are so done with this */ + result = Curl_done(&conn, result, FALSE); /* we are so done with this */ /* conn may no longer be a good pointer */ -- cgit v1.2.1 From 44ac2776ae8394974c88655c8c45ee4a6bf7b209 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 25 Jan 2007 01:35:43 +0000 Subject: Fixed a dangling pointer problem that prevented the http_proxy environment variable from being properly used in many cases (and caused test case 63 to fail). --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 91cb57e2e..01751a380 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3380,12 +3380,13 @@ else { conn->proxy.name = conn->proxy.rawalloc; free(proxydup); /* free the duplicate pointer and not the modified */ + proxy = NULL; /* this may have just been freed */ if(!conn->proxy.rawalloc) return CURLE_OUT_OF_MEMORY; } /************************************************************* - * If the protcol is using SSL and HTTP proxy is used, we set + * If the protocol is using SSL and HTTP proxy is used, we set * the tunnel_proxy bit. *************************************************************/ if((conn->protocol&PROT_SSL) && conn->bits.httpproxy) @@ -3831,7 +3832,7 @@ else { /* set a pointer to the hostname we display */ fix_hostname(data, conn, &conn->host); - if(!proxy || !*proxy) { + if(!conn->proxy.name || !*conn->proxy.name) { /* 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 */ -- cgit v1.2.1 From 1f4c8c4f0931ceb1afc11e6d5310d4d8e953b0a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 28 Jan 2007 22:45:22 +0000 Subject: Andreas Rieke added extra infof() for when a connection is not re-used due to SSL conditions not being the same --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 01751a380..bc896b39d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2047,6 +2047,10 @@ ConnectionExists(struct SessionHandle *data, ssl options as well */ if(!Curl_ssl_config_matches(&needle->ssl_config, &check->ssl_config)) { + infof(data, + "Connection #%ld has different SSL parameters, " + "can't reuse\n", + check->connectindex ); continue; } } -- cgit v1.2.1 From 49c4d9c9cd6ef5354ea68e8ace79fbe3cc5eae9d Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 31 Jan 2007 19:47:49 +0000 Subject: add debug messages for initialization failures --- lib/url.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bc896b39d..63c93f1b1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -485,14 +485,17 @@ CURLcode Curl_open(struct SessionHandle **curl) /* Very simple start-up: alloc the struct, init it with zeroes and return */ data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle)); - if(!data) + if(!data) { /* this is a very serious error */ + DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n")); return CURLE_OUT_OF_MEMORY; + } data->magic = CURLEASY_MAGIC_NUMBER; #ifdef USE_ARES if(ARES_SUCCESS != ares_init(&data->state.areschannel)) { + DEBUGF(fprintf(stderr, "Error: ares_init failed\n")); free(data); return CURLE_FAILED_INIT; } @@ -503,8 +506,10 @@ CURLcode Curl_open(struct SessionHandle **curl) /* We do some initial setup here, all those fields that can't be just 0 */ data->state.headerbuff=(char*)malloc(HEADERSIZE); - if(!data->state.headerbuff) + if(!data->state.headerbuff) { + DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); res = CURLE_OUT_OF_MEMORY; + } else { data->state.headersize=HEADERSIZE; -- cgit v1.2.1 From 54db98c220255737456b1311cb9534c9e95215c6 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 1 Feb 2007 01:42:13 +0000 Subject: compiler warning fix --- lib/url.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 63c93f1b1..916d2a63c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -375,19 +375,29 @@ CURLcode Curl_close(struct SessionHandle *data) /* create a connection cache of a private or multi type */ struct conncache *Curl_mk_connc(int type, - int amount) /* set -1 to use default */ + long amount) /* set -1 to use default */ { /* It is subject for debate how many default connections to have for a multi connection cache... */ - int default_amount = amount == -1? - ((type == CONNCACHE_PRIVATE)?5:10):amount; + struct conncache *c; + long default_amount; + + if (type == CONNCACHE_PRIVATE) { + default_amount = (amount < 0) ? 5 : amount; + } + else { + default_amount = (amount < 0) ? 10 : amount; + } c= calloc(sizeof(struct conncache), 1); if(!c) return NULL; - c->connects = calloc(sizeof(struct connectdata *), default_amount); + if ((size_t)(default_amount) > ((size_t)-1) / sizeof(struct connectdata *)) + default_amount = ((size_t)-1) / sizeof(struct connectdata *); + + c->connects = calloc(sizeof(struct connectdata *), (size_t)default_amount); if(!c->connects) { free(c); return NULL; -- cgit v1.2.1 From 138b4f27b46475e4d28ae8bb96ad9ae1395faabc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 3 Feb 2007 09:33:54 +0000 Subject: - Manfred Schwarb reported that socks5 support was broken and help us pinpoint the problem. The code now tries harder to use httproxy and proxy where apppropriate, as not all proxies are HTTP... --- lib/url.c | 62 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 916d2a63c..8b49033f3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2084,8 +2084,9 @@ ConnectionExists(struct SessionHandle *data, } } else { /* The requested needle connection is using a proxy, - is the checked one using the same? */ - if(check->bits.httpproxy && + is the checked one using the same host, port and type? */ + if(check->bits.proxy && + (needle->proxytype == check->proxytype) && strequal(needle->proxy.name, check->proxy.name) && needle->port == check->port) { /* This is the same proxy connection, use it! */ @@ -2240,10 +2241,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data, { CURLcode result; Curl_addrinfo *addr; - char *hostname = conn->bits.httpproxy?conn->proxy.name:conn->host.name; + char *hostname = conn->bits.proxy?conn->proxy.name:conn->host.name; infof(data, "About to connect() to %s%s port %d (#%d)\n", - conn->bits.httpproxy?"proxy ":"", + conn->bits.proxy?"proxy ":"", hostname, conn->port, conn->connectindex); /************************************************************* @@ -2287,7 +2288,7 @@ static CURLcode ConnectPlease(struct SessionHandle *data, static void verboseconnect(struct connectdata *conn) { infof(conn->data, "Connected to %s (%s) port %d (#%d)\n", - conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, + conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, conn->ip_addr_str, conn->port, conn->connectindex); } @@ -2766,9 +2767,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->connectindex = -1; /* no index */ - conn->bits.httpproxy = (bool)(data->set.proxy /* http proxy or not */ - && *data->set.proxy - && (data->set.proxytype == CURLPROXY_HTTP)); + conn->proxytype = data->set.proxytype; /* type */ + conn->bits.proxy = (bool)(data->set.proxy && *data->set.proxy); + conn->bits.httpproxy = (bool)(conn->bits.proxy + && (conn->proxytype == CURLPROXY_HTTP)); proxy = data->set.proxy; /* if global proxy is set, this is it */ /* Default protocol-independent behavior doesn't support persistent @@ -2867,9 +2869,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, #ifndef CURL_DISABLE_HTTP /************************************************************* - * Detect what (if any) proxy to use + * Detect what (if any) proxy to use. Remember that this selects a host + * name and is not limited to HTTP proxies only. *************************************************************/ - if(!conn->bits.httpproxy) { + if(!proxy) { /* If proxy was not specified, we check for default proxy environment * variables, to enable i.e Lynx compliance: * @@ -2964,11 +2967,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(proxy && *proxy) { long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); - /* force this to become HTTP */ - conn->protocol = PROT_HTTP | bits; proxy_alloc=TRUE; /* this needs to be freed later */ - conn->bits.httpproxy = TRUE; + + if(conn->proxytype == CURLPROXY_HTTP) { + /* force this connection's protocol to become HTTP */ + conn->protocol = PROT_HTTP | bits; + conn->bits.httpproxy = TRUE; + } } } /* if (!nope) - it wasn't specified non-proxy */ } /* NO_PROXY wasn't specified or '*' */ @@ -3081,7 +3087,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->remote_port = (unsigned short)port; conn->protocol |= PROT_FTP; - if(proxy && *proxy && !data->set.tunnel_thru_httpproxy) { + if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) { /* Unless we have asked to tunnel ftp operations through the proxy, we switch and use HTTP operations only */ #ifndef CURL_DISABLE_HTTP @@ -3686,17 +3692,16 @@ else { } /* host can change, when doing keepalive with a proxy ! */ - if (conn->bits.httpproxy) { + if (conn->bits.proxy) { free(conn->host.rawalloc); conn->host=old_conn->host; } + else + free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ /* get the newly set value, not the old one */ conn->bits.no_body = old_conn->bits.no_body; - if (!conn->bits.httpproxy) - free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ - /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ conn->bits.chunk = FALSE; /* always assume not chunked unless told @@ -3743,7 +3748,7 @@ else { infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, - conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); + proxy?conn->proxy.dispname:conn->host.dispname); } else { /* @@ -3842,7 +3847,7 @@ else { hostaddr = NULL; /* we'll need to clear conn->dns_entry later in Curl_disconnect() */ - if (conn->bits.httpproxy) + if (conn->bits.proxy) fix_hostname(data, conn, &conn->host); } else { @@ -3961,17 +3966,14 @@ static CURLcode SetupConnection(struct connectdata *conn, *protocol_done = FALSE; /* default to not done */ /************************************************************* - * Send user-agent to HTTP proxies even if the target protocol - * isn't HTTP. + * Set user-agent for HTTP *************************************************************/ - if((conn->protocol&PROT_HTTP) || conn->bits.httpproxy) { - if(data->set.useragent) { - Curl_safefree(conn->allocptr.uagent); - conn->allocptr.uagent = - aprintf("User-Agent: %s\r\n", data->set.useragent); - if(!conn->allocptr.uagent) - return CURLE_OUT_OF_MEMORY; - } + if((conn->protocol&PROT_HTTP) && data->set.useragent) { + Curl_safefree(conn->allocptr.uagent); + conn->allocptr.uagent = + aprintf("User-Agent: %s\r\n", data->set.useragent); + if(!conn->allocptr.uagent) + return CURLE_OUT_OF_MEMORY; } conn->headerbytecount = 0; -- cgit v1.2.1 From 91386937ff120d11f7bf24dc487f00751362a61c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Feb 2007 22:51:32 +0000 Subject: - Michael Wallner provided a patch that adds support for CURLOPT_TIMEOUT_MS and CURLOPT_CONNECTTIMEOUT_MS that, as their names should hint, do the timeouts with millisecond resolution instead. The only restriction to that is the alarm() (sometimes) used to abort name resolves as that uses full seconds. I fixed the FTP response timeout part of the patch. Internally we now count and keep the timeouts in milliseconds but it also means we multiply set timeouts with 1000. The effect of this is that no timeout can be set to more than 2^31 milliseconds (on 32 bit systems), which equals 24.86 days. We probably couldn't before either since the code did *1000 on the timeout values on several places already. --- lib/url.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8b49033f3..076f50ebd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -734,7 +734,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * An FTP option that specifies how quickly an FTP response must be * obtained before it is considered failure. */ - data->set.ftp_response_timeout = va_arg( param , long ); + data->set.ftp_response_timeout = va_arg( param , long ) * 1000; break; case CURLOPT_FTPLISTONLY: /* @@ -1242,12 +1242,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * The maximum time you allow curl to use for a single transfer * operation. */ + data->set.timeout = va_arg(param, long) * 1000L; + break; + + case CURLOPT_TIMEOUT_MS: data->set.timeout = va_arg(param, long); break; + case CURLOPT_CONNECTTIMEOUT: /* * The maximum time you allow curl to use to connect. */ + data->set.connecttimeout = va_arg(param, long) * 1000L; + break; + + case CURLOPT_CONNECTTIMEOUT_MS: data->set.connecttimeout = va_arg(param, long); break; @@ -3828,9 +3837,14 @@ else { /* if timeout is not set, use the connect timeout */ shortest = data->set.connecttimeout; + if(shortest < 1000) + /* the alarm() function only provide integer second resolution, so if + we want to wait less than one second we must bail out already now. */ + return CURLE_OPERATION_TIMEDOUT; + /* alarm() makes a signal get sent when the timeout fires off, and that will abort system calls */ - prev_alarm = alarm((unsigned int) shortest); + prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest)); /* We can expect the conn->created time to be "now", as that was just recently set in the beginning of this function and nothing slow has been done since then until now. */ -- cgit v1.2.1 From 28b932fb4ef14b8b9ebda6823c98fbedad6be4b2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Feb 2007 21:13:47 +0000 Subject: - Shmulik Regev fixed so that the final CRLF of HTTP response headers are sent to the debug callback. - Shmulik Regev added CURLOPT_HTTP_CONTENT_DECODING and CURLOPT_HTTP_TRANSFER_DECODING that if set to zero will disable libcurl's internal decoding of content or transfer encoded content. This may be preferable in cases where you use libcurl for proxy purposes or similar. The command line tool got a --raw option to disable both at once. --- lib/url.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 076f50ebd..148d7b2bb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1725,6 +1725,19 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ssh_private_key = va_arg(param, char *); break; + case CURLOPT_HTTP_TRANSFER_DECODING: + /* + * disable libcurl transfer encoding is used + */ + data->set.http_te_skip = (bool)(0 == va_arg(param, long)); + break; + + case CURLOPT_HTTP_CONTENT_DECODING: + /* + * raw data passed to the application when content encoding is used + */ + data->set.http_ce_skip = (bool)(0 == va_arg(param, long)); + break; default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From cbf58d88d0a84042d9dd8a7a6b1644f15242cf02 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 18 Feb 2007 23:02:42 +0000 Subject: - Jeff Pohlmeyer identified two problems: first a rather obscure problem with the multi interface and connection re-use that could make a curl_multi_remove_handle() ruin a pointer in another handle. The second problem was less of an actual problem but more of minor quirk: the re-using of connections wasn't properly checking if the connection was marked for closure. --- lib/url.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 148d7b2bb..6d1fa0459 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2030,7 +2030,8 @@ ConnectionExists(struct SessionHandle *data, from the multi */ } - infof(data, "Examining connection #%ld for reuse\n", check->connectindex); + DEBUGF(infof(data, "Examining connection #%ld for reuse\n", + check->connectindex)); if(check->inuse && !canPipeline) { /* can only happen within multi handles, and means that another easy @@ -2056,11 +2057,11 @@ ConnectionExists(struct SessionHandle *data, continue; } - if (data->state.is_in_pipeline && check->bits.close) { - /* Don't pick a connection that is going to be closed */ - infof(data, "Connection #%ld has been marked for close, can't reuse\n", - check->connectindex); - continue; + if (check->bits.close) { + /* Don't pick a connection that is going to be closed. */ + infof(data, "Connection #%ld has been marked for close, can't reuse\n", + check->connectindex); + continue; } if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) @@ -4136,8 +4137,9 @@ CURLcode Curl_async_resolved(struct connectdata *conn, CURLcode Curl_done(struct connectdata **connp, - CURLcode status, bool premature) /* an error if this is called after an - error was detected */ + CURLcode status, /* an error if this is called after an + error was detected */ + bool premature) { CURLcode result; struct connectdata *conn = *connp; -- cgit v1.2.1 From 17e8d60c01f8f020e3738db855584f23fb892a04 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 19 Feb 2007 11:53:54 +0000 Subject: - Robson Braga Araujo made passive FTP transfers work with SOCKS (both 4 and 5). --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6d1fa0459..692e66c2d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2287,13 +2287,15 @@ static CURLcode ConnectPlease(struct SessionHandle *data, switch(data->set.proxytype) { case CURLPROXY_SOCKS5: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn); + result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn); break; case CURLPROXY_HTTP: /* do nothing here. handled later. */ break; case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn); + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, + FIRSTSOCKET, conn); break; default: failf(data, "unknown proxytype option given"); -- cgit v1.2.1 From 1045b8d3828db484bb7e1f8162362d10cc21d2f3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 19 Feb 2007 12:20:32 +0000 Subject: - Shmulik Regev found a memory leak in re-used HTTPS connections, at least when the multi interface was used. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 692e66c2d..3bd8dcb6d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1786,6 +1786,8 @@ static void conn_free(struct connectdata *conn) Curl_destroy_thread_data(&conn->async); #endif + Curl_ssl_close(conn); + Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ -- cgit v1.2.1 From 2f5e99ca02b6716fdac59c299ab7738a2077743d Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Tue, 20 Feb 2007 22:02:11 +0000 Subject: New FTP CCC functionality - adds passive and active mode to accomodate for different server behaviour --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3bd8dcb6d..05920b72e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1156,7 +1156,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_FTP_SSL_CCC: - data->set.ftp_use_ccc = (bool)(0 != va_arg(param, long)); + data->set.ftp_ccc = va_arg(param, long); break; case CURLOPT_FTP_SKIP_PASV_IP: -- cgit v1.2.1 From 48029d7e745f62f4088955032842a671f3215579 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 21 Feb 2007 05:48:07 +0000 Subject: fix compiler warning "enumerated type mixed with another type" --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 05920b72e..0368fee3a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1156,7 +1156,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_FTP_SSL_CCC: - data->set.ftp_ccc = va_arg(param, long); + data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long); break; case CURLOPT_FTP_SKIP_PASV_IP: -- cgit v1.2.1 From f19d333ef6b067809cb2b0c153fbd3f5db4321a1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 21 Feb 2007 21:59:40 +0000 Subject: - Ravi Pratap provided work on libcurl making pipelining more robust and fixing some bugs: o Don't mix GET and POST requests in a pipeline o Fix the order in which requests are dispatched from the pipeline o Fixed several curl bugs with pipelining when the server is returning chunked encoding: * Added states to chunked parsing for final CRLF * Rewind buffer after parsing chunk with data remaining * Moved chunked header initializing to a spot just before receiving headers --- lib/url.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0368fee3a..4ca629cb2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -164,6 +164,8 @@ static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipe); +static struct SessionHandle* gethandleathead(struct curl_llist *pipe); + #define MAX_PIPELINE_LENGTH 5 /* @@ -1973,6 +1975,16 @@ bool Curl_isHandleAtHead(struct SessionHandle *handle, return FALSE; } +static struct SessionHandle* gethandleathead(struct curl_llist *pipe) +{ + struct curl_llist_element *curr = pipe->head; + if (curr) { + return (struct SessionHandle *) curr->ptr; + } + + return NULL; +} + static void signalPipeClose(struct curl_llist *pipe) { struct curl_llist_element *curr; @@ -2017,6 +2029,7 @@ ConnectionExists(struct SessionHandle *data, for(i=0; i< data->state.connc->num; i++) { bool match = FALSE; + int pipeLen = 0; /* * Note that if we use a HTTP proxy, we check connections to that * proxy and not to the actual remote server. @@ -2026,18 +2039,20 @@ ConnectionExists(struct SessionHandle *data, /* NULL pointer means not filled-in entry */ continue; + pipeLen = check->send_pipe->size + check->recv_pipe->size; + if (check->connectindex == -1) { check->connectindex = i; /* Set this appropriately since it might have been set to -1 when the easy was removed from the multi */ } - DEBUGF(infof(data, "Examining connection #%ld for reuse\n", - check->connectindex)); + DEBUGF(infof(data, "Examining connection #%ld for reuse \ + (pipeLen = %ld)\n", check->connectindex, pipeLen)); - if(check->inuse && !canPipeline) { + if(pipeLen > 0 && !canPipeline) { /* can only happen within multi handles, and means that another easy - handle is using this connection */ + handle is using this connection */ continue; } @@ -2052,13 +2067,26 @@ ConnectionExists(struct SessionHandle *data, } #endif - if (check->send_pipe->size + - check->recv_pipe->size >= MAX_PIPELINE_LENGTH) { + if (pipeLen >= MAX_PIPELINE_LENGTH) { infof(data, "Connection #%ld has its pipeline full, can't reuse\n", check->connectindex); continue; } + if (canPipeline) { + /* Make sure the pipe has only GET requests */ + struct SessionHandle* sh = gethandleathead(check->send_pipe); + struct SessionHandle* rh = gethandleathead(check->recv_pipe); + if (sh) { + if(!IsPipeliningPossible(sh)) + continue; + } + else if (rh) { + if(!IsPipeliningPossible(rh)) + continue; + } + } + if (check->bits.close) { /* Don't pick a connection that is going to be closed. */ infof(data, "Connection #%ld has been marked for close, can't reuse\n", @@ -3731,8 +3759,6 @@ else { /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ - conn->bits.chunk = FALSE; /* always assume not chunked unless told - otherwise */ Curl_safefree(old_conn->user); Curl_safefree(old_conn->passwd); -- cgit v1.2.1 From 4937281ddccbec1daf007257f1732497cb7d62a0 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 22 Feb 2007 07:39:45 +0000 Subject: compiler warning fix --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4ca629cb2..e777d2a1f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2029,7 +2029,7 @@ ConnectionExists(struct SessionHandle *data, for(i=0; i< data->state.connc->num; i++) { bool match = FALSE; - int pipeLen = 0; + size_t pipeLen = 0; /* * Note that if we use a HTTP proxy, we check connections to that * proxy and not to the actual remote server. -- cgit v1.2.1 From c514a2a89aa1c1e06b70405eedb4e1f70b27fd10 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Mon, 26 Feb 2007 04:24:26 +0000 Subject: Removed inclusion of and in .c-files since they're already included through "setup.h". --- lib/url.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e777d2a1f..64a145cdb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -30,12 +30,6 @@ #include #include #include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif #include #ifdef WIN32 @@ -78,7 +72,8 @@ #ifndef HAVE_SOCKET #error "We can't compile without socket() support!" #endif -#endif + +#endif /* WIN32 */ #ifdef USE_LIBIDN #include -- cgit v1.2.1 From 060f7ca2d2a7f5c8845a62a143c1d9fa988d1269 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 27 Feb 2007 22:12:15 +0000 Subject: - Hang Kin Lau found and fixed: When I use libcurl to connect to an https server through a proxy and have the remote https server port set using the CURLOPT_PORT option, protocol gets reset to http from https after the first request. User defined URL was modified internally by libcurl and subsequent reuse of the easy handle may lead to connection using a different protocol (if not originally http). I found that libcurl hardcoded the protocol to "http" when it tries to regenerate the URL if CURLOPT_PORT is set. I tried to fix the problem as follows and it's working fine so far --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 64a145cdb..87a07736e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3590,8 +3590,8 @@ else { /* we need to create new URL with the new port number */ char *url; - url = aprintf("http://%s:%d%s", conn->host.name, conn->remote_port, - data->reqdata.path); + url = aprintf("%s://%s:%d%s", conn->protostr, conn->host.name, + conn->remote_port, data->reqdata.path); if(!url) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 85daec253cf5a6e1eb3f023e76180f553c715de8 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 7 Mar 2007 22:42:05 +0000 Subject: Honour --ftp-ssl-control on ftps:// URLs to allow encrypted control and unencrypted data connections. --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 87a07736e..b80d79239 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3124,7 +3124,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(strequal(conn->protostr, "FTPS")) { #ifdef USE_SSL conn->protocol |= PROT_FTPS|PROT_SSL; - conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */ + /* send data securely unless specifically requested otherwise */ + conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLFTPSSL_CONTROL; port = PORT_FTPS; #else failf(data, LIBCURL_NAME -- cgit v1.2.1 From 09c70dec08529a2a9c552681c8e7c5c1c3f3a6ae Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 10 Mar 2007 22:51:20 +0000 Subject: Eygene Ryabinkin fixed a use-after-free issue with HTTP transfers with the multi interface --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b80d79239..644cec39a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4240,6 +4240,10 @@ CURLcode Curl_done(struct connectdata **connp, infof(data, "Connection #%ld to host %s left intact\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); + + *connp = NULL; /* to make the caller of this function better detect that + this connection is handed over and no longer used from + this point on */ } return result; -- cgit v1.2.1 From 20b9ab49a75b14b6aad3c5c67d504f1bfd8e6bd5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 11 Mar 2007 22:48:58 +0000 Subject: can just as well NULLify the pointer in a single spot --- lib/url.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 644cec39a..2fcc31f33 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4223,9 +4223,6 @@ CURLcode Curl_done(struct connectdata **connp, if(data->set.reuse_forbid || conn->bits.close) { CURLcode res2 = Curl_disconnect(conn); /* close the connection */ - *connp = NULL; /* to make the caller of this function better detect that - this was actually killed here */ - /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ if(!result && res2) @@ -4240,12 +4237,13 @@ CURLcode Curl_done(struct connectdata **connp, infof(data, "Connection #%ld to host %s left intact\n", conn->connectindex, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); - - *connp = NULL; /* to make the caller of this function better detect that - this connection is handed over and no longer used from - this point on */ } + *connp = NULL; /* to make the caller of this function better detect that + this was either closed or handed over to the connection + cache here, and therefore cannot be used from this point on + */ + return result; } -- cgit v1.2.1 From f9a339a22562f9621fd985c87fd84116878661e2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Mar 2007 22:24:33 +0000 Subject: fix debug message --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2fcc31f33..7ff268e0a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2042,8 +2042,8 @@ ConnectionExists(struct SessionHandle *data, from the multi */ } - DEBUGF(infof(data, "Examining connection #%ld for reuse \ - (pipeLen = %ld)\n", check->connectindex, pipeLen)); + DEBUGF(infof(data, "Examining connection #%ld for reuse, " + "(pipeLen = %ld)\n", check->connectindex, pipeLen)); if(pipeLen > 0 && !canPipeline) { /* can only happen within multi handles, and means that another easy -- cgit v1.2.1 From 0dd1219668de43b675a0f3f1c7521b5f823c6895 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Sat, 24 Mar 2007 02:15:20 +0000 Subject: Fixed a memory leak when specifying a proxy with a file: URL and added test case 288 to verify it. --- lib/url.c | 129 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 69 insertions(+), 60 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7ff268e0a..5a882a3b4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2767,8 +2767,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, char passwd[MAX_CURL_PASSWORD_LENGTH]; int rc; bool reuse; - char *proxy; - bool proxy_alloc = FALSE; + char *proxy = NULL; #ifndef USE_ARES #ifdef SIGALRM @@ -2821,7 +2820,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.proxy = (bool)(data->set.proxy && *data->set.proxy); conn->bits.httpproxy = (bool)(conn->bits.proxy && (conn->proxytype == CURLPROXY_HTTP)); - proxy = data->set.proxy; /* if global proxy is set, this is it */ + /* Default protocol-independent behavior doesn't support persistent connections, so we set this to force-close. Protocols that support @@ -2917,6 +2916,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; } + if (data->set.proxy) { + proxy = strdup(data->set.proxy); /* if global proxy is set, this is it */ + if(NULL == proxy) { + failf(data, "memory shortage"); + return CURLE_OUT_OF_MEMORY; + } + } + /* proxy must be freed later unless NULL */ + #ifndef CURL_DISABLE_HTTP /************************************************************* * Detect what (if any) proxy to use. Remember that this selects a host @@ -3018,8 +3026,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(proxy && *proxy) { long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); - proxy_alloc=TRUE; /* this needs to be freed later */ - if(conn->proxytype == CURLPROXY_HTTP) { /* force this connection's protocol to become HTTP */ conn->protocol = PROT_HTTP | bits; @@ -3044,35 +3050,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, reurl = aprintf("%s://%s", conn->protostr, data->change.url); - if(!reurl) + if(!reurl) { + Curl_safefree(proxy); return CURLE_OUT_OF_MEMORY; + } data->change.url = reurl; data->change.url_alloc = TRUE; /* free this later */ conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } -#ifndef CURL_DISABLE_HTTP - /************************************************************ - * RESUME on a HTTP page is a tricky business. First, let's just check that - * 'range' isn't used, then set the range parameter and leave the resume as - * it is to inform about this situation for later use. We will then - * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later) - * server, we will get the document resumed. If we talk to a HTTP/1.0 - * server, we just fail since we can't rewind the file writing from within - * this function. - ***********************************************************/ - if(data->reqdata.resume_from) { - if(!data->reqdata.use_range) { - /* if it already was in use, we just skip this */ - data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", data->reqdata.resume_from); - if(!data->reqdata.range) - return CURLE_OUT_OF_MEMORY; - data->reqdata.rangestringalloc = TRUE; /* mark as allocated */ - data->reqdata.use_range = 1; /* switch on range usage */ - } - } -#endif /************************************************************* * Setup internals depending on protocol *************************************************************/ @@ -3206,6 +3193,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else failf(data, LIBCURL_NAME " was built with TELNET disabled!"); + return CURLE_UNSUPPORTED_PROTOCOL; #endif } else if (strequal(conn->protostr, "DICT")) { @@ -3219,6 +3207,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else failf(data, LIBCURL_NAME " was built with DICT disabled!"); + return CURLE_UNSUPPORTED_PROTOCOL; #endif } else if (strequal(conn->protostr, "LDAP")) { @@ -3232,6 +3221,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else failf(data, LIBCURL_NAME " was built with LDAP disabled!"); + return CURLE_UNSUPPORTED_PROTOCOL; #endif } else if (strequal(conn->protostr, "FILE")) { @@ -3240,25 +3230,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_do = Curl_file; conn->curl_done = Curl_file_done; - - /* anyway, this is supposed to be the connect function so we better - at least check that the file is present here! */ - result = Curl_file_connect(conn); - - /* Setup a "faked" transfer that'll do nothing */ - if(CURLE_OK == result) { - conn->data = data; - conn->bits.tcpconnect = TRUE; /* we are "connected */ - ConnectionStore(data, conn); - - result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ - } - - return result; #else failf(data, LIBCURL_NAME " was built with FILE disabled!"); + return CURLE_UNSUPPORTED_PROTOCOL; #endif } else if (strequal(conn->protostr, "TFTP")) { @@ -3297,6 +3272,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #else failf(data, LIBCURL_NAME " was built with TFTP disabled!"); + return CURLE_UNSUPPORTED_PROTOCOL; #endif } else if (strequal(conn->protostr, "SCP")) { @@ -3344,21 +3320,11 @@ else { char *prox_portno; char *endofprot; - /* We need to make a duplicate of the proxy so that we can modify the - string safely. If 'proxy_alloc' is TRUE, the string is already - allocated and we can treat it as duplicated. */ - char *proxydup=proxy_alloc?proxy:strdup(proxy); - /* We use 'proxyptr' to point to the proxy name from now on... */ - char *proxyptr=proxydup; + char *proxyptr=proxy; char *portptr; char *atsign; - if(NULL == proxydup) { - failf(data, "memory shortage"); - return CURLE_OUT_OF_MEMORY; - } - /* We do the proxy host string parsing here. We want the host name and the * port name. Accept a protocol:// prefix, even though it should just be * ignored. @@ -3404,15 +3370,15 @@ else { atsign = strdup(atsign+1); /* the right side of the @-letter */ if(atsign) { - free(proxydup); /* free the former proxy string */ - proxydup = proxyptr = atsign; /* now use this instead */ + free(proxy); /* free the former proxy string */ + proxy = proxyptr = atsign; /* now use this instead */ } else res = CURLE_OUT_OF_MEMORY; } if(res) { - free(proxydup); /* free the allocated proxy string */ + free(proxy); /* free the allocated proxy string */ return res; } } @@ -3455,12 +3421,33 @@ else { conn->proxy.rawalloc = strdup(proxyptr); conn->proxy.name = conn->proxy.rawalloc; - free(proxydup); /* free the duplicate pointer and not the modified */ - proxy = NULL; /* this may have just been freed */ + free(proxy); + proxy = NULL; if(!conn->proxy.rawalloc) return CURLE_OUT_OF_MEMORY; } + /*********************************************************************** + * file: is a special case in that it doesn't need a network connection + ***********************************************************************/ + if (strequal(conn->protostr, "FILE")) { + /* anyway, this is supposed to be the connect function so we better + at least check that the file is present here! */ + result = Curl_file_connect(conn); + + /* Setup a "faked" transfer that'll do nothing */ + if(CURLE_OK == result) { + conn->data = data; + conn->bits.tcpconnect = TRUE; /* we are "connected */ + ConnectionStore(data, conn); + + result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ + -1, NULL); /* no upload */ + } + + return result; + } + /************************************************************* * If the protocol is using SSL and HTTP proxy is used, we set * the tunnel_proxy bit. @@ -3678,6 +3665,28 @@ else { if(!conn->user || !conn->passwd) return CURLE_OUT_OF_MEMORY; +#ifndef CURL_DISABLE_HTTP + /************************************************************ + * RESUME on a HTTP page is a tricky business. First, let's just check that + * 'range' isn't used, then set the range parameter and leave the resume as + * it is to inform about this situation for later use. We will then + * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later) + * server, we will get the document resumed. If we talk to a HTTP/1.0 + * server, we just fail since we can't rewind the file writing from within + * this function. + ***********************************************************/ + if(data->reqdata.resume_from) { + if(!data->reqdata.use_range) { + /* if it already was in use, we just skip this */ + data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", data->reqdata.resume_from); + if(!data->reqdata.range) + return CURLE_OUT_OF_MEMORY; + data->reqdata.rangestringalloc = TRUE; /* mark as allocated */ + data->reqdata.use_range = 1; /* switch on range usage */ + } + } +#endif + /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a @@ -3797,7 +3806,7 @@ else { infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, - proxy?conn->proxy.dispname:conn->host.dispname); + conn->proxy.name?conn->proxy.dispname:conn->host.dispname); } else { /* -- cgit v1.2.1 From 2bd1d7e996e8c781f14af8d3e7d0ffbd4033d5f1 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Sat, 24 Mar 2007 17:23:01 +0000 Subject: Fixed a couple of compile problems. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5a882a3b4..d11ebd3a0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3430,6 +3430,7 @@ else { /*********************************************************************** * file: is a special case in that it doesn't need a network connection ***********************************************************************/ +#ifndef CURL_DISABLE_FILE if (strequal(conn->protostr, "FILE")) { /* anyway, this is supposed to be the connect function so we better at least check that the file is present here! */ @@ -3447,6 +3448,7 @@ else { return result; } +#endif /************************************************************* * If the protocol is using SSL and HTTP proxy is used, we set -- cgit v1.2.1 From d6eca8922960f2e3bf2cd07eef3eebbdb7ee265a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 25 Mar 2007 01:59:52 +0000 Subject: fix compiler warning --- lib/url.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d11ebd3a0..04f1aa497 100644 --- a/lib/url.c +++ b/lib/url.c @@ -195,6 +195,10 @@ RETSIGTYPE alarmfunc(int sig) #endif /* WIN32 */ #endif /* USE_ARES */ +#ifdef CURL_DISABLE_VERBOSE_STRINGS +#define verboseconnect(x) do { } while (0) +#endif + void Curl_safefree(void *ptr) { if(ptr) @@ -2289,11 +2293,13 @@ static CURLcode ConnectPlease(struct SessionHandle *data, { CURLcode result; Curl_addrinfo *addr; +#ifndef CURL_DISABLE_VERBOSE_STRINGS char *hostname = conn->bits.proxy?conn->proxy.name:conn->host.name; infof(data, "About to connect() to %s%s port %d (#%d)\n", conn->bits.proxy?"proxy ":"", hostname, conn->port, conn->connectindex); +#endif /************************************************************* * Connect to server/proxy @@ -2335,12 +2341,14 @@ static CURLcode ConnectPlease(struct SessionHandle *data, /* * verboseconnect() displays verbose information after a connect */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS static void verboseconnect(struct connectdata *conn) { infof(conn->data, "Connected to %s (%s) port %d (#%d)\n", conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, conn->ip_addr_str, conn->port, conn->connectindex); } +#endif int Curl_protocol_getsock(struct connectdata *conn, curl_socket_t *socks, @@ -2481,6 +2489,14 @@ static bool tld_check_name(struct SessionHandle *data, size_t err_pos; char *uc_name = NULL; int rc; +#ifndef CURL_DISABLE_VERBOSE_STRINGS + char *tld_errmsg; +#ifndef HAVE_TLD_STRERROR + char no_msg[] = ""; +#endif +#else + (void)data; +#endif /* Convert (and downcase) ACE-name back into locale's character set */ rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); @@ -2488,24 +2504,21 @@ static bool tld_check_name(struct SessionHandle *data, return (FALSE); rc = tld_check_lz(uc_name, &err_pos, NULL); - if (rc == TLD_INVALID) - infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if (rc != TLD_SUCCESS) #ifdef HAVE_TLD_STRERROR - tld_strerror((Tld_rc)rc), + tld_errmsg = tld_strerror((Tld_rc)rc); #else - "", + tld_errmsg = no_msg; #endif - err_pos, uc_name[err_pos], - uc_name[err_pos] & 255); + if (rc == TLD_INVALID) + infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", + tld_errmsg, err_pos, uc_name[err_pos], + uc_name[err_pos] & 255); else if (rc != TLD_SUCCESS) - infof(data, "WARNING: TLD check for %s failed; %s\n", - uc_name, -#ifdef HAVE_TLD_STRERROR - tld_strerror((Tld_rc)rc) -#else - "" -#endif - ); + infof(data, "WARNING: TLD check for %s failed; %s\n", + uc_name, tld_errmsg); +#endif /* CURL_DISABLE_VERBOSE_STRINGS */ if (uc_name) idn_free(uc_name); return (bool)(rc == TLD_SUCCESS); -- cgit v1.2.1 From fa0780bb91eae08e3c9fed407beb668c647c5ced Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 25 Mar 2007 03:20:17 +0000 Subject: fix compiler warning --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 04f1aa497..a83707dac 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2507,7 +2507,7 @@ static bool tld_check_name(struct SessionHandle *data, #ifndef CURL_DISABLE_VERBOSE_STRINGS if (rc != TLD_SUCCESS) #ifdef HAVE_TLD_STRERROR - tld_errmsg = tld_strerror((Tld_rc)rc); + tld_errmsg = (char *)tld_strerror((Tld_rc)rc); #else tld_errmsg = no_msg; #endif -- cgit v1.2.1 From fba4cd0e625cdba3561b3530317ba87ae348aeaf Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 26 Mar 2007 23:23:46 +0000 Subject: Internal function Curl_select() renamed to Curl_socket_ready() --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a83707dac..43853f367 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1890,7 +1890,7 @@ static bool SocketIsDead(curl_socket_t sock) int sval; bool ret_val = TRUE; - sval = Curl_select(sock, CURL_SOCKET_BAD, 0); + sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0); if(sval == 0) /* timeout */ ret_val = FALSE; -- cgit v1.2.1 From 25c064c8888134be91e157d6542e4667b8cf5742 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Wed, 28 Mar 2007 04:23:33 +0000 Subject: Simplified code around 'tld_errmsg' a bit. --- lib/url.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 43853f367..95eab6da1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2490,10 +2490,7 @@ static bool tld_check_name(struct SessionHandle *data, char *uc_name = NULL; int rc; #ifndef CURL_DISABLE_VERBOSE_STRINGS - char *tld_errmsg; -#ifndef HAVE_TLD_STRERROR - char no_msg[] = ""; -#endif + char *tld_errmsg = ""; #else (void)data; #endif @@ -2508,8 +2505,6 @@ static bool tld_check_name(struct SessionHandle *data, if (rc != TLD_SUCCESS) #ifdef HAVE_TLD_STRERROR tld_errmsg = (char *)tld_strerror((Tld_rc)rc); -#else - tld_errmsg = no_msg; #endif if (rc == TLD_INVALID) infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", -- cgit v1.2.1 From 8a0a7ce3a8db1dd9db36e2858e64f8d80c1f950f Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Wed, 28 Mar 2007 04:44:14 +0000 Subject: Fix compiler warning. --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 95eab6da1..3eec1ccad 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2553,6 +2553,9 @@ static void fix_hostname(struct SessionHandle *data, (void)data; /* never used */ (void)conn; /* never used */ #endif +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)conn; /* never used */ +#endif } /* -- cgit v1.2.1 From bfa0f8c6c271460de31d42eb99d8c4e3a5e12486 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 28 Mar 2007 19:05:43 +0000 Subject: fix compiler warning --- lib/url.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3eec1ccad..3aa7bdcc2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2490,7 +2490,7 @@ static bool tld_check_name(struct SessionHandle *data, char *uc_name = NULL; int rc; #ifndef CURL_DISABLE_VERBOSE_STRINGS - char *tld_errmsg = ""; + char *tld_errmsg = (char *)""; #else (void)data; #endif @@ -2523,6 +2523,13 @@ static bool tld_check_name(struct SessionHandle *data, static void fix_hostname(struct SessionHandle *data, struct connectdata *conn, struct hostname *host) { +#ifndef USE_LIBIDN + (void)data; + (void)conn; +#elif defined(CURL_DISABLE_VERBOSE_STRINGS) + (void)conn; +#endif + /* set the name we use to display the host name */ host->dispname = host->name; @@ -2549,12 +2556,6 @@ static void fix_hostname(struct SessionHandle *data, host->name = host->encalloc; } } -#else - (void)data; /* never used */ - (void)conn; /* never used */ -#endif -#ifdef CURL_DISABLE_VERBOSE_STRINGS - (void)conn; /* never used */ #endif } -- cgit v1.2.1 From a1e5c621c09deae7f21211741a7f6ea994233460 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 29 Mar 2007 12:29:32 +0000 Subject: fix compiler warning --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3aa7bdcc2..10daab687 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2490,7 +2490,8 @@ static bool tld_check_name(struct SessionHandle *data, char *uc_name = NULL; int rc; #ifndef CURL_DISABLE_VERBOSE_STRINGS - char *tld_errmsg = (char *)""; + char nomsg_str[] = ""; + char *tld_errmsg = nomsg_str; #else (void)data; #endif @@ -2502,8 +2503,8 @@ static bool tld_check_name(struct SessionHandle *data, rc = tld_check_lz(uc_name, &err_pos, NULL); #ifndef CURL_DISABLE_VERBOSE_STRINGS - if (rc != TLD_SUCCESS) #ifdef HAVE_TLD_STRERROR + if (rc != TLD_SUCCESS) tld_errmsg = (char *)tld_strerror((Tld_rc)rc); #endif if (rc == TLD_INVALID) -- cgit v1.2.1 From bcf0af9ddb9dd0225017805d18a0b0b4a5236f7a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 3 Apr 2007 13:26:05 +0000 Subject: recover code simplification lost with last commit --- lib/url.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 10daab687..60fe028fb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2490,8 +2490,7 @@ static bool tld_check_name(struct SessionHandle *data, char *uc_name = NULL; int rc; #ifndef CURL_DISABLE_VERBOSE_STRINGS - char nomsg_str[] = ""; - char *tld_errmsg = nomsg_str; + char *tld_errmsg = (char *)""; #else (void)data; #endif -- cgit v1.2.1 From 990b15e40288ad89c423d331b9563d8259284d9c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Apr 2007 20:54:37 +0000 Subject: Rob Jones fixed better #ifdef'ing for a bunch of #include lines. --- lib/url.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 60fe028fb..0ae0197d3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -39,22 +39,30 @@ #ifdef HAVE_SYS_SOCKET_H #include #endif +#ifdef HAVE_NETINET_IN_H #include +#endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_NETDB_H #include +#endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NET_IF_H #include #endif +#ifdef HAVE_SYS_IOCTL_H #include +#endif +#if HAVE_SIGNAL_H #include +#endif #ifdef HAVE_SYS_PARAM_H #include -- cgit v1.2.1 From c321b9f7046e96aa269635d9deafa357a118e88c Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 4 Apr 2007 23:41:35 +0000 Subject: Fixes some more out of memory handling bugs. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0ae0197d3..edbd1157c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2856,6 +2856,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Initialize the pipeline lists */ conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if (!conn->send_pipe || !conn->recv_pipe) + return CURLE_OUT_OF_MEMORY; /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); -- cgit v1.2.1 From 0e05a6329a885a513aefa6c3e698f4cb1f08eb73 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 8 Apr 2007 22:49:38 +0000 Subject: fix out of memory handling issue --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index edbd1157c..3b6e56642 100644 --- a/lib/url.c +++ b/lib/url.c @@ -501,6 +501,9 @@ CURLcode Curl_open(struct SessionHandle **curl) { CURLcode res = CURLE_OK; struct SessionHandle *data; +#ifdef USE_ARES + int status; +#endif /* Very simple start-up: alloc the struct, init it with zeroes and return */ data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle)); @@ -513,10 +516,13 @@ CURLcode Curl_open(struct SessionHandle **curl) data->magic = CURLEASY_MAGIC_NUMBER; #ifdef USE_ARES - if(ARES_SUCCESS != ares_init(&data->state.areschannel)) { + if ((status = ares_init(&data->state.areschannel)) != ARES_SUCCESS) { DEBUGF(fprintf(stderr, "Error: ares_init failed\n")); free(data); - return CURLE_FAILED_INIT; + if (status == ARES_ENOMEM) + return CURLE_OUT_OF_MEMORY; + else + return CURLE_FAILED_INIT; } /* make sure that all other returns from this function should destroy the ares channel before returning error! */ -- cgit v1.2.1 From 5daa6b93679b1e9a630975fef66191ae3bc71ab1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Apr 2007 20:46:40 +0000 Subject: Ravi Pratap provided fixes for HTTP pipelining --- lib/url.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3b6e56642..ddb214d20 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1970,8 +1970,7 @@ static void Curl_printPipeline(struct curl_llist *pipe) curr = pipe->head; while (curr) { struct SessionHandle *data = (struct SessionHandle *) curr->ptr; - infof(data, "Handle in pipeline: %s\n", - data->reqdata.path); + infof(data, "Handle in pipeline: %s\n", data->reqdata.path); curr = curr->next; } } @@ -2010,12 +2009,12 @@ static void signalPipeClose(struct curl_llist *pipe) #ifdef CURLDEBUG /* debug-only code */ if(data->magic != CURLEASY_MAGIC_NUMBER) { /* MAJOR BADNESS */ - fprintf(stderr, "signalPipeClose() found BAAD easy handle\n"); + infof(data, "signalPipeClose() found BAAD easy handle\n"); } - else #endif data->state.pipe_broke = TRUE; + Curl_multi_handlePipeBreak(data); Curl_llist_remove(pipe, curr, NULL); curr = next; } @@ -2060,8 +2059,8 @@ ConnectionExists(struct SessionHandle *data, from the multi */ } - DEBUGF(infof(data, "Examining connection #%ld for reuse, " - "(pipeLen = %ld)\n", check->connectindex, pipeLen)); + DEBUGF(infof(data, "Examining connection #%ld for reuse" + " (pipeLen = %ld)\n", check->connectindex, pipeLen)); if(pipeLen > 0 && !canPipeline) { /* can only happen within multi handles, and means that another easy @@ -2074,12 +2073,26 @@ ConnectionExists(struct SessionHandle *data, yet and until then we don't re-use this connection */ if (!check->ip_addr_str) { infof(data, - "Connection #%ld has not finished name resolve, can't reuse\n", + "Connection #%ld hasn't finished name resolve, can't reuse\n", check->connectindex); continue; } #endif + if ((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { + /* Don't pick a connection that hasn't connected yet or that is going to + get closed. */ + infof(data, "Connection #%ld isn't open enough, can't reuse\n", + check->connectindex); +#ifdef CURLDEBUG + if (check->recv_pipe->size > 0) { + infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", + check->connectindex); + } +#endif + continue; + } + if (pipeLen >= MAX_PIPELINE_LENGTH) { infof(data, "Connection #%ld has its pipeline full, can't reuse\n", check->connectindex); @@ -2100,13 +2113,6 @@ ConnectionExists(struct SessionHandle *data, } } - if (check->bits.close) { - /* Don't pick a connection that is going to be closed. */ - infof(data, "Connection #%ld has been marked for close, can't reuse\n", - check->connectindex); - continue; - } - if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) /* don't do mixed SSL and non-SSL connections */ continue; @@ -2178,15 +2184,11 @@ ConnectionExists(struct SessionHandle *data, check->inuse = TRUE; /* mark this as being in use so that no other handle in a multi stack may nick it */ - if (canPipeline) { /* Mark the connection as being in a pipeline */ check->is_in_pipeline = TRUE; } - check->connectindex = i; /* Set this appropriately since it might have - been set to -1 when the easy was removed - from the multi */ *usethis = check; return TRUE; /* yes, we found one to use! */ } @@ -4069,7 +4071,7 @@ static CURLcode SetupConnection(struct connectdata *conn, return CURLE_OUT_OF_MEMORY; } - conn->headerbytecount = 0; + data->reqdata.keep.headerbytecount = 0; #ifdef CURL_DO_LINEEND_CONV data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ -- cgit v1.2.1 From bc1ae973daafb5881b65e179d2f5ce891acf22bd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 24 Apr 2007 10:18:06 +0000 Subject: Robert Iakobashvili made the 'master_buffer' get allocated first once it is can/will be used as it then makes the common cases save 16KB of data for each easy handle that isn't used for pipelining. --- lib/url.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ddb214d20..659b977d8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1789,6 +1789,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ + Curl_safefree(conn->master_buffer); Curl_llist_destroy(conn->send_pipe, NULL); Curl_llist_destroy(conn->recv_pipe, NULL); @@ -2825,7 +2826,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, to not have to modify everything at once, we allocate a temporary connection data struct and fill in for comparison purposes. */ - conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1); + conn = (struct connectdata *)calloc(1, sizeof(struct connectdata)); if(!conn) { *in_connect = NULL; /* clear the pointer */ return CURLE_OUT_OF_MEMORY; @@ -2835,6 +2836,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, any failure */ *in_connect = conn; + if (data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ + conn->master_buffer = calloc(BUFSIZE, sizeof (char)); + if (!conn->master_buffer) + return CURLE_OUT_OF_MEMORY; + } + /* and we setup a few fields in case we end up actually using this struct */ conn->data = data; /* Setup the association between this connection @@ -3803,6 +3812,7 @@ else { Curl_safefree(old_conn->proxypasswd); Curl_llist_destroy(old_conn->send_pipe, NULL); Curl_llist_destroy(old_conn->recv_pipe, NULL); + Curl_safefree(old_conn->master_buffer); free(old_conn); /* we don't need this anymore */ -- cgit v1.2.1 From ed8cb57151bf0e08641024e1edadb6ba7c25a4a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 25 Apr 2007 20:20:15 +0000 Subject: Sonia Subramanian brought our attention to a problem that happens if you set the CURLOPT_RESUME_FROM or CURLOPT_RANGE options and an existing connection in the connection cache is closed to make room for the new one when you call curl_easy_perform(). It would then wrongly free range-related data in the connection close funtion. --- lib/url.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 659b977d8..1953c886c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1830,16 +1830,6 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_expire(data, 0); /* shut off timers */ Curl_hostcache_prune(data); /* kill old DNS cache entries */ - /* - * The range string is usually freed in curl_done(), but we might - * get here *instead* if we fail prematurely. Thus we need to be able - * to free this resource here as well. - */ - if(data->reqdata.rangestringalloc) { - free(data->reqdata.range); - data->reqdata.rangestringalloc = FALSE; - } - if((conn->ntlm.state != NTLMSTATE_NONE) || (conn->proxyntlm.state != NTLMSTATE_NONE)) { /* Authentication data is a mix of connection-related and sessionhandle- -- cgit v1.2.1 From 7a343a3f60295963ce51185a739c5e4fb1438524 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 27 Apr 2007 08:18:47 +0000 Subject: As a follow-up to the removal of the free of the range data in Curl_done() - this moves and re-arranges how range/resume is setup and freed. --- lib/url.c | 109 +++++++++++++++++++++++++++----------------------------------- 1 file changed, 48 insertions(+), 61 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1953c886c..faa85b1b0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1827,6 +1827,12 @@ CURLcode Curl_disconnect(struct connectdata *conn) NULL, Curl_scan_cache_used); #endif + /* cleanups done even if the connection is re-used */ + if(data->reqdata.rangestringalloc) { + free(data->reqdata.range); + data->reqdata.rangestringalloc = FALSE; + } + Curl_expire(data, 0); /* shut off timers */ Curl_hostcache_prune(data); /* kill old DNS cache entries */ @@ -2746,6 +2752,37 @@ static void llist_dtor(void *user, void *element) /* Do nothing */ } +static CURLcode setup_range(struct SessionHandle *data) +{ + /* + * If we're doing a resumed transfer, we need to setup our stuff + * properly. + */ + struct HandleData *req = &data->reqdata; + + req->resume_from = data->set.set_resume_from; + if (req->resume_from || data->set.set_range) { + if (req->rangestringalloc == TRUE) + free(req->range); + + if(req->resume_from) + req->range = aprintf("%" FORMAT_OFF_T "-", req->resume_from); + else + req->range = strdup(data->set.set_range); + + req->rangestringalloc = req->range?TRUE:FALSE; + + if(!req->range) + return CURLE_OUT_OF_MEMORY; + + /* tell ourselves to fetch this range */ + req->use_range = TRUE; /* enable range download */ + } + else + req->use_range = FALSE; /* disable range download */ + + return CURLE_OK; +} /** * CreateConnection() sets up a new connectdata struct, or re-uses an already @@ -2869,11 +2906,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); +#if 0 /* range status */ data->reqdata.use_range = (bool)(NULL != data->set.set_range); data->reqdata.range = data->set.set_range; /* clone the range setting */ data->reqdata.resume_from = data->set.set_resume_from; +#endif conn->bits.user_passwd = (bool)(NULL != data->set.userpwd); conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd); @@ -3462,17 +3501,17 @@ else { #ifndef CURL_DISABLE_FILE if (strequal(conn->protostr, "FILE")) { /* anyway, this is supposed to be the connect function so we better - at least check that the file is present here! */ + at least check that the file is present here! */ result = Curl_file_connect(conn); /* Setup a "faked" transfer that'll do nothing */ if(CURLE_OK == result) { - conn->data = data; - conn->bits.tcpconnect = TRUE; /* we are "connected */ - ConnectionStore(data, conn); + conn->data = data; + conn->bits.tcpconnect = TRUE; /* we are "connected */ + ConnectionStore(data, conn); result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ + -1, NULL); /* no upload */ } return result; @@ -3696,28 +3735,6 @@ else { if(!conn->user || !conn->passwd) return CURLE_OUT_OF_MEMORY; -#ifndef CURL_DISABLE_HTTP - /************************************************************ - * RESUME on a HTTP page is a tricky business. First, let's just check that - * 'range' isn't used, then set the range parameter and leave the resume as - * it is to inform about this situation for later use. We will then - * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later) - * server, we will get the document resumed. If we talk to a HTTP/1.0 - * server, we just fail since we can't rewind the file writing from within - * this function. - ***********************************************************/ - if(data->reqdata.resume_from) { - if(!data->reqdata.use_range) { - /* if it already was in use, we just skip this */ - data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", data->reqdata.resume_from); - if(!data->reqdata.range) - return CURLE_OUT_OF_MEMORY; - data->reqdata.rangestringalloc = TRUE; /* mark as allocated */ - data->reqdata.use_range = 1; /* switch on range usage */ - } - } -#endif - /************************************************************* * Check the current list of connections to see if we can * re-use an already existing one or if we have to create a @@ -3806,34 +3823,6 @@ else { free(old_conn); /* we don't need this anymore */ - /* - * If we're doing a resumed transfer, we need to setup our stuff - * properly. - */ - data->reqdata.resume_from = data->set.set_resume_from; - if (data->reqdata.resume_from) { - if (data->reqdata.rangestringalloc == TRUE) - free(data->reqdata.range); - data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", - data->reqdata.resume_from); - if(!data->reqdata.range) - return CURLE_OUT_OF_MEMORY; - - /* tell ourselves to fetch this range */ - data->reqdata.use_range = TRUE; /* enable range download */ - data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */ - } - else if (data->set.set_range) { - /* There is a range, but is not a resume, useful for random ftp access */ - data->reqdata.range = strdup(data->set.set_range); - if(!data->reqdata.range) - return CURLE_OUT_OF_MEMORY; - data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */ - data->reqdata.use_range = TRUE; /* enable range download */ - } - else - data->reqdata.use_range = FALSE; /* disable range download */ - *in_connect = conn; /* return this instead! */ infof(data, "Re-using existing connection! (#%ld) with host %s\n", @@ -3848,6 +3837,10 @@ else { ConnectionStore(data, conn); } + result = setup_range(data); + if(result) + return result; + /* Continue connectdata initialization here. */ /* @@ -4226,12 +4219,6 @@ CURLcode Curl_done(struct connectdata **connp, conn->writechannel_inuse) conn->writechannel_inuse = FALSE; - /* cleanups done even if the connection is re-used */ - if(data->reqdata.rangestringalloc) { - free(data->reqdata.range); - data->reqdata.rangestringalloc = FALSE; - } - /* Cleanup possible redirect junk */ if(data->reqdata.newurl) { free(data->reqdata.newurl); -- cgit v1.2.1 From 61edee979f2e34a3957da65f6329d5c24a47fc72 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 27 Apr 2007 08:19:48 +0000 Subject: oops, this was supposed to be properly removed --- lib/url.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index faa85b1b0..77fc67173 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2906,14 +2906,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); -#if 0 - /* range status */ - data->reqdata.use_range = (bool)(NULL != data->set.set_range); - - data->reqdata.range = data->set.set_range; /* clone the range setting */ - data->reqdata.resume_from = data->set.set_resume_from; -#endif - conn->bits.user_passwd = (bool)(NULL != data->set.userpwd); conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd); conn->bits.no_body = data->set.opt_no_body; -- cgit v1.2.1 From 7a0e0c36c549218f74ac5f1d4b679667135a97da Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 27 Apr 2007 08:30:48 +0000 Subject: Move the explictit free of the range string to Curl_close() from Curl_disconnect() since it easy-handle related and not connection-related. --- lib/url.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 77fc67173..6611486a0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -310,6 +310,9 @@ CURLcode Curl_close(struct SessionHandle *data) } } + if(data->reqdata.rangestringalloc) + free(data->reqdata.range); + /* Free the pathbuffer */ Curl_safefree(data->reqdata.pathbuffer); Curl_safefree(data->reqdata.proto.generic); @@ -1827,12 +1830,6 @@ CURLcode Curl_disconnect(struct connectdata *conn) NULL, Curl_scan_cache_used); #endif - /* cleanups done even if the connection is re-used */ - if(data->reqdata.rangestringalloc) { - free(data->reqdata.range); - data->reqdata.rangestringalloc = FALSE; - } - Curl_expire(data, 0); /* shut off timers */ Curl_hostcache_prune(data); /* kill old DNS cache entries */ -- cgit v1.2.1 From 717adfeb96579d1aeda8102ac47d35a67cdc16d0 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Sun, 29 Apr 2007 07:04:29 +0000 Subject: Rearranged some allocs so they will be freed correctly in the error path. --- lib/url.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6611486a0..5ebc9e8b9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2860,14 +2860,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, any failure */ *in_connect = conn; - if (data->multi && Curl_multi_canPipeline(data->multi) && - !conn->master_buffer) { - /* Allocate master_buffer to be used for pipelining */ - conn->master_buffer = calloc(BUFSIZE, sizeof (char)); - if (!conn->master_buffer) - return CURLE_OUT_OF_MEMORY; - } - /* and we setup a few fields in case we end up actually using this struct */ conn->data = data; /* Setup the association between this connection @@ -2894,12 +2886,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->read_pos = 0; conn->buf_len = 0; - /* Initialize the pipeline lists */ - conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if (!conn->send_pipe || !conn->recv_pipe) - return CURLE_OUT_OF_MEMORY; - /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); @@ -2910,6 +2896,20 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + if (data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ + conn->master_buffer = calloc(BUFSIZE, sizeof (char)); + if (!conn->master_buffer) + return CURLE_OUT_OF_MEMORY; + } + + /* Initialize the pipeline lists */ + conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if (!conn->send_pipe || !conn->recv_pipe) + return CURLE_OUT_OF_MEMORY; + /* This initing continues below, see the comment "Continue connectdata * initialization here" */ -- cgit v1.2.1 From 9f72db13c4608d57e8232f355e5b96335d2035f6 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 2 May 2007 19:13:56 +0000 Subject: Fixed an out of memory handling issue with HTTP pipelines. --- lib/url.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5ebc9e8b9..4b8c53399 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1925,8 +1925,8 @@ static bool IsPipeliningEnabled(struct SessionHandle *handle) return FALSE; } -void Curl_addHandleToPipeline(struct SessionHandle *data, - struct curl_llist *pipe) +CURLcode Curl_addHandleToPipeline(struct SessionHandle *data, + struct curl_llist *pipe) { #ifdef CURLDEBUG if(!IsPipeliningPossible(data)) { @@ -1935,7 +1935,9 @@ void Curl_addHandleToPipeline(struct SessionHandle *data, infof(data, "PIPE when no PIPE supposed!\n"); } #endif - Curl_llist_insert_next(pipe, pipe->tail, data); + if (!Curl_llist_insert_next(pipe, pipe->tail, data)) + return CURLE_OUT_OF_MEMORY; + return CURLE_OK; } @@ -1995,6 +1997,9 @@ static void signalPipeClose(struct curl_llist *pipe) { struct curl_llist_element *curr; + if (!pipe) + return; + curr = pipe->head; while (curr) { struct curl_llist_element *next = curr->next; -- cgit v1.2.1 From b6820b26745c819386be03d4150d5006ec33080c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 May 2007 09:24:06 +0000 Subject: remove really annoying debug output that makes life miserable when you do hundreds of parallel transfers... --- lib/url.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4b8c53399..8a280aff4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2058,9 +2058,6 @@ ConnectionExists(struct SessionHandle *data, from the multi */ } - DEBUGF(infof(data, "Examining connection #%ld for reuse" - " (pipeLen = %ld)\n", check->connectindex, pipeLen)); - if(pipeLen > 0 && !canPipeline) { /* can only happen within multi handles, and means that another easy handle is using this connection */ -- cgit v1.2.1 From e71378d3c83c43517e86d2ae792445301fd58aa6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Jun 2007 13:41:50 +0000 Subject: mark connect failures as non-connected when ConnectPlease() fails, like when a connection through a socks proxy doesn't work --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8a280aff4..8165c9298 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2346,6 +2346,8 @@ static CURLcode ConnectPlease(struct SessionHandle *data, break; } } + if(result) + *connected = FALSE; /* mark it as not connected */ return result; } -- cgit v1.2.1 From a1b650ad7be4f8ec2fb486244f2f303434d43dfc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 21 Jun 2007 14:23:38 +0000 Subject: =?UTF-8?q?Gerrit=20Bruchh=E4user=20pointed=20out=20a=20warning=20?= =?UTF-8?q?that=20the=20Intel(R)=20Thread=20Checker=20tool=20reports=20and?= =?UTF-8?q?=20it=20was=20indeed=20a=20legitimate=20one=20and=20it=20is=20o?= =?UTF-8?q?ne=20fixed.=20It=20was=20a=20use=20of=20a=20share=20without=20d?= =?UTF-8?q?oing=20the=20proper=20locking=20first.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8165c9298..789959762 100644 --- a/lib/url.c +++ b/lib/url.c @@ -378,8 +378,11 @@ CURLcode Curl_close(struct SessionHandle *data) #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ /* No longer a dirty share, if it exists */ - if (data->share) + if (data->share) { + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); data->share->dirty--; + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } free(data); return CURLE_OK; -- cgit v1.2.1 From 4cd7f85410ae9590fa4dd274a9c77604b3b8d4fc Mon Sep 17 00:00:00 2001 From: James Housley Date: Wed, 27 Jun 2007 20:15:48 +0000 Subject: Add two new options for the SFTP/SCP/FILE protocols: CURLOPT_NEW_FILE_PERMS and CURLOPT_NEW_DIRECTORY_PERMS. These control the premissions for files and directories created on the remote server. CURLOPT_NEW_FILE_PERMS defaults to 0644 and CURLOPT_NEW_DIRECTORY_PERMS defaults to 0755 --- lib/url.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 789959762..b5b83effb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -595,6 +595,8 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth type */ + data->set.new_file_perms = 0644; /* Default permissions */ + data->set.new_directory_perms = 0755; /* Default permissions */ /* most recent connection is not yet defined */ data->state.lastconnect = -1; @@ -1759,6 +1761,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.http_ce_skip = (bool)(0 == va_arg(param, long)); break; + + case CURLOPT_NEW_FILE_PERMS: + /* + * Uses these permissions instead of 0644 + */ + data->set.new_file_perms = va_arg(param, long); + break; + + case CURLOPT_NEW_DIRECTORY_PERMS: + /* + * Uses these permissions instead of 0755 + */ + data->set.new_directory_perms = va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 54967d2a3ab5559631407f7b7f67ef48c2dda6dd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 1 Jul 2007 22:01:18 +0000 Subject: Thomas J. Moore provided a patch that introduces Kerberos5 support in libcurl. This also makes the options change name to --krb (from --krb4) and CURLOPT_KRBLEVEL (from CURLOPT_KRB4LEVEL) but the old names are still --- lib/url.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b5b83effb..aa2aafe09 100644 --- a/lib/url.c +++ b/lib/url.c @@ -146,9 +146,6 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #define _MPRINTF_REPLACE /* use our functions only */ #include -#ifdef HAVE_KRB4 -#include "krb4.h" -#endif #include "memory.h" /* The last #include file should be: */ @@ -1498,12 +1495,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.localportrange = (int) va_arg(param, long); break; - case CURLOPT_KRB4LEVEL: + case CURLOPT_KRBLEVEL: /* - * A string that defines the krb4 security level. + * A string that defines the kerberos security level. */ - data->set.krb4_level = va_arg(param, char *); - data->set.krb4 = (bool)(NULL != data->set.krb4_level); + data->set.krb_level = va_arg(param, char *); + data->set.krb = (bool)(NULL != data->set.krb_level); break; case CURLOPT_SSL_VERIFYPEER: /* -- cgit v1.2.1 From 8026d94c07cae4185b3e88872fb68ecd071a2c00 Mon Sep 17 00:00:00 2001 From: James Housley Date: Tue, 10 Jul 2007 22:26:32 +0000 Subject: * Finish moving sftp:// into a state machine so it won't block in multi mode * Move scp:// into a state machine so it won't block in multi mode * When available use the full directory entry from the sftp:// server --- lib/url.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index aa2aafe09..dc535c9cd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3361,6 +3361,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_do = Curl_scp_do; conn->curl_done = Curl_scp_done; +#if (LIBSSH2_APINO >= 200706012030) + conn->curl_connecting = Curl_ssh_multi_statemach; + conn->curl_doing = Curl_scp_doing; +#endif (LIBSSH2_APINO >= 200706012030) conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME @@ -3376,14 +3380,18 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_do = Curl_sftp_do; conn->curl_done = Curl_sftp_done; - conn->curl_do_more = (Curl_do_more_func)NULL; +#if (LIBSSH2_APINO >= 200706012030) + conn->curl_connecting = Curl_ssh_multi_statemach; + conn->curl_doing = Curl_sftp_doing; +#endif (LIBSSH2_APINO >= 200706012030) + conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME " was built without LIBSSH2, scp: not supported!"); return CURLE_UNSUPPORTED_PROTOCOL; #endif -} -else { + } + else { /* We fell through all checks and thus we don't support the specified protocol */ failf(data, "Unsupported protocol: %s", conn->protostr); -- cgit v1.2.1 From cf61c8d659692185eb61451ada7a4b90043527bb Mon Sep 17 00:00:00 2001 From: Gunter Knauf Date: Wed, 11 Jul 2007 09:03:22 +0000 Subject: fixed endif comment. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dc535c9cd..24cbaaf89 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3364,7 +3364,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #if (LIBSSH2_APINO >= 200706012030) conn->curl_connecting = Curl_ssh_multi_statemach; conn->curl_doing = Curl_scp_doing; -#endif (LIBSSH2_APINO >= 200706012030) +#endif /* (LIBSSH2_APINO >= 200706012030) */ conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME @@ -3383,7 +3383,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, #if (LIBSSH2_APINO >= 200706012030) conn->curl_connecting = Curl_ssh_multi_statemach; conn->curl_doing = Curl_sftp_doing; -#endif (LIBSSH2_APINO >= 200706012030) +#endif /* (LIBSSH2_APINO >= 200706012030) */ conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME -- cgit v1.2.1 From cf86f8cb78721d04253b0cec9fc01a52456d7448 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 12 Jul 2007 20:15:38 +0000 Subject: Shmulik Regev found an (albeit rare) case where the proxy CONNECT operation could in fact get stuck in an endless loop. --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 24cbaaf89..a12d94d63 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4071,6 +4071,12 @@ static CURLcode SetupConnection(struct connectdata *conn, } *protocol_done = FALSE; /* default to not done */ + /* set proxy_connect_closed to false unconditionally already here since it + is used strictly to provide extra information to a parent function in the + case of proxy CONNECT failures and we must make sure we don't have it + lingering set from a previous invoke */ + conn->bits.proxy_connect_closed = FALSE; + /************************************************************* * Set user-agent for HTTP *************************************************************/ -- cgit v1.2.1 From fee4f8c86dc91ab1861118aa2cc149d87cc4ee85 Mon Sep 17 00:00:00 2001 From: Gunter Knauf Date: Sat, 14 Jul 2007 15:59:01 +0000 Subject: for now unless we do better fixed LIBSSH2_APINO compares to use long constants. --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a12d94d63..127c5df9e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3361,10 +3361,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_do = Curl_scp_do; conn->curl_done = Curl_scp_done; -#if (LIBSSH2_APINO >= 200706012030) +#if defined(LIBSSH2_APINO) && (LIBSSH2_APINO >= 200706012030L) conn->curl_connecting = Curl_ssh_multi_statemach; conn->curl_doing = Curl_scp_doing; -#endif /* (LIBSSH2_APINO >= 200706012030) */ +#endif /* LIBSSH2_APINO && (LIBSSH2_APINO >= 200706012030L) */ conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME @@ -3380,10 +3380,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_do = Curl_sftp_do; conn->curl_done = Curl_sftp_done; -#if (LIBSSH2_APINO >= 200706012030) +#if defined(LIBSSH2_APINO) && (LIBSSH2_APINO >= 200706012030L) conn->curl_connecting = Curl_ssh_multi_statemach; conn->curl_doing = Curl_sftp_doing; -#endif /* (LIBSSH2_APINO >= 200706012030) */ +#endif /* LIBSSH2_APINO && (LIBSSH2_APINO >= 200706012030L) */ conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME -- cgit v1.2.1 From 5ecd56d9646c2adcc70c0369fb6196f62ecc62f4 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 23 Jul 2007 18:51:22 +0000 Subject: Implemented only the parts of Patrick Monnerat's OS/400 patch that renamed some few internal identifiers to avoid conflicts, which could be useful on other platforms. --- lib/url.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 127c5df9e..de4c59db6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -546,10 +546,10 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.err = stderr; /* default stderr to stderr */ /* use fwrite as default function to store output */ - data->set.fwrite = (curl_write_callback)fwrite; + data->set.fwrite_func = (curl_write_callback)fwrite; /* use fread as default function to read input */ - data->set.fread = (curl_read_callback)fread; + data->set.fread_func = (curl_read_callback)fread; /* conversion callbacks for non-ASCII hosts */ data->set.convfromnetwork = (curl_conv_callback)ZERO_NULL; @@ -1380,19 +1380,19 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set data write callback */ - data->set.fwrite = va_arg(param, curl_write_callback); - if(!data->set.fwrite) + data->set.fwrite_func = va_arg(param, curl_write_callback); + if(!data->set.fwrite_func) /* When set to NULL, reset to our internal default function */ - data->set.fwrite = (curl_write_callback)fwrite; + data->set.fwrite_func = (curl_write_callback)fwrite; break; case CURLOPT_READFUNCTION: /* * Read data callback */ - data->set.fread = va_arg(param, curl_read_callback); - if(!data->set.fread) + data->set.fread_func = va_arg(param, curl_read_callback); + if(!data->set.fread_func) /* When set to NULL, reset to our internal default function */ - data->set.fread = (curl_read_callback)fread; + data->set.fread_func = (curl_read_callback)fread; break; case CURLOPT_CONV_FROM_NETWORK_FUNCTION: /* @@ -1416,7 +1416,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * I/O control callback. Might be NULL. */ - data->set.ioctl = va_arg(param, curl_ioctl_callback); + data->set.ioctl_func = va_arg(param, curl_ioctl_callback); break; case CURLOPT_IOCTLDATA: /* @@ -3865,7 +3865,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * * Inherit the proper values from the urldata struct AFTER we have arranged * the persistent connection stuff */ - conn->fread = data->set.fread; + conn->fread_func = data->set.fread_func; conn->fread_in = data->set.in; if ((conn->protocol&PROT_HTTP) && -- cgit v1.2.1 From 813a1107f465197c984ee807f69f916ebfefa212 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Jul 2007 21:48:27 +0000 Subject: #if that should be #ifdef --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index de4c59db6..3f93311f6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -60,7 +60,7 @@ #ifdef HAVE_SYS_IOCTL_H #include #endif -#if HAVE_SIGNAL_H +#ifdef HAVE_SIGNAL_H #include #endif -- cgit v1.2.1 From f1fa7b8ba469d9b8681e30f107b44004695b32e9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 29 Jul 2007 12:54:05 +0000 Subject: Bug report #1759542 (http://curl.haxx.se/bug/view.cgi?id=1759542). A bad use of a socket after it has been closed, when the FTP-SSL data connection is taken down. --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f93311f6..7a8effb1e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1822,7 +1822,8 @@ static void conn_free(struct connectdata *conn) Curl_destroy_thread_data(&conn->async); #endif - Curl_ssl_close(conn); + Curl_ssl_close(conn, FIRSTSOCKET); + Curl_ssl_close(conn, SECONDARYSOCKET); Curl_free_ssl_config(&conn->ssl_config); @@ -1892,7 +1893,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) allocated by libidn */ #endif - Curl_ssl_close(conn); + Curl_ssl_close(conn, FIRSTSOCKET); /* Indicate to all handles on the pipe that we're dead */ if (IsPipeliningEnabled(data)) { -- cgit v1.2.1 From 50c10aa5bf545eedfdbe561116656b6ec12654cd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 1 Aug 2007 21:20:01 +0000 Subject: Patrick Monnerat and I modified libcurl so that now it *copies* all strings passed to it with curl_easy_setopt()! Previously it has always just refered to the data, forcing the user to keep the data around until libcurl is done with it. That is now history and libcurl will instead clone the given strings and keep private copies. --- lib/url.c | 220 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 159 insertions(+), 61 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7a8effb1e..0de87a824 100644 --- a/lib/url.c +++ b/lib/url.c @@ -217,6 +217,59 @@ static void close_connections(struct SessionHandle *data) ; /* empty loop */ } +void Curl_freeset(struct SessionHandle * data) +{ + /* Free all dynamic strings stored in the data->set substructure. */ + enum dupstring i; + for(i=0; i < STRING_LAST; i++) + Curl_safefree(data->set.str[i]); +} + +static CURLcode Curl_setstropt(char **charp, char * s) +{ + /* Release the previous storage at `charp' and replace by a dynamic storage + copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ + + if (*charp) { + free(*charp); + *charp = (char *) NULL; + } + + if (s) { + s = strdup(s); + + if (!s) + return CURLE_OUT_OF_MEMORY; + + *charp = s; + } + + return CURLE_OK; +} + +CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) +{ + CURLcode r; + enum dupstring i; + + /* Copy src->set into dst->set first, then deal with the strings + afterwards */ + dst->set = src->set; + + /* clear all string pointers first */ + memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); + + /* duplicate all strings */ + for(i=0; i< STRING_LAST; i++) { + r = Curl_setstropt(&dst->set.str[i], src->set.str[i]); + if (r != CURLE_OK) + break; + } + + /* If a failure occurred, freeing has to be performed externally. */ + return r; +} + /* * This is the internal function curl_easy_cleanup() calls. This should * cleanup and free all resources associated with this sessionhandle. @@ -329,7 +382,7 @@ CURLcode Curl_close(struct SessionHandle *data) #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(data->set.cookiejar) { + if(data->set.str[STRING_COOKIEJAR]) { if(data->change.cookielist) { /* If there is a list of cookie files to read, do it first so that we have all the told files read before we write the new jar */ @@ -337,9 +390,9 @@ CURLcode Curl_close(struct SessionHandle *data) } /* we have a "destination" for all the cookies to get dumped to */ - if(Curl_cookie_output(data->cookies, data->set.cookiejar)) + if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) infof(data, "WARNING: failed to save cookies in %s\n", - data->set.cookiejar); + data->set.str[STRING_COOKIEJAR]); } else { if(data->change.cookielist) @@ -381,6 +434,7 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } + Curl_freeset(data); free(data); return CURLE_OK; } @@ -609,7 +663,8 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */ #ifdef CURL_CA_BUNDLE /* This is our preferred CA cert bundle since install time */ - data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE; + res = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], + (char *) CURL_CA_BUNDLE); #endif } @@ -617,6 +672,7 @@ CURLcode Curl_open(struct SessionHandle **curl) ares_destroy(data->state.areschannel); if(data->state.headerbuff) free(data->state.headerbuff); + Curl_freeset(data); free(data); data = NULL; } @@ -648,7 +704,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ - data->set.ssl.cipher_list = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], + va_arg(param, char *)); break; case CURLOPT_RANDOM_FILE: @@ -656,13 +713,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * 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->set.ssl.random_file = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SSL_RANDOM_FILE], + va_arg(param, char *)); break; case CURLOPT_EGDSOCKET: /* * The Entropy Gathering Daemon socket pathname */ - data->set.ssl.egdsocket = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SSL_EGDSOCKET], + va_arg(param, char *)); break; case CURLOPT_MAXCONNECTS: /* @@ -785,7 +844,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Use this file instead of the $HOME/.netrc file */ - data->set.netrc_file = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE], + va_arg(param, char *)); break; case CURLOPT_TRANSFERTEXT: /* @@ -836,9 +896,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * and ignore an received Content-Encoding header. * */ - data->set.encoding = va_arg(param, char *); - if(data->set.encoding && !*data->set.encoding) - data->set.encoding = (char*)ALL_CONTENT_ENCODINGS; + argptr = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_ENCODING], + (argptr && !*argptr)? + (char *) ALL_CONTENT_ENCODINGS: argptr); break; case CURLOPT_FOLLOWLOCATION: @@ -881,7 +942,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * A string with POST data. Makes curl HTTP POST. Even if it is NULL. */ - data->set.postfields = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_POSTFIELDS], + va_arg(param, char *)); data->set.httpreq = HTTPREQ_POST; break; @@ -918,15 +980,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, free(data->change.referer); data->change.referer_alloc = FALSE; } - data->set.set_referer = va_arg(param, char *); - data->change.referer = data->set.set_referer; + result = Curl_setstropt(&data->set.str[STRING_SET_REFERER], + va_arg(param, char *)); + data->change.referer = data->set.str[STRING_SET_REFERER]; break; case CURLOPT_USERAGENT: /* * String to use in the HTTP User-Agent field */ - data->set.useragent = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_USERAGENT], + va_arg(param, char *)); break; case CURLOPT_HTTPHEADER: @@ -948,7 +1012,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Cookie string to send to the remote server in the request. */ - data->set.cookie = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_COOKIE], + va_arg(param, char *)); break; case CURLOPT_COOKIEFILE: @@ -973,7 +1038,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set cookie file name to dump all cookies to when we're done. */ - data->set.cookiejar = (char *)va_arg(param, void *); + result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR], + va_arg(param, char *)); /* * Activate the cookie parser. This may or may not already @@ -1071,7 +1137,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set a custom string to use as request */ - data->set.customrequest = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST], + va_arg(param, char *)); /* we don't set data->set.httpreq = HTTPREQ_CUSTOM; @@ -1137,7 +1204,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Setting it to NULL, means no proxy but allows the environment variables * to decide for us. */ - data->set.proxy = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_PROXY], + va_arg(param, char *)); break; case CURLOPT_WRITEHEADER: @@ -1163,8 +1231,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Use FTP PORT, this also specifies which IP address to use */ - data->set.ftpport = va_arg(param, char *); - data->set.ftp_use_port = (bool)(NULL != data->set.ftpport); + result = Curl_setstropt(&data->set.str[STRING_FTPPORT], + va_arg(param, char *)); + data->set.ftp_use_port = (bool)(NULL != data->set.str[STRING_FTPPORT]); break; case CURLOPT_FTP_USE_EPRT: @@ -1247,8 +1316,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, free(data->change.url); data->change.url_alloc=FALSE; } - data->set.set_url = va_arg(param, char *); - data->change.url = data->set.set_url; + result = Curl_setstropt(&data->set.str[STRING_SET_URL], + va_arg(param, char *)); + data->change.url = data->set.str[STRING_SET_URL]; data->change.url_changed = TRUE; break; case CURLOPT_PORT: @@ -1284,7 +1354,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password to use in the operation */ - data->set.userpwd = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_USERPWD], + va_arg(param, char *)); break; case CURLOPT_POSTQUOTE: /* @@ -1325,13 +1396,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password needed to use the proxy */ - data->set.proxyuserpwd = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_PROXYUSERPWD], + va_arg(param, char *)); break; case CURLOPT_RANGE: /* * What range of the file you want to transfer */ - data->set.set_range = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SET_RANGE], + va_arg(param, char *)); break; case CURLOPT_RESUME_FROM: /* @@ -1428,31 +1501,36 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * String that holds file name of the SSL certificate to use */ - data->set.cert = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_CERT], + va_arg(param, char *)); break; case CURLOPT_SSLCERTTYPE: /* * String that holds file type of the SSL certificate to use */ - data->set.cert_type = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE], + va_arg(param, char *)); break; case CURLOPT_SSLKEY: /* * String that holds file name of the SSL certificate to use */ - data->set.key = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_KEY], + va_arg(param, char *)); break; case CURLOPT_SSLKEYTYPE: /* * String that holds file type of the SSL certificate to use */ - data->set.key_type = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE], + va_arg(param, char *)); break; case CURLOPT_SSLKEYPASSWD: /* * String that holds the SSL private key password. */ - data->set.key_passwd = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], + va_arg(param, char *)); break; case CURLOPT_SSLENGINE: /* @@ -1481,7 +1559,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set what interface or address/hostname to bind the socket to when * performing an operation and thus what from-IP your connection will use. */ - data->set.device = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_DEVICE], + va_arg(param, char *)); break; case CURLOPT_LOCALPORT: /* @@ -1499,8 +1578,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * A string that defines the kerberos security level. */ - data->set.krb_level = va_arg(param, char *); - data->set.krb = (bool)(NULL != data->set.krb_level); + result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], + va_arg(param, char *)); + data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]); break; case CURLOPT_SSL_VERIFYPEER: /* @@ -1530,7 +1610,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set CA info for SSL connection. Specify file name of the CA certificate */ - data->set.ssl.CAfile = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], + va_arg(param, char *)); break; case CURLOPT_CAPATH: /* @@ -1538,7 +1619,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * certificates which have been prepared using openssl c_rehash utility. */ /* This does not work on windows. */ - data->set.ssl.CApath = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], + va_arg(param, char *)); break; case CURLOPT_TELNETOPTIONS: /* @@ -1639,7 +1721,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set private data pointer. */ - data->set.private_data = va_arg(param, char *); + data->set.private_data = va_arg(param, void *); break; case CURLOPT_MAXFILESIZE: @@ -1691,7 +1773,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, These former 3rd party transfer options are deprecated */ case CURLOPT_FTP_ACCOUNT: - data->set.ftp_account = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT], + va_arg(param, char *)); break; case CURLOPT_IGNORE_CONTENT_LENGTH: @@ -1706,7 +1789,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_FTP_ALTERNATIVE_TO_USER: - data->set.ftp_alternative_to_user = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], + va_arg(param, char *)); break; case CURLOPT_SOCKOPTFUNCTION: @@ -1735,14 +1819,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Use this file instead of the $HOME/.ssh/id_dsa.pub file */ - data->set.ssh_public_key = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], + va_arg(param, char *)); break; case CURLOPT_SSH_PRIVATE_KEYFILE: /* * Use this file instead of the $HOME/.ssh/id_dsa file */ - data->set.ssh_private_key = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], + va_arg(param, char *)); break; case CURLOPT_HTTP_TRANSFER_DECODING: @@ -2780,14 +2866,14 @@ static CURLcode setup_range(struct SessionHandle *data) struct HandleData *req = &data->reqdata; req->resume_from = data->set.set_resume_from; - if (req->resume_from || data->set.set_range) { + if (req->resume_from || data->set.str[STRING_SET_RANGE]) { if (req->rangestringalloc == TRUE) free(req->range); if(req->resume_from) req->range = aprintf("%" FORMAT_OFF_T "-", req->resume_from); else - req->range = strdup(data->set.set_range); + req->range = strdup(data->set.str[STRING_SET_RANGE]); req->rangestringalloc = req->range?TRUE:FALSE; @@ -2892,7 +2978,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->connectindex = -1; /* no index */ conn->proxytype = data->set.proxytype; /* type */ - conn->bits.proxy = (bool)(data->set.proxy && *data->set.proxy); + conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && + *data->set.str[STRING_PROXY]); conn->bits.httpproxy = (bool)(conn->bits.proxy && (conn->proxytype == CURLPROXY_HTTP)); @@ -2911,8 +2998,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); - conn->bits.user_passwd = (bool)(NULL != data->set.userpwd); - conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd); + conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); + conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); conn->bits.no_body = data->set.opt_no_body; conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; @@ -2945,11 +3032,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(urllen < LEAST_PATH_ALLOC) urllen=LEAST_PATH_ALLOC; - if (!data->set.source_url /* 3rd party FTP */ - && data->reqdata.pathbuffer) { - /* Free the old buffer */ - free(data->reqdata.pathbuffer); - } + /* Free the old buffer */ + Curl_safefree(data->reqdata.pathbuffer); /* * We malloc() the buffers below urllen+2 to make room for to possibilities: @@ -2981,7 +3065,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, char proxyuser[MAX_CURL_USER_LENGTH]=""; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - sscanf(data->set.proxyuserpwd, + sscanf(data->set.str[STRING_PROXYUSERPWD], "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", proxyuser, proxypasswd); @@ -2995,8 +3079,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; } - if (data->set.proxy) { - proxy = strdup(data->set.proxy); /* if global proxy is set, this is it */ + if (data->set.str[STRING_PROXY]) { + proxy = strdup(data->set.str[STRING_PROXY]); + /* if global proxy is set, this is it */ if(NULL == proxy) { failf(data, "memory shortage"); return CURLE_OUT_OF_MEMORY; @@ -3711,9 +3796,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, * user_password is set in "inherit initial knowledge' above, * so it doesn't have to be set in this block */ - if (data->set.userpwd != NULL) { + if (data->set.str[STRING_USERPWD] != NULL) { /* the name is given, get user+password */ - sscanf(data->set.userpwd, + sscanf(data->set.str[STRING_USERPWD], "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", user, passwd); @@ -3723,7 +3808,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (data->set.use_netrc != CURL_NETRC_IGNORED) { if(Curl_parsenetrc(conn->host.name, user, passwd, - data->set.netrc_file)) { + data->set.str[STRING_NETRC_FILE])) { infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n", conn->host.name); @@ -3760,8 +3845,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, * new one. *************************************************************/ - /* get a cloned copy of the SSL config situation stored in the - connection struct */ + /* Get a cloned copy of the SSL config situation stored in the + connection struct. But to get this going nicely, we must first make + sure that the strings in the master copy are pointing to the correct + strings in the session handle strings array! + + Keep in mind that the pointers in the master copy are pointing to strings + that will be freed as part of the SessionHandle struct, but all cloned + copies will be separately allocated. + */ + data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH]; + data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; + if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) return CURLE_OUT_OF_MEMORY; @@ -4081,10 +4179,10 @@ static CURLcode SetupConnection(struct connectdata *conn, /************************************************************* * Set user-agent for HTTP *************************************************************/ - if((conn->protocol&PROT_HTTP) && data->set.useragent) { + if((conn->protocol&PROT_HTTP) && data->set.str[STRING_USERAGENT]) { Curl_safefree(conn->allocptr.uagent); conn->allocptr.uagent = - aprintf("User-Agent: %s\r\n", data->set.useragent); + aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); if(!conn->allocptr.uagent) return CURLE_OUT_OF_MEMORY; } -- cgit v1.2.1 From 6f750f3b575bce420666b8115c1db7897dae5f7a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 2 Aug 2007 14:09:08 +0000 Subject: Dmitriy Sergeyev reported a regression: resumed file:// transfers broke after 7.16.2. This is much due to the different treatment file:// gets internally, but now I added test 231 to make it less likely to happen again without us noticing! --- lib/url.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0de87a824..21b869efa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3604,18 +3604,24 @@ static CURLcode CreateConnection(struct SessionHandle *data, ***********************************************************************/ #ifndef CURL_DISABLE_FILE if (strequal(conn->protostr, "FILE")) { - /* anyway, this is supposed to be the connect function so we better - at least check that the file is present here! */ - result = Curl_file_connect(conn); - - /* Setup a "faked" transfer that'll do nothing */ - if(CURLE_OK == result) { - conn->data = data; - conn->bits.tcpconnect = TRUE; /* we are "connected */ - ConnectionStore(data, conn); - - result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ + /* this is supposed to be the connect function so we better at least check + that the file is present here! */ + result = Curl_file_connect(conn); + + /* Setup a "faked" transfer that'll do nothing */ + if(CURLE_OK == result) { + conn->data = data; + conn->bits.tcpconnect = TRUE; /* we are "connected */ + + ConnectionStore(data, conn); + + result = setup_range(data); + if(result) + return result; + + result = Curl_setup_transfer(conn, -1, -1, FALSE, + NULL, /* no download */ + -1, NULL); /* no upload */ } return result; -- cgit v1.2.1 From 035ee257c8fd20652c5de2581ef46958e563a5e0 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 2 Aug 2007 19:23:35 +0000 Subject: Fixed a compiler warning. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 21b869efa..226e7be3b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -249,7 +249,7 @@ static CURLcode Curl_setstropt(char **charp, char * s) CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) { - CURLcode r; + CURLcode r = CURLE_OK; enum dupstring i; /* Copy src->set into dst->set first, then deal with the strings -- cgit v1.2.1 From 5ec786b02e0b460320b9bb4d75f5ddb8b1016656 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 2 Aug 2007 20:10:28 +0000 Subject: Scott Cantor filed bug report #1766320 (http://curl.haxx.se/bug/view.cgi?id=1766320) pointing out that the libcurl code accessed two curl_easy_setopt() options (CURLOPT_DNS_CACHE_TIMEOUT and CURLOPT_DNS_USE_GLOBAL_CACHE) as ints even though they're documented to be passed in as longs, and that makes a difference on 64 bit architectures. --- lib/url.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 226e7be3b..35f8644b8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -690,14 +690,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, switch(option) { case CURLOPT_DNS_CACHE_TIMEOUT: - data->set.dns_cache_timeout = va_arg(param, int); + data->set.dns_cache_timeout = va_arg(param, long); break; case CURLOPT_DNS_USE_GLOBAL_CACHE: { - int use_cache = va_arg(param, int); - if (use_cache) { + long use_cache = va_arg(param, long); + if (use_cache) Curl_global_host_cache_init(); - } data->set.global_dns_cache = (bool)(0 != use_cache); } -- cgit v1.2.1 From 9fa05db83b104509bdbce7baa3fd46fba4b5e850 Mon Sep 17 00:00:00 2001 From: James Housley Date: Fri, 3 Aug 2007 13:46:59 +0000 Subject: The previous commit to force the use of libssh2-0.16 by removing LIBSSH2_APINO --- lib/url.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 35f8644b8..e184c2b09 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3446,10 +3446,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_do = Curl_scp_do; conn->curl_done = Curl_scp_done; -#if defined(LIBSSH2_APINO) && (LIBSSH2_APINO >= 200706012030L) conn->curl_connecting = Curl_ssh_multi_statemach; conn->curl_doing = Curl_scp_doing; -#endif /* LIBSSH2_APINO && (LIBSSH2_APINO >= 200706012030L) */ conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME @@ -3465,10 +3463,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_do = Curl_sftp_do; conn->curl_done = Curl_sftp_done; -#if defined(LIBSSH2_APINO) && (LIBSSH2_APINO >= 200706012030L) conn->curl_connecting = Curl_ssh_multi_statemach; conn->curl_doing = Curl_sftp_doing; -#endif /* LIBSSH2_APINO && (LIBSSH2_APINO >= 200706012030L) */ conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; #else failf(data, LIBCURL_NAME -- cgit v1.2.1 From 0d3d84e3ffcaa6118cc4f33c5f2d6c9166d60662 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 3 Aug 2007 22:46:59 +0000 Subject: Refactored CreateConnection() somewhat to reduce its length by splitting it into a few new functions. Fixed a few leaks in out of memory conditions, including for test case 231. --- lib/url.c | 949 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 510 insertions(+), 439 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e184c2b09..ba48da8eb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2888,345 +2888,13 @@ static CURLcode setup_range(struct SessionHandle *data) return CURLE_OK; } -/** - * CreateConnection() sets up a new connectdata struct, or re-uses an already - * existing one, and resolves host name. - * - * if this function returns CURLE_OK and *async is set to TRUE, the resolve - * response will be coming asynchronously. If *async is FALSE, the name is - * already resolved. - * - * @param data The sessionhandle pointer - * @param in_connect is set to the next connection data pointer - * @param addr is set to the new dns entry for this connection. If this - * connection is re-used it will be NULL. - * @param async is set TRUE/FALSE depending on the nature of this lookup - * @return CURLcode - * @see SetupConnection() - * - * *NOTE* this function assigns the conn->data pointer! - */ -static CURLcode CreateConnection(struct SessionHandle *data, - struct connectdata **in_connect, - struct Curl_dns_entry **addr, - bool *async) +/*************************************************************** +* Setup connection internals specific to the requested protocol +***************************************************************/ +static CURLcode setup_connection_internals(struct SessionHandle *data, + struct connectdata *conn) { - - char *tmp; - CURLcode result=CURLE_OK; - struct connectdata *conn; - struct connectdata *conn_temp = NULL; - size_t urllen; - struct Curl_dns_entry *hostaddr; -#if defined(HAVE_ALARM) && !defined(USE_ARES) - unsigned int prev_alarm=0; -#endif - char endbracket; - char user[MAX_CURL_USER_LENGTH]; - char passwd[MAX_CURL_PASSWORD_LENGTH]; - int rc; - bool reuse; - char *proxy = NULL; - -#ifndef USE_ARES -#ifdef SIGALRM -#ifdef HAVE_SIGACTION - struct sigaction keep_sigact; /* store the old struct here */ - bool keep_copysig=FALSE; /* did copy it? */ -#else -#ifdef HAVE_SIGNAL - void (*keep_sigact)(int); /* store the old handler here */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ -#endif /* SIGALRM */ -#endif /* USE_ARES */ - - *addr = NULL; /* nothing yet */ - *async = FALSE; - - /************************************************************* - * Check input data - *************************************************************/ - - if(!data->change.url) - return CURLE_URL_MALFORMAT; - - /* First, split up the current URL in parts so that we can use the - parts for checking against the already present connections. In order - to not have to modify everything at once, we allocate a temporary - connection data struct and fill in for comparison purposes. */ - - conn = (struct connectdata *)calloc(1, sizeof(struct connectdata)); - if(!conn) { - *in_connect = NULL; /* clear the pointer */ - return CURLE_OUT_OF_MEMORY; - } - /* We must set the return variable as soon as possible, so that our - parent can cleanup any possible allocs we may have done before - any failure */ - *in_connect = conn; - - /* and we setup a few fields in case we end up actually using this struct */ - - conn->data = data; /* Setup the association between this connection - and the SessionHandle */ - - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->connectindex = -1; /* no index */ - - conn->proxytype = data->set.proxytype; /* type */ - conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && - *data->set.str[STRING_PROXY]); - conn->bits.httpproxy = (bool)(conn->bits.proxy - && (conn->proxytype == CURLPROXY_HTTP)); - - - /* Default protocol-independent behavior doesn't support persistent - connections, so we set this to force-close. Protocols that support - this need to set this to FALSE in their "curl_do" functions. */ - conn->bits.close = TRUE; - - conn->readchannel_inuse = FALSE; - conn->writechannel_inuse = FALSE; - - conn->read_pos = 0; - conn->buf_len = 0; - - /* Store creation time to help future close decision making */ - conn->created = Curl_tvnow(); - - conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); - conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); - conn->bits.no_body = data->set.opt_no_body; - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; - conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; - conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; - - if (data->multi && Curl_multi_canPipeline(data->multi) && - !conn->master_buffer) { - /* Allocate master_buffer to be used for pipelining */ - conn->master_buffer = calloc(BUFSIZE, sizeof (char)); - if (!conn->master_buffer) - return CURLE_OUT_OF_MEMORY; - } - - /* Initialize the pipeline lists */ - conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if (!conn->send_pipe || !conn->recv_pipe) - return CURLE_OUT_OF_MEMORY; - - /* This initing continues below, see the comment "Continue connectdata - * initialization here" */ - - /*********************************************************** - * We need to allocate memory to store the path in. We get the size of the - * full URL to be sure, and we need to make it at least 256 bytes since - * other parts of the code will rely on this fact - ***********************************************************/ -#define LEAST_PATH_ALLOC 256 - urllen=strlen(data->change.url); - if(urllen < LEAST_PATH_ALLOC) - urllen=LEAST_PATH_ALLOC; - - /* Free the old buffer */ - Curl_safefree(data->reqdata.pathbuffer); - - /* - * We malloc() the buffers below urllen+2 to make room for to possibilities: - * 1 - an extra terminating zero - * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) - */ - - data->reqdata.pathbuffer=(char *)malloc(urllen+2); - if(NULL == data->reqdata.pathbuffer) - return CURLE_OUT_OF_MEMORY; /* really bad error */ - data->reqdata.path = data->reqdata.pathbuffer; - - conn->host.rawalloc=(char *)malloc(urllen+2); - if(NULL == conn->host.rawalloc) - return CURLE_OUT_OF_MEMORY; - - conn->host.name = conn->host.rawalloc; - conn->host.name[0] = 0; - - result = ParseURLAndFillConnection(data, conn); - if (result != CURLE_OK) { - return result; - } - - /************************************************************* - * Take care of proxy authentication stuff - *************************************************************/ - if(conn->bits.proxy_user_passwd) { - char proxyuser[MAX_CURL_USER_LENGTH]=""; - char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - - sscanf(data->set.str[STRING_PROXYUSERPWD], - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - proxyuser, proxypasswd); - - conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); - if(!conn->proxyuser) - return CURLE_OUT_OF_MEMORY; - - conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); - if(!conn->proxypasswd) - return CURLE_OUT_OF_MEMORY; - } - - if (data->set.str[STRING_PROXY]) { - proxy = strdup(data->set.str[STRING_PROXY]); - /* if global proxy is set, this is it */ - if(NULL == proxy) { - failf(data, "memory shortage"); - return CURLE_OUT_OF_MEMORY; - } - } - /* proxy must be freed later unless NULL */ - -#ifndef CURL_DISABLE_HTTP - /************************************************************* - * Detect what (if any) proxy to use. Remember that this selects a host - * name and is not limited to HTTP proxies only. - *************************************************************/ - if(!proxy) { - /* If proxy was not specified, we check for default proxy environment - * variables, to enable i.e Lynx compliance: - * - * http_proxy=http://some.server.dom:port/ - * https_proxy=http://some.server.dom:port/ - * ftp_proxy=http://some.server.dom:port/ - * no_proxy=domain1.dom,host.domain2.dom - * (a comma-separated list of hosts which should - * not be proxied, or an asterisk to override - * all proxy variables) - * all_proxy=http://some.server.dom:port/ - * (seems to exist for the CERN www lib. Probably - * the first to check for.) - * - * For compatibility, the all-uppercase versions of these variables are - * checked if the lowercase versions don't exist. - */ - char *no_proxy=NULL; - char *no_proxy_tok_buf; - char proxy_env[128]; - - no_proxy=curl_getenv("no_proxy"); - if(!no_proxy) - no_proxy=curl_getenv("NO_PROXY"); - - if(!no_proxy || !strequal("*", no_proxy)) { - /* NO_PROXY wasn't specified or it wasn't just an asterisk */ - char *nope; - - nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; - while(nope) { - size_t namelen; - char *endptr = strchr(conn->host.name, ':'); - if(endptr) - namelen=endptr-conn->host.name; - else - namelen=strlen(conn->host.name); - - if(strlen(nope) <= namelen) { - char *checkn= - conn->host.name + namelen - strlen(nope); - if(checkprefix(nope, checkn)) { - /* no proxy for this host! */ - break; - } - } - nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); - } - if(!nope) { - /* It was not listed as without proxy */ - char *protop = conn->protostr; - char *envp = proxy_env; - char *prox; - - /* Now, build _proxy and check for such a one to use */ - while(*protop) - *envp++ = (char)tolower((int)*protop++); - - /* append _proxy */ - strcpy(envp, "_proxy"); - - /* read the protocol proxy: */ - prox=curl_getenv(proxy_env); - - /* - * We don't try the uppercase version of HTTP_PROXY because of - * security reasons: - * - * When curl is used in a webserver application - * environment (cgi or php), this environment variable can - * be controlled by the web server user by setting the - * http header 'Proxy:' to some value. - * - * This can cause 'internal' http/ftp requests to be - * arbitrarily redirected by any external attacker. - */ - if(!prox && !strequal("http_proxy", proxy_env)) { - /* There was no lowercase variable, try the uppercase version: */ - for(envp = proxy_env; *envp; envp++) - *envp = (char)toupper((int)*envp); - prox=curl_getenv(proxy_env); - } - - if(prox && *prox) { /* don't count "" strings */ - proxy = prox; /* use this */ - } - else { - proxy = curl_getenv("all_proxy"); /* default proxy to use */ - if(!proxy) - proxy=curl_getenv("ALL_PROXY"); - } - - if(proxy && *proxy) { - long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); - - if(conn->proxytype == CURLPROXY_HTTP) { - /* force this connection's protocol to become HTTP */ - conn->protocol = PROT_HTTP | bits; - conn->bits.httpproxy = TRUE; - } - } - } /* if (!nope) - it wasn't specified non-proxy */ - } /* NO_PROXY wasn't specified or '*' */ - if(no_proxy) - free(no_proxy); - } /* if not using proxy */ -#endif /* CURL_DISABLE_HTTP */ - - /************************************************************* - * No protocol part in URL was used, add it! - *************************************************************/ - if(conn->protocol&PROT_MISSING) { - /* We're guessing prefixes here and if we're told to use a proxy or if - we're gonna follow a Location: later or... then we need the protocol - part added so that we have a valid URL. */ - char *reurl; - - reurl = aprintf("%s://%s", conn->protostr, data->change.url); - - if(!reurl) { - Curl_safefree(proxy); - return CURLE_OUT_OF_MEMORY; - } - - data->change.url = reurl; - data->change.url_alloc = TRUE; /* free this later */ - conn->protocol &= ~PROT_MISSING; /* switch that one off again */ - } - - /************************************************************* - * Setup internals depending on protocol - *************************************************************/ - conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ if (strequal(conn->protostr, "HTTP")) { @@ -3244,6 +2912,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if (strequal(conn->protostr, "HTTPS")) { #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) @@ -3264,6 +2933,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif /* !USE_SSL */ } + else if(strequal(conn->protostr, "FTP") || strequal(conn->protostr, "FTPS")) { @@ -3344,6 +3014,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if(strequal(conn->protostr, "TELNET")) { #ifndef CURL_DISABLE_TELNET /* telnet testing factory */ @@ -3359,6 +3030,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if (strequal(conn->protostr, "DICT")) { #ifndef CURL_DISABLE_DICT conn->protocol |= PROT_DICT; @@ -3373,6 +3045,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if (strequal(conn->protostr, "LDAP")) { #ifndef CURL_DISABLE_LDAP conn->protocol |= PROT_LDAP; @@ -3387,6 +3060,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if (strequal(conn->protostr, "FILE")) { #ifndef CURL_DISABLE_FILE conn->protocol |= PROT_FILE; @@ -3399,6 +3073,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if (strequal(conn->protostr, "TFTP")) { #ifndef CURL_DISABLE_TFTP char *type; @@ -3438,6 +3113,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if (strequal(conn->protostr, "SCP")) { #ifdef USE_LIBSSH2 conn->port = PORT_SSH; @@ -3455,6 +3131,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else if (strequal(conn->protostr, "SFTP")) { #ifdef USE_LIBSSH2 conn->port = PORT_SSH; @@ -3472,128 +3149,520 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #endif } + else { /* We fell through all checks and thus we don't support the specified protocol */ failf(data, "Unsupported protocol: %s", conn->protostr); return CURLE_UNSUPPORTED_PROTOCOL; } + return CURLE_OK; +} - if(proxy && *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. */ - - char *prox_portno; - char *endofprot; - - /* We use 'proxyptr' to point to the proxy name from now on... */ - char *proxyptr=proxy; - char *portptr; - char *atsign; - - /* We do the proxy host string parsing here. We want the host name and the - * port name. Accept a protocol:// prefix, even though it should just be - * ignored. - */ - - /* Skip the protocol part if present */ - endofprot=strstr(proxyptr, "://"); - if(endofprot) - proxyptr = endofprot+3; - - /* Is there a username and password given in this proxy url? */ - atsign = strchr(proxyptr, '@'); - if(atsign) { - char proxyuser[MAX_CURL_USER_LENGTH]; - char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; - proxypasswd[0] = 0; - - if(1 <= sscanf(proxyptr, - "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - proxyuser, proxypasswd)) { - CURLcode res = CURLE_OK; - - /* found user and password, rip them out. note that we are - unescaping them, as there is otherwise no way to have a - username or password with reserved characters like ':' in - them. */ - Curl_safefree(conn->proxyuser); - conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); - - if(!conn->proxyuser) - res = CURLE_OUT_OF_MEMORY; - else { - Curl_safefree(conn->proxypasswd); - conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); - - if(!conn->proxypasswd) - res = CURLE_OUT_OF_MEMORY; - } - - if(CURLE_OK == res) { - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - atsign = strdup(atsign+1); /* the right side of the @-letter */ +/**************************************************************** +* Detect what (if any) proxy to use. Remember that this selects a host +* name and is not limited to HTTP proxies only. +* The returned pointer must be freed by the caller (unless NULL) +****************************************************************/ +static char *detect_proxy(struct connectdata *conn) +{ + char *proxy = NULL; - if(atsign) { - free(proxy); /* free the former proxy string */ - proxy = proxyptr = atsign; /* now use this instead */ - } - else - res = CURLE_OUT_OF_MEMORY; - } - - if(res) { - free(proxy); /* free the allocated proxy string */ - return res; - } +#ifndef CURL_DISABLE_HTTP + /* If proxy was not specified, we check for default proxy environment + * variables, to enable i.e Lynx compliance: + * + * http_proxy=http://some.server.dom:port/ + * https_proxy=http://some.server.dom:port/ + * ftp_proxy=http://some.server.dom:port/ + * no_proxy=domain1.dom,host.domain2.dom + * (a comma-separated list of hosts which should + * not be proxied, or an asterisk to override + * all proxy variables) + * all_proxy=http://some.server.dom:port/ + * (seems to exist for the CERN www lib. Probably + * the first to check for.) + * + * For compatibility, the all-uppercase versions of these variables are + * checked if the lowercase versions don't exist. + */ + char *no_proxy=NULL; + char *no_proxy_tok_buf; + char proxy_env[128]; + + no_proxy=curl_getenv("no_proxy"); + if(!no_proxy) + no_proxy=curl_getenv("NO_PROXY"); + + if(!no_proxy || !strequal("*", no_proxy)) { + /* NO_PROXY wasn't specified or it wasn't just an asterisk */ + char *nope; + + nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; + while(nope) { + size_t namelen; + char *endptr = strchr(conn->host.name, ':'); + if(endptr) + namelen=endptr-conn->host.name; + else + namelen=strlen(conn->host.name); + + if(strlen(nope) <= namelen) { + char *checkn= + conn->host.name + namelen - strlen(nope); + if(checkprefix(nope, checkn)) { + /* no proxy for this host! */ + break; + } } + nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); } + if(!nope) { + /* It was not listed as without proxy */ + char *protop = conn->protostr; + char *envp = proxy_env; + char *prox; - /* start scanning for port number at this point */ - portptr = proxyptr; - - /* detect and extract RFC2732-style IPv6-addresses */ - if(*proxyptr == '[') { - char *ptr = ++proxyptr; /* advance beyond the initial bracket */ - while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':'))) - ptr++; - if(*ptr == ']') { - /* yeps, it ended nicely with a bracket as well */ - *ptr = 0; - portptr = ptr+1; - } - /* Note that if this didn't end with a bracket, we still advanced the - * proxyptr first, but I can't see anything wrong with that as no host - * name nor a numeric can legally start with a bracket. + /* Now, build _proxy and check for such a one to use */ + while(*protop) + *envp++ = (char)tolower((int)*protop++); + + /* append _proxy */ + strcpy(envp, "_proxy"); + + /* read the protocol proxy: */ + prox=curl_getenv(proxy_env); + + /* + * We don't try the uppercase version of HTTP_PROXY because of + * security reasons: + * + * When curl is used in a webserver application + * environment (cgi or php), this environment variable can + * be controlled by the web server user by setting the + * http header 'Proxy:' to some value. + * + * This can cause 'internal' http/ftp requests to be + * arbitrarily redirected by any external attacker. */ - } + if(!prox && !strequal("http_proxy", proxy_env)) { + /* There was no lowercase variable, try the uppercase version: */ + for(envp = proxy_env; *envp; envp++) + *envp = (char)toupper((int)*envp); + prox=curl_getenv(proxy_env); + } + + if(prox && *prox) { /* don't count "" strings */ + proxy = prox; /* use this */ + } + else { + proxy = curl_getenv("all_proxy"); /* default proxy to use */ + if(!proxy) + proxy=curl_getenv("ALL_PROXY"); + } + + if(proxy && *proxy) { + long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); + + if(conn->proxytype == CURLPROXY_HTTP) { + /* force this connection's protocol to become HTTP */ + conn->protocol = PROT_HTTP | bits; + conn->bits.httpproxy = TRUE; + } + } + } /* if (!nope) - it wasn't specified non-proxy */ + } /* NO_PROXY wasn't specified or '*' */ + if(no_proxy) + free(no_proxy); +#endif /* CURL_DISABLE_HTTP */ + + return proxy; +} + +/* If this is supposed to use a proxy, we need to figure out the proxy + * host name, so that we can re-use an existing connection + * that may exist registered to the same proxy host. + * proxy will be freed before this function returns. + */ +static CURLcode parse_proxy(struct SessionHandle *data, + struct connectdata *conn, char *proxy) +{ + char *prox_portno; + char *endofprot; + + /* We use 'proxyptr' to point to the proxy name from now on... */ + char *proxyptr=proxy; + char *portptr; + char *atsign; + + /* We do the proxy host string parsing here. We want the host name and the + * port name. Accept a protocol:// prefix, even though it should just be + * ignored. + */ + + /* Skip the protocol part if present */ + endofprot=strstr(proxyptr, "://"); + if(endofprot) + proxyptr = endofprot+3; + + /* Is there a username and password given in this proxy url? */ + atsign = strchr(proxyptr, '@'); + if(atsign) { + char proxyuser[MAX_CURL_USER_LENGTH]; + char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; + proxypasswd[0] = 0; + + if(1 <= sscanf(proxyptr, + "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", + proxyuser, proxypasswd)) { + CURLcode res = CURLE_OK; + + /* found user and password, rip them out. note that we are + unescaping them, as there is otherwise no way to have a + username or password with reserved characters like ':' in + them. */ + Curl_safefree(conn->proxyuser); + conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); + + if(!conn->proxyuser) + res = CURLE_OUT_OF_MEMORY; + else { + Curl_safefree(conn->proxypasswd); + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); - /* Get port number off proxy.server.com:1080 */ - prox_portno = strchr(portptr, ':'); - if (prox_portno) { - *prox_portno = 0x0; /* cut off number from host name */ - prox_portno ++; - /* now set the local port number */ - conn->port = atoi(prox_portno); + if(!conn->proxypasswd) + res = CURLE_OUT_OF_MEMORY; + } + + if(CURLE_OK == res) { + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + atsign = strdup(atsign+1); /* the right side of the @-letter */ + + if(atsign) { + free(proxy); /* free the former proxy string */ + proxy = proxyptr = atsign; /* now use this instead */ + } + else + res = CURLE_OUT_OF_MEMORY; + } + + if(res) { + free(proxy); /* free the allocated proxy string */ + return res; + } } - else if(data->set.proxyport) { - /* None given in the proxy string, then get the default one if it is - given */ - conn->port = data->set.proxyport; + } + + /* start scanning for port number at this point */ + portptr = proxyptr; + + /* detect and extract RFC2732-style IPv6-addresses */ + if(*proxyptr == '[') { + char *ptr = ++proxyptr; /* advance beyond the initial bracket */ + while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':'))) + ptr++; + if(*ptr == ']') { + /* yeps, it ended nicely with a bracket as well */ + *ptr = 0; + portptr = ptr+1; } + /* Note that if this didn't end with a bracket, we still advanced the + * proxyptr first, but I can't see anything wrong with that as no host + * name nor a numeric can legally start with a bracket. + */ + } + + /* Get port number off proxy.server.com:1080 */ + prox_portno = strchr(portptr, ':'); + if (prox_portno) { + *prox_portno = 0x0; /* cut off number from host name */ + prox_portno ++; + /* now set the local port number */ + conn->port = atoi(prox_portno); + } + else if(data->set.proxyport) { + /* None given in the proxy string, then get the default one if it is + given */ + conn->port = data->set.proxyport; + } + + /* now, clone the cleaned proxy host name */ + conn->proxy.rawalloc = strdup(proxyptr); + conn->proxy.name = conn->proxy.rawalloc; + + free(proxy); + if(!conn->proxy.rawalloc) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +/* Extract the user and password from the authentication string */ +static CURLcode parse_proxy_auth(struct SessionHandle *data, struct connectdata *conn) +{ + char proxyuser[MAX_CURL_USER_LENGTH]=""; + char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; + + sscanf(data->set.str[STRING_PROXYUSERPWD], + "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", + proxyuser, proxypasswd); + + conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); + if(!conn->proxyuser) + return CURLE_OUT_OF_MEMORY; + + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); + if(!conn->proxypasswd) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +/** + * CreateConnection() sets up a new connectdata struct, or re-uses an already + * existing one, and resolves host name. + * + * if this function returns CURLE_OK and *async is set to TRUE, the resolve + * response will be coming asynchronously. If *async is FALSE, the name is + * already resolved. + * + * @param data The sessionhandle pointer + * @param in_connect is set to the next connection data pointer + * @param addr is set to the new dns entry for this connection. If this + * connection is re-used it will be NULL. + * @param async is set TRUE/FALSE depending on the nature of this lookup + * @return CURLcode + * @see SetupConnection() + * + * *NOTE* this function assigns the conn->data pointer! + */ + +static CURLcode CreateConnection(struct SessionHandle *data, + struct connectdata **in_connect, + struct Curl_dns_entry **addr, + bool *async) +{ + + char *tmp; + CURLcode result=CURLE_OK; + struct connectdata *conn; + struct connectdata *conn_temp = NULL; + size_t urllen; + struct Curl_dns_entry *hostaddr; +#if defined(HAVE_ALARM) && !defined(USE_ARES) + unsigned int prev_alarm=0; +#endif + char endbracket; + char user[MAX_CURL_USER_LENGTH]; + char passwd[MAX_CURL_PASSWORD_LENGTH]; + int rc; + bool reuse; + char *proxy = NULL; + +#ifndef USE_ARES +#ifdef SIGALRM +#ifdef HAVE_SIGACTION + struct sigaction keep_sigact; /* store the old struct here */ + bool keep_copysig=FALSE; /* did copy it? */ +#else +#ifdef HAVE_SIGNAL + void (*keep_sigact)(int); /* store the old handler here */ +#endif /* HAVE_SIGNAL */ +#endif /* HAVE_SIGACTION */ +#endif /* SIGALRM */ +#endif /* USE_ARES */ + + *addr = NULL; /* nothing yet */ + *async = FALSE; + + /************************************************************* + * Check input data + *************************************************************/ - /* now, clone the cleaned proxy host name */ - conn->proxy.rawalloc = strdup(proxyptr); - conn->proxy.name = conn->proxy.rawalloc; + if(!data->change.url) + return CURLE_URL_MALFORMAT; + + /* First, split up the current URL in parts so that we can use the + parts for checking against the already present connections. In order + to not have to modify everything at once, we allocate a temporary + connection data struct and fill in for comparison purposes. */ + + conn = (struct connectdata *)calloc(1, sizeof(struct connectdata)); + if(!conn) { + *in_connect = NULL; /* clear the pointer */ + return CURLE_OUT_OF_MEMORY; + } + /* We must set the return variable as soon as possible, so that our + parent can cleanup any possible allocs we may have done before + any failure */ + *in_connect = conn; - free(proxy); + /* and we setup a few fields in case we end up actually using this struct */ + + conn->data = data; /* Setup the association between this connection + and the SessionHandle */ + + conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->connectindex = -1; /* no index */ + + conn->proxytype = data->set.proxytype; /* type */ + conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && + *data->set.str[STRING_PROXY]); + conn->bits.httpproxy = (bool)(conn->bits.proxy + && (conn->proxytype == CURLPROXY_HTTP)); + + + /* Default protocol-independent behavior doesn't support persistent + connections, so we set this to force-close. Protocols that support + this need to set this to FALSE in their "curl_do" functions. */ + conn->bits.close = TRUE; + + conn->readchannel_inuse = FALSE; + conn->writechannel_inuse = FALSE; + + conn->read_pos = 0; + conn->buf_len = 0; + + /* Store creation time to help future close decision making */ + conn->created = Curl_tvnow(); + + conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); + conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); + conn->bits.no_body = data->set.opt_no_body; + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; + conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; + conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + + if (data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ + conn->master_buffer = calloc(BUFSIZE, sizeof (char)); + if (!conn->master_buffer) + return CURLE_OUT_OF_MEMORY; + } + + /* Initialize the pipeline lists */ + conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if (!conn->send_pipe || !conn->recv_pipe) + return CURLE_OUT_OF_MEMORY; + + /* This initing continues below, see the comment "Continue connectdata + * initialization here" */ + + /*********************************************************** + * We need to allocate memory to store the path in. We get the size of the + * full URL to be sure, and we need to make it at least 256 bytes since + * other parts of the code will rely on this fact + ***********************************************************/ +#define LEAST_PATH_ALLOC 256 + urllen=strlen(data->change.url); + if(urllen < LEAST_PATH_ALLOC) + urllen=LEAST_PATH_ALLOC; + + /* Free the old buffer */ + Curl_safefree(data->reqdata.pathbuffer); + + /* + * We malloc() the buffers below urllen+2 to make room for to possibilities: + * 1 - an extra terminating zero + * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) + */ + + data->reqdata.pathbuffer=(char *)malloc(urllen+2); + if(NULL == data->reqdata.pathbuffer) + return CURLE_OUT_OF_MEMORY; /* really bad error */ + data->reqdata.path = data->reqdata.pathbuffer; + + conn->host.rawalloc=(char *)malloc(urllen+2); + if(NULL == conn->host.rawalloc) + return CURLE_OUT_OF_MEMORY; + + conn->host.name = conn->host.rawalloc; + conn->host.name[0] = 0; + + result = ParseURLAndFillConnection(data, conn); + if (result != CURLE_OK) { + return result; + } + + /************************************************************* + * Take care of proxy authentication stuff + *************************************************************/ + if(conn->bits.proxy_user_passwd) { + result = parse_proxy_auth(data, conn); + if (result != CURLE_OK) + return result; + } + + /************************************************************* + * Detect what (if any) proxy to use + *************************************************************/ + if (data->set.str[STRING_PROXY]) { + proxy = strdup(data->set.str[STRING_PROXY]); + /* if global proxy is set, this is it */ + if(NULL == proxy) { + failf(data, "memory shortage"); + return CURLE_OUT_OF_MEMORY; + } + } + + if (!proxy) + proxy = detect_proxy(conn); + if (proxy && !*proxy) { + free(proxy); /* Don't bother with an empty proxy string */ proxy = NULL; - if(!conn->proxy.rawalloc) + } + /* proxy must be freed later unless NULL */ + + /************************************************************* + * No protocol part in URL was used, add it! + *************************************************************/ + if(conn->protocol&PROT_MISSING) { + /* We're guessing prefixes here and if we're told to use a proxy or if + we're gonna follow a Location: later or... then we need the protocol + part added so that we have a valid URL. */ + char *reurl; + + reurl = aprintf("%s://%s", conn->protostr, data->change.url); + + if(!reurl) { + Curl_safefree(proxy); return CURLE_OUT_OF_MEMORY; + } + + data->change.url = reurl; + data->change.url_alloc = TRUE; /* free this later */ + conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } + /************************************************************* + * Setup internals depending on protocol + *************************************************************/ + result = setup_connection_internals(data, conn); + if (result != CURLE_OK) { + Curl_safefree(proxy); + return result; + } + + + /*********************************************************************** + * If this is supposed to use a proxy, we need to figure out the proxy + * host name, so that we can re-use an existing connection + * that may exist registered to the same proxy host. + ***********************************************************************/ + if (proxy) { + result = parse_proxy(data, conn, proxy); + /* parse_proxy has freed the proxy string, so don't try to use it again */ + proxy = NULL; + if (result != CURLE_OK) + return result; + } + + /*********************************************************************** * file: is a special case in that it doesn't need a network connection ***********************************************************************/ @@ -3611,8 +3680,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, ConnectionStore(data, conn); result = setup_range(data); - if(result) + if(result) { + Curl_file_done(conn, result, FALSE); return result; + } result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ -- cgit v1.2.1 From 7fe65aaf5bda5f48eebcc3f694485b2bc6b49d6c Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Sat, 4 Aug 2007 16:54:58 +0000 Subject: Fixed a couple of compiler warnings. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ba48da8eb..5273fdb41 100644 --- a/lib/url.c +++ b/lib/url.c @@ -221,7 +221,7 @@ void Curl_freeset(struct SessionHandle * data) { /* Free all dynamic strings stored in the data->set substructure. */ enum dupstring i; - for(i=0; i < STRING_LAST; i++) + for(i=(enum dupstring)0; i < STRING_LAST; i++) Curl_safefree(data->set.str[i]); } @@ -3274,6 +3274,10 @@ static char *detect_proxy(struct connectdata *conn) } /* NO_PROXY wasn't specified or '*' */ if(no_proxy) free(no_proxy); + +#else /* !CURL_DISABLE_HTTP */ + + (void)conn; #endif /* CURL_DISABLE_HTTP */ return proxy; -- cgit v1.2.1 From 2e60ca382dbe99bd294641dabf7e84a349b080c8 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 7 Aug 2007 00:10:27 +0000 Subject: Fixed some icc compiler warnings. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5273fdb41..8c32f035c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -260,7 +260,7 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); /* duplicate all strings */ - for(i=0; i< STRING_LAST; i++) { + for(i=(enum dupstring)0; i< STRING_LAST; i++) { r = Curl_setstropt(&dst->set.str[i], src->set.str[i]); if (r != CURLE_OK) break; -- cgit v1.2.1 From c669e1ae45fce7e0aae73825ba69d4c2db009f57 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 7 Aug 2007 18:24:49 +0000 Subject: Fixed torture test for test 509 --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8c32f035c..901b1495c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1318,7 +1318,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = Curl_setstropt(&data->set.str[STRING_SET_URL], va_arg(param, char *)); data->change.url = data->set.str[STRING_SET_URL]; - data->change.url_changed = TRUE; + if (data->change.url) + data->change.url_changed = TRUE; break; case CURLOPT_PORT: /* -- cgit v1.2.1 From d0edb478964cb5bf7446c34d5ac1e9d34dc5ca63 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 11 Aug 2007 20:57:54 +0000 Subject: Patrick Monnerat modified the LDAP code and approach in curl. Starting now, the configure script checks for openldap and friends and we link with those libs just like we link all other third party libraries, and we no longer dlopen() those libraries. Our private header file lib/ldap.h was renamed to lib/curl_ldap.h due to this. I set a tag in CVS (curl-7_17_0-preldapfix) just before this commit, just in case. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 901b1495c..7699e38d2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -130,7 +130,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "tftp.h" #include "http.h" #include "file.h" -#include "ldap.h" +#include "curl_ldap.h" #include "ssh.h" #include "url.h" #include "connect.h" -- cgit v1.2.1 From ccba0d10b6baf5c73cae8cf4fb3f29f0f55c5a34 Mon Sep 17 00:00:00 2001 From: Gunter Knauf Date: Thu, 16 Aug 2007 14:08:47 +0000 Subject: added basic ldaps support; for now its ifdef'd with HAVE_LDAP_SSL unless we know its fully working, and available with all LDAP SDKs. Win32 requires to have the trusted CA in local keystore - I've not found yet a way to disable the cert check. --- lib/url.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7699e38d2..ca7f51431 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3062,6 +3062,23 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, #endif } +#ifdef HAVE_LDAP_SSL + else if (strequal(conn->protostr, "LDAPS")) { +#ifndef CURL_DISABLE_LDAP + conn->protocol |= PROT_LDAP|PROT_SSL; + conn->port = PORT_LDAPS; + conn->remote_port = PORT_LDAPS; + conn->curl_do = Curl_ldap; + /* no LDAP-specific done */ + conn->curl_done = (Curl_done_func)ZERO_NULL; +#else + failf(data, LIBCURL_NAME + " was built with LDAP disabled!"); + return CURLE_UNSUPPORTED_PROTOCOL; +#endif + } +#endif /* CURL_LDAP_USE_SSL */ + else if (strequal(conn->protostr, "FILE")) { #ifndef CURL_DISABLE_FILE conn->protocol |= PROT_FILE; -- cgit v1.2.1 From 523767660c05cf359091694fcaccb763ebb7b2d7 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Sun, 26 Aug 2007 05:53:26 +0000 Subject: Fixed some minor mismatched types found by splint. --- lib/url.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ca7f51431..c4b87d340 100644 --- a/lib/url.c +++ b/lib/url.c @@ -158,8 +158,8 @@ static bool ConnectionExists(struct SessionHandle *data, struct connectdata **usethis); static long ConnectionStore(struct SessionHandle *data, struct connectdata *conn); -static bool IsPipeliningPossible(struct SessionHandle *handle); -static bool IsPipeliningEnabled(struct SessionHandle *handle); +static bool IsPipeliningPossible(const struct SessionHandle *handle); +static bool IsPipeliningEnabled(const struct SessionHandle *handle); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipe); @@ -292,7 +292,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) { struct conncache *c = data->state.connc; - int i; + long i; struct curl_llist *pipe; struct curl_llist_element *curr; struct connectdata *connptr; @@ -536,7 +536,7 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, void Curl_rm_connc(struct conncache *c) { if(c->connects) { - int i; + long i; for(i = 0; i < c->num; ++i) conn_free(c->connects[i]); @@ -2010,7 +2010,7 @@ static bool SocketIsDead(curl_socket_t sock) return ret_val; } -static bool IsPipeliningPossible(struct SessionHandle *handle) +static bool IsPipeliningPossible(const struct SessionHandle *handle) { if (handle->multi && Curl_multi_canPipeline(handle->multi) && (handle->set.httpreq == HTTPREQ_GET || @@ -2021,7 +2021,7 @@ static bool IsPipeliningPossible(struct SessionHandle *handle) return FALSE; } -static bool IsPipeliningEnabled(struct SessionHandle *handle) +static bool IsPipeliningEnabled(const struct SessionHandle *handle) { if (handle->multi && Curl_multi_canPipeline(handle->multi)) return TRUE; @@ -2430,24 +2430,27 @@ static CURLcode ConnectPlease(struct SessionHandle *data, conn->dns_entry = hostaddr; conn->ip_addr = addr; - Curl_store_ip_addr(conn); + result = Curl_store_ip_addr(conn); - switch(data->set.proxytype) { - case CURLPROXY_SOCKS5: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn); - break; - case CURLPROXY_HTTP: - /* do nothing here. handled later. */ - break; - case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, - FIRSTSOCKET, conn); - break; - default: - failf(data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - break; + if(CURLE_OK == result) { + + switch(data->set.proxytype) { + case CURLPROXY_SOCKS5: + result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn); + break; + case CURLPROXY_HTTP: + /* do nothing here. handled later. */ + break; + case CURLPROXY_SOCKS4: + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, + FIRSTSOCKET, conn); + break; + default: + failf(data, "unknown proxytype option given"); + result = CURLE_COULDNT_CONNECT; + break; + } } } if(result) @@ -2867,7 +2870,7 @@ static CURLcode setup_range(struct SessionHandle *data) req->resume_from = data->set.set_resume_from; if (req->resume_from || data->set.str[STRING_SET_RANGE]) { - if (req->rangestringalloc == TRUE) + if (req->rangestringalloc) free(req->range); if(req->resume_from) -- cgit v1.2.1 From 1b66c1da6c6cf6e33bedbc01c93f5d4c48de4e55 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 29 Aug 2007 05:36:53 +0000 Subject: Added lots of consts --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c4b87d340..82fcc3bd4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -104,7 +104,6 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "netrc.h" #include "formdata.h" -#include "base64.h" #include "sslgen.h" #include "hostip.h" #include "transfer.h" -- cgit v1.2.1 From 9f44a95522162c0f4a61093efe1bf1f58b087358 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 30 Aug 2007 20:34:57 +0000 Subject: Renamed several libcurl error codes and options to make them more general and allow reuse by multiple protocols. Several unused error codes were removed. In all cases, macros were added to preserve source (and binary) compatibility with the old names. These macros are subject to removal at a future date, but probably not before 2009. An application can be tested to see if it is using any obsolete code by compiling it with the CURL_NO_OLDIES macro defined. Documented some newer error codes in libcurl-error(3) --- lib/url.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 82fcc3bd4..09febb075 100644 --- a/lib/url.c +++ b/lib/url.c @@ -813,16 +813,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.ftp_response_timeout = va_arg( param , long ) * 1000; break; - case CURLOPT_FTPLISTONLY: + case CURLOPT_DIRLISTONLY: /* - * An FTP option that changes the command to one that asks for a list + * An option that changes the command to one that asks for a list * only, no file info details. */ data->set.ftp_list_only = (bool)(0 != va_arg(param, long)); break; - case CURLOPT_FTPAPPEND: + case CURLOPT_APPEND: /* - * We want to upload and append to an existing (FTP) file. + * We want to upload and append to an existing file. */ data->set.ftp_append = (bool)(0 != va_arg(param, long)); break; @@ -1524,9 +1524,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE], va_arg(param, char *)); break; - case CURLOPT_SSLKEYPASSWD: + case CURLOPT_KEYPASSWD: /* - * String that holds the SSL private key password. + * String that holds the SSL or SSH private key password. */ result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], va_arg(param, char *)); @@ -1730,9 +1730,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.max_filesize = va_arg(param, long); break; - case CURLOPT_FTP_SSL: + case CURLOPT_USE_SSL: /* - * Make FTP transfers attempt to use SSL/TLS. + * Make transfers attempt to use SSL/TLS. */ data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long); break; @@ -4226,7 +4226,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, won't, and zero would be to switch it off so we never set it to less than 1! */ alarm(1); - result = CURLE_OPERATION_TIMEOUTED; + result = CURLE_OPERATION_TIMEDOUT; failf(data, "Previous alarm fired off!"); } else -- cgit v1.2.1 From 3fa60164af98720696cf157158e78ad4e0540aba Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 31 Aug 2007 19:36:32 +0000 Subject: Renamed the CURLE_FTP_SSL_FAILED error code to CURLE_USE_SSL_FAILED. Renamed the curl_ftpssl enum to curl_usessl and its enumerated constants, creating macros for backward compatibility. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 09febb075..9a7b22a94 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1734,7 +1734,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Make transfers attempt to use SSL/TLS. */ - data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long); + data->set.ftp_ssl = (curl_usessl)va_arg(param, long); break; case CURLOPT_FTPSSLAUTH: @@ -2948,7 +2948,7 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, #ifdef USE_SSL conn->protocol |= PROT_FTPS|PROT_SSL; /* send data securely unless specifically requested otherwise */ - conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLFTPSSL_CONTROL; + conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLUSESSL_CONTROL; port = PORT_FTPS; #else failf(data, LIBCURL_NAME -- cgit v1.2.1 From fd4cf78f36e89b8a0913e4fb34fd7a89f5c0cfd4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 26 Sep 2007 12:44:59 +0000 Subject: Philip Langdale provided the new CURLOPT_POST301 option for curl_easy_setopt() that alters how libcurl functions when following redirects. It makes libcurl obey the RFC2616 when a 301 response is received after a non-GET request is made. Default libcurl behaviour is to change method to GET in the subsequent request (like it does for response code 302 - because that's what many/most browsers do), but with this CURLOPT_POST301 option enabled it will do what the spec says and do the next request using the same method again. I.e keep POST after 301. The curl tool got this option as --post301 Test case 1011 and 1012 were added to verify. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9a7b22a94..6735b0179 100644 --- a/lib/url.c +++ b/lib/url.c @@ -924,6 +924,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.maxredirs = va_arg(param, long); break; + case CURLOPT_POST301: + /* + * Obey RFC 2616/10.3.2 and resubmit a POST as a POST after a 301. + */ + data->set.post301 = (bool)(0 != va_arg(param, long)); + break; + case CURLOPT_POST: /* Does this option serve a purpose anymore? Yes it does, when CURLOPT_POSTFIELDS isn't used and the POST data is read off the -- cgit v1.2.1 From 16b95fc77316fdd3866f7de4ebb5d14bd136ac11 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 27 Sep 2007 01:45:22 +0000 Subject: Enabled a few more gcc warnings with --enable-debug. Renamed a few variables to avoid shadowing global declarations. --- lib/url.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6735b0179..878c92d44 100644 --- a/lib/url.c +++ b/lib/url.c @@ -161,9 +161,9 @@ static bool IsPipeliningPossible(const struct SessionHandle *handle); static bool IsPipeliningEnabled(const struct SessionHandle *handle); static void conn_free(struct connectdata *conn); -static void signalPipeClose(struct curl_llist *pipe); +static void signalPipeClose(struct curl_llist *pipeline); -static struct SessionHandle* gethandleathead(struct curl_llist *pipe); +static struct SessionHandle* gethandleathead(struct curl_llist *pipeline); #define MAX_PIPELINE_LENGTH 5 @@ -292,7 +292,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) { struct conncache *c = data->state.connc; long i; - struct curl_llist *pipe; + struct curl_llist *pipeline; struct curl_llist_element *curr; struct connectdata *connptr; @@ -301,9 +301,9 @@ CURLcode Curl_close(struct SessionHandle *data) if(!connptr) continue; - pipe = connptr->send_pipe; - if(pipe) { - for (curr = pipe->head; curr; curr=curr->next) { + pipeline = connptr->send_pipe; + if(pipeline) { + for (curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "MAJOR problem we %p are still in send pipe for %p done %d\n", @@ -311,9 +311,9 @@ CURLcode Curl_close(struct SessionHandle *data) } } } - pipe = connptr->recv_pipe; - if(pipe) { - for (curr = pipe->head; curr; curr=curr->next) { + pipeline = connptr->recv_pipe; + if(pipeline) { + for (curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "MAJOR problem we %p are still in recv pipe for %p done %d\n", @@ -2036,30 +2036,30 @@ static bool IsPipeliningEnabled(const struct SessionHandle *handle) } CURLcode Curl_addHandleToPipeline(struct SessionHandle *data, - struct curl_llist *pipe) + struct curl_llist *pipeline) { #ifdef CURLDEBUG if(!IsPipeliningPossible(data)) { /* when not pipelined, there MUST be no handle in the list already */ - if(pipe->head) + if(pipeline->head) infof(data, "PIPE when no PIPE supposed!\n"); } #endif - if (!Curl_llist_insert_next(pipe, pipe->tail, data)) + if (!Curl_llist_insert_next(pipeline, pipeline->tail, data)) return CURLE_OUT_OF_MEMORY; return CURLE_OK; } int Curl_removeHandleFromPipeline(struct SessionHandle *handle, - struct curl_llist *pipe) + struct curl_llist *pipeline) { struct curl_llist_element *curr; - curr = pipe->head; + curr = pipeline->head; while (curr) { if (curr->ptr == handle) { - Curl_llist_remove(pipe, curr, NULL); + Curl_llist_remove(pipeline, curr, NULL); return 1; /* we removed a handle */ } curr = curr->next; @@ -2069,11 +2069,11 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle, } #if 0 /* this code is saved here as it is useful for debugging purposes */ -static void Curl_printPipeline(struct curl_llist *pipe) +static void Curl_printPipeline(struct curl_llist *pipeline) { struct curl_llist_element *curr; - curr = pipe->head; + curr = pipeline->head; while (curr) { struct SessionHandle *data = (struct SessionHandle *) curr->ptr; infof(data, "Handle in pipeline: %s\n", data->reqdata.path); @@ -2083,9 +2083,9 @@ static void Curl_printPipeline(struct curl_llist *pipe) #endif bool Curl_isHandleAtHead(struct SessionHandle *handle, - struct curl_llist *pipe) + struct curl_llist *pipeline) { - struct curl_llist_element *curr = pipe->head; + struct curl_llist_element *curr = pipeline->head; if (curr) { return (bool)(curr->ptr == handle); } @@ -2093,9 +2093,9 @@ bool Curl_isHandleAtHead(struct SessionHandle *handle, return FALSE; } -static struct SessionHandle* gethandleathead(struct curl_llist *pipe) +static struct SessionHandle* gethandleathead(struct curl_llist *pipeline) { - struct curl_llist_element *curr = pipe->head; + struct curl_llist_element *curr = pipeline->head; if (curr) { return (struct SessionHandle *) curr->ptr; } @@ -2103,14 +2103,14 @@ static struct SessionHandle* gethandleathead(struct curl_llist *pipe) return NULL; } -static void signalPipeClose(struct curl_llist *pipe) +static void signalPipeClose(struct curl_llist *pipeline) { struct curl_llist_element *curr; - if (!pipe) + if (!pipeline) return; - curr = pipe->head; + curr = pipeline->head; while (curr) { struct curl_llist_element *next = curr->next; struct SessionHandle *data = (struct SessionHandle *) curr->ptr; @@ -2124,7 +2124,7 @@ static void signalPipeClose(struct curl_llist *pipe) data->state.pipe_broke = TRUE; Curl_multi_handlePipeBreak(data); - Curl_llist_remove(pipe, curr, NULL); + Curl_llist_remove(pipeline, curr, NULL); curr = next; } } -- cgit v1.2.1 From 048bfeaaefe04001b6610b45a6ab6cfa02bcffd3 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 2 Oct 2007 15:26:30 +0000 Subject: Fix compiler warning --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 878c92d44..afb0b3837 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2884,7 +2884,7 @@ static CURLcode setup_range(struct SessionHandle *data) else req->range = strdup(data->set.str[STRING_SET_RANGE]); - req->rangestringalloc = req->range?TRUE:FALSE; + req->rangestringalloc = (unsigned char)(req->range?TRUE:FALSE); if(!req->range) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 51c6a5d43b09835289a469165aa7a2bfb79dbdc6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Oct 2007 08:00:42 +0000 Subject: Based on a patch brought by Johnny Luong, libcurl now offers CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 and the curl tool --hostpubmd5. They both make the SCP or SFTP connection verify the remote host's md5 checksum of the public key before doing a connect, to reduce the risk of a man-in-the-middle attack. --- lib/url.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index afb0b3837..c91d062fe 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1836,7 +1836,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], va_arg(param, char *)); break; - + case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: + /* + * Option to allow for the MD5 of the host public key to be checked + * for validation purposes. + */ + result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], + va_arg(param, char *)); + break; case CURLOPT_HTTP_TRANSFER_DECODING: /* * disable libcurl transfer encoding is used -- cgit v1.2.1 From ce1cfcb7a6a0956c3101f5a6eb20961024e55d84 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Oct 2007 08:45:00 +0000 Subject: Alexey Pesternikov introduced CURLOPT_OPENSOCKETFUNCTION and CURLOPT_OPENSOCKETDATA to set a callback that allows an application to replace the socket() call used by libcurl. It basically allows the app to change address, protocol or whatever of the socket. (I also did some whitespace indent/cleanups in lib/url.c which kind of hides some of these changes, sorry for mixing those in.) --- lib/url.c | 139 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 62 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c91d062fe..0571fd651 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1813,6 +1813,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.sockopt_client = va_arg(param, void *); break; + case CURLOPT_OPENSOCKETFUNCTION: + /* + * open/create socket callback function: called instead of socket(), + * before connect() + */ + data->set.fopensocket = va_arg(param, curl_opensocket_callback); + break; + + case CURLOPT_OPENSOCKETDATA: + /* + * socket callback data pointer. Might be NULL. + */ + data->set.opensocket_client = va_arg(param, void *); + break; + case CURLOPT_SSL_SESSIONID_CACHE: data->set.ssl.sessionid = (bool)(0 != va_arg(param, long)); break; @@ -1838,7 +1853,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: /* - * Option to allow for the MD5 of the host public key to be checked + * Option to allow for the MD5 of the host public key to be checked * for validation purposes. */ result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], @@ -2449,20 +2464,20 @@ static CURLcode ConnectPlease(struct SessionHandle *data, switch(data->set.proxytype) { case CURLPROXY_SOCKS5: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn); - break; + result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn); + break; case CURLPROXY_HTTP: - /* do nothing here. handled later. */ - break; + /* do nothing here. handled later. */ + break; case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, - FIRSTSOCKET, conn); - break; + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, + FIRSTSOCKET, conn); + break; default: - failf(data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - break; + failf(data, "unknown proxytype option given"); + result = CURLE_COULDNT_CONNECT; + break; } } } @@ -2910,7 +2925,7 @@ static CURLcode setup_range(struct SessionHandle *data) * Setup connection internals specific to the requested protocol ***************************************************************/ static CURLcode setup_connection_internals(struct SessionHandle *data, - struct connectdata *conn) + struct connectdata *conn) { conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ @@ -3237,17 +3252,17 @@ static char *detect_proxy(struct connectdata *conn) size_t namelen; char *endptr = strchr(conn->host.name, ':'); if(endptr) - namelen=endptr-conn->host.name; + namelen=endptr-conn->host.name; else - namelen=strlen(conn->host.name); + namelen=strlen(conn->host.name); if(strlen(nope) <= namelen) { - char *checkn= - conn->host.name + namelen - strlen(nope); - if(checkprefix(nope, checkn)) { - /* no proxy for this host! */ - break; - } + char *checkn= + conn->host.name + namelen - strlen(nope); + if(checkprefix(nope, checkn)) { + /* no proxy for this host! */ + break; + } } nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); } @@ -3259,7 +3274,7 @@ static char *detect_proxy(struct connectdata *conn) /* Now, build _proxy and check for such a one to use */ while(*protop) - *envp++ = (char)tolower((int)*protop++); + *envp++ = (char)tolower((int)*protop++); /* append _proxy */ strcpy(envp, "_proxy"); @@ -3280,29 +3295,29 @@ static char *detect_proxy(struct connectdata *conn) * arbitrarily redirected by any external attacker. */ if(!prox && !strequal("http_proxy", proxy_env)) { - /* There was no lowercase variable, try the uppercase version: */ - for(envp = proxy_env; *envp; envp++) - *envp = (char)toupper((int)*envp); - prox=curl_getenv(proxy_env); + /* There was no lowercase variable, try the uppercase version: */ + for(envp = proxy_env; *envp; envp++) + *envp = (char)toupper((int)*envp); + prox=curl_getenv(proxy_env); } if(prox && *prox) { /* don't count "" strings */ - proxy = prox; /* use this */ + proxy = prox; /* use this */ } else { - proxy = curl_getenv("all_proxy"); /* default proxy to use */ - if(!proxy) - proxy=curl_getenv("ALL_PROXY"); + proxy = curl_getenv("all_proxy"); /* default proxy to use */ + if(!proxy) + proxy=curl_getenv("ALL_PROXY"); } if(proxy && *proxy) { - long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); + long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); - if(conn->proxytype == CURLPROXY_HTTP) { - /* force this connection's protocol to become HTTP */ - conn->protocol = PROT_HTTP | bits; - conn->bits.httpproxy = TRUE; - } + if(conn->proxytype == CURLPROXY_HTTP) { + /* force this connection's protocol to become HTTP */ + conn->protocol = PROT_HTTP | bits; + conn->bits.httpproxy = TRUE; + } } } /* if (!nope) - it wasn't specified non-proxy */ } /* NO_PROXY wasn't specified or '*' */ @@ -3351,43 +3366,43 @@ static CURLcode parse_proxy(struct SessionHandle *data, proxypasswd[0] = 0; if(1 <= sscanf(proxyptr, - "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - proxyuser, proxypasswd)) { + "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", + proxyuser, proxypasswd)) { CURLcode res = CURLE_OK; /* found user and password, rip them out. note that we are - unescaping them, as there is otherwise no way to have a - username or password with reserved characters like ':' in - them. */ + unescaping them, as there is otherwise no way to have a + username or password with reserved characters like ':' in + them. */ Curl_safefree(conn->proxyuser); conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); if(!conn->proxyuser) - res = CURLE_OUT_OF_MEMORY; + res = CURLE_OUT_OF_MEMORY; else { - Curl_safefree(conn->proxypasswd); - conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); + Curl_safefree(conn->proxypasswd); + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); - if(!conn->proxypasswd) - res = CURLE_OUT_OF_MEMORY; + if(!conn->proxypasswd) + res = CURLE_OUT_OF_MEMORY; } if(CURLE_OK == res) { - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - atsign = strdup(atsign+1); /* the right side of the @-letter */ - - if(atsign) { - free(proxy); /* free the former proxy string */ - proxy = proxyptr = atsign; /* now use this instead */ - } - else - res = CURLE_OUT_OF_MEMORY; + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + atsign = strdup(atsign+1); /* the right side of the @-letter */ + + if(atsign) { + free(proxy); /* free the former proxy string */ + proxy = proxyptr = atsign; /* now use this instead */ + } + else + res = CURLE_OUT_OF_MEMORY; } if(res) { - free(proxy); /* free the allocated proxy string */ - return res; + free(proxy); /* free the allocated proxy string */ + return res; } } } @@ -3443,9 +3458,9 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, struct connectdata char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; sscanf(data->set.str[STRING_PROXYUSERPWD], - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - proxyuser, proxypasswd); + "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", + proxyuser, proxypasswd); conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); if(!conn->proxyuser) @@ -3633,7 +3648,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, if(conn->bits.proxy_user_passwd) { result = parse_proxy_auth(data, conn); if (result != CURLE_OK) - return result; + return result; } /************************************************************* -- cgit v1.2.1 From 4449bd9b4dffc67b4c0597414d816a123e9a98e5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Oct 2007 14:37:33 +0000 Subject: Michael Wallner made the CULROPT_COOKIELIST option support a new magic string: "FLUSH". Using that will cause libcurl to flush its cookies to the CURLOPT_COOKIEJAR file. --- lib/url.c | 64 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 24 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0571fd651..c74a1d858 100644 --- a/lib/url.c +++ b/lib/url.c @@ -165,6 +165,10 @@ static void signalPipeClose(struct curl_llist *pipeline); static struct SessionHandle* gethandleathead(struct curl_llist *pipeline); +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) +static void flush_cookies(struct SessionHandle *data, int cleanup); +#endif + #define MAX_PIPELINE_LENGTH 5 /* @@ -269,6 +273,36 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) return r; } +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) +static void flush_cookies(struct SessionHandle *data, int cleanup) +{ + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + if(data->set.str[STRING_COOKIEJAR]) { + if(data->change.cookielist) { + /* If there is a list of cookie files to read, do it first so that + we have all the told files read before we write the new jar */ + Curl_cookie_loadfiles(data); + } + + /* we have a "destination" for all the cookies to get dumped to */ + if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) + infof(data, "WARNING: failed to save cookies in %s\n", + data->set.str[STRING_COOKIEJAR]); + } + else { + if(cleanup && data->change.cookielist) + /* since nothing is written, we can just free the list of cookie file + names */ + curl_slist_free_all(data->change.cookielist); /* clean up list */ + } + + if(cleanup && (!data->share || (data->cookies != data->share->cookies))) { + Curl_cookie_cleanup(data->cookies); + } + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); +} +#endif + /* * This is the internal function curl_easy_cleanup() calls. This should * cleanup and free all resources associated with this sessionhandle. @@ -380,30 +414,7 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.headerbuff); #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(data->set.str[STRING_COOKIEJAR]) { - if(data->change.cookielist) { - /* If there is a list of cookie files to read, do it first so that - we have all the told files read before we write the new jar */ - Curl_cookie_loadfiles(data); - } - - /* we have a "destination" for all the cookies to get dumped to */ - if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) - infof(data, "WARNING: failed to save cookies in %s\n", - data->set.str[STRING_COOKIEJAR]); - } - else { - if(data->change.cookielist) - /* since nothing is written, we can just free the list of cookie file - names */ - curl_slist_free_all(data->change.cookielist); /* clean up list */ - } - - if( !data->share || (data->cookies != data->share->cookies) ) { - Curl_cookie_cleanup(data->cookies); - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + flush_cookies(data, 1); #endif Curl_digest_cleanup(data); @@ -1089,6 +1100,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, Curl_cookie_clearsess(data->cookies); break; } + else if(strequal(argptr, "FLUSH")) { + /* flush cookies to file */ + flush_cookies(data, 0); + break; + } if(!data->cookies) /* if cookie engine was not running, activate it */ -- cgit v1.2.1 From 07b6e7363d910ad4828376d568a2f19fd8d64661 Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Fri, 12 Oct 2007 13:36:37 +0000 Subject: Added per-protocol callback static tables, replacing callback ptr storage in the connectdata structure by a single handler table ptr. --- lib/url.c | 409 ++++++++++++++++++-------------------------------------------- 1 file changed, 120 insertions(+), 289 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c74a1d858..bc3d235a8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -178,6 +178,7 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); #define ZERO_NULL 0 + #ifndef USE_ARES /* not for ares builds */ @@ -188,6 +189,82 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); extern sigjmp_buf curl_jmpenv; #endif + +/* + * Protocol table. + */ + +static const struct Curl_handler * protocols[] = { + +#ifndef CURL_DISABLE_HTTP + &Curl_handler_http, +#endif + +#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + &Curl_handler_https, +#endif + +#ifndef CURL_DISABLE_FTP + &Curl_handler_ftp, +#endif + +#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) + &Curl_handler_ftps, +#endif + +#ifndef CURL_DISABLE_TELNET + &Curl_handler_telnet, +#endif + +#ifndef CURL_DISABLE_DICT + &Curl_handler_dict, +#endif + +#ifndef CURL_DISABLE_LDAP + &Curl_handler_ldap, +#endif + +#if defined(HAVE_LDAP_SSL) && !defined(CURL_DISABLE_SSL) + &Curl_handler_ldaps, +#endif + +#ifndef CURL_DISABLE_FILE + &Curl_handler_file, +#endif + +#ifndef CURL_DISABLE_TFTP + &Curl_handler_tftp, +#endif + +#ifdef USE_LIBSSH2 + &Curl_handler_scp, + &Curl_handler_sftp, +#endif + + (struct Curl_handler *) NULL +}; + +/* + * Dummy handler for undefined protocol schemes. + */ + +const struct Curl_handler Curl_handler_dummy = { + "", /* scheme */ + NULL, /* setup_connection */ + NULL, /* do_it */ + NULL, /* done */ + NULL, /* do_more */ + NULL, /* connect_it */ + NULL, /* connecting */ + NULL, /* doing */ + NULL, /* proto_getsock */ + NULL, /* doing_getsock */ + NULL, /* disconnect */ + 0, /* defport */ + 0 /* protocol */ +}; + + #ifdef SIGALRM static RETSIGTYPE alarmfunc(int sig) @@ -1999,9 +2076,9 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_ntlm_cleanup(conn); } - if(conn->curl_disconnect) + if(conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ - conn->curl_disconnect(conn); + conn->handler->disconnect(conn); if(-1 != conn->connectindex) { /* unlink ourselves! */ @@ -2519,8 +2596,8 @@ int Curl_protocol_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) { - if(conn->curl_proto_getsock) - return conn->curl_proto_getsock(conn, socks, numsocks); + if(conn->handler->proto_getsock) + return conn->handler->proto_getsock(conn, socks, numsocks); return GETSOCK_BLANK; } @@ -2528,8 +2605,8 @@ int Curl_doing_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) { - if(conn && conn->curl_doing_getsock) - return conn->curl_doing_getsock(conn, socks, numsocks); + if(conn && conn->handler && conn->handler->doing_getsock) + return conn->handler->doing_getsock(conn, socks, numsocks); return GETSOCK_BLANK; } @@ -2544,9 +2621,9 @@ CURLcode Curl_protocol_connecting(struct connectdata *conn, { CURLcode result=CURLE_OK; - if(conn && conn->curl_connecting) { + if(conn && conn->handler && conn->handler->connecting) { *done = FALSE; - result = conn->curl_connecting(conn, done); + result = conn->handler->connecting(conn, done); } else *done = TRUE; @@ -2563,9 +2640,9 @@ CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) { CURLcode result=CURLE_OK; - if(conn && conn->curl_doing) { + if(conn && conn->handler && conn->handler->doing) { *done = FALSE; - result = conn->curl_doing(conn, done); + result = conn->handler->doing(conn, done); } else *done = TRUE; @@ -2593,7 +2670,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, Unless this protocol doesn't have any protocol-connect callback, as then we know we're done. */ - if(!conn->curl_connecting) + if(!conn->handler->connecting) *protocol_done = TRUE; return CURLE_OK; @@ -2608,7 +2685,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, } if(!conn->bits.protoconnstart) { - if(conn->curl_connect) { + if(conn->handler->connect_it) { /* is there a protocol-specific connect() procedure? */ /* Set start time here for timeout purposes in the connect procedure, it @@ -2616,7 +2693,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, conn->now = Curl_tvnow(); /* Call the protocol-specific connect function */ - result = conn->curl_connect(conn, protocol_done); + result = conn->handler->connect_it(conn, protocol_done); } else *protocol_done = TRUE; @@ -2943,285 +3020,39 @@ static CURLcode setup_range(struct SessionHandle *data) static CURLcode setup_connection_internals(struct SessionHandle *data, struct connectdata *conn) { - conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ - - if (strequal(conn->protostr, "HTTP")) { -#ifndef CURL_DISABLE_HTTP - conn->port = PORT_HTTP; - conn->remote_port = PORT_HTTP; - conn->protocol |= PROT_HTTP; - conn->curl_do = Curl_http; - conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; - conn->curl_done = Curl_http_done; - conn->curl_connect = Curl_http_connect; -#else - failf(data, LIBCURL_NAME - " was built with HTTP disabled, http: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } + const struct Curl_handler * * pp; + const struct Curl_handler * p; + CURLcode result; - else if (strequal(conn->protostr, "HTTPS")) { -#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ - conn->port = PORT_HTTPS; - conn->remote_port = PORT_HTTPS; - conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL; - - conn->curl_do = Curl_http; - conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; - conn->curl_done = Curl_http_done; - conn->curl_connect = Curl_http_connect; - conn->curl_connecting = Curl_https_connecting; - conn->curl_proto_getsock = Curl_https_getsock; - -#else /* USE_SSL */ - failf(data, LIBCURL_NAME - " was built with SSL disabled, https: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif /* !USE_SSL */ - } + /* Scan protocol handler table. */ - else if(strequal(conn->protostr, "FTP") || - strequal(conn->protostr, "FTPS")) { + for (pp = protocols; p = *pp; pp++) + if (strequal(p->scheme, conn->protostr)) { + /* Protocol found in table. Perform setup complement if some. */ + conn->handler = p; -#ifndef CURL_DISABLE_FTP - char *type; - int port = PORT_FTP; - - if(strequal(conn->protostr, "FTPS")) { -#ifdef USE_SSL - conn->protocol |= PROT_FTPS|PROT_SSL; - /* send data securely unless specifically requested otherwise */ - conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLUSESSL_CONTROL; - port = PORT_FTPS; -#else - failf(data, LIBCURL_NAME - " was built with SSL disabled, ftps: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif /* !USE_SSL */ - } + if (p->setup_connection) { + result = (*p->setup_connection)(conn); - conn->port = port; - conn->remote_port = (unsigned short)port; - conn->protocol |= PROT_FTP; + if (result != CURLE_OK) + return result; - if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) { - /* Unless we have asked to tunnel ftp operations through the proxy, we - switch and use HTTP operations only */ -#ifndef CURL_DISABLE_HTTP - conn->curl_do = Curl_http; - conn->curl_done = Curl_http_done; - conn->protocol = PROT_HTTP; /* switch to HTTP */ -#else - failf(data, "FTP over http proxy requires HTTP support built-in!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - else { - conn->curl_do = Curl_ftp; - conn->curl_do_more = Curl_ftp_nextconnect; - conn->curl_done = Curl_ftp_done; - conn->curl_connect = Curl_ftp_connect; - conn->curl_connecting = Curl_ftp_multi_statemach; - conn->curl_doing = Curl_ftp_doing; - conn->curl_proto_getsock = Curl_ftp_getsock; - conn->curl_doing_getsock = Curl_ftp_getsock; - conn->curl_disconnect = Curl_ftp_disconnect; - } - - data->reqdata.path++; /* don't include the initial slash */ - - /* FTP URLs support an extension like ";type=" that - * we'll try to get now! */ - type=strstr(data->reqdata.path, ";type="); - if(!type) { - type=strstr(conn->host.rawalloc, ";type="); - } - if(type) { - char command; - *type=0; /* it was in the middle of the hostname */ - command = (char)toupper((int)type[6]); - switch(command) { - case 'A': /* ASCII mode */ - data->set.prefer_ascii = TRUE; - break; - case 'D': /* directory mode */ - data->set.ftp_list_only = TRUE; - break; - case 'I': /* binary mode */ - default: - /* switch off ASCII */ - data->set.prefer_ascii = FALSE; - break; + p = conn->handler; /* May have changed. */ } - } -#else /* CURL_DISABLE_FTP */ - failf(data, LIBCURL_NAME - " was built with FTP disabled, ftp/ftps: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - else if(strequal(conn->protostr, "TELNET")) { -#ifndef CURL_DISABLE_TELNET - /* telnet testing factory */ - conn->protocol |= PROT_TELNET; - - conn->port = PORT_TELNET; - conn->remote_port = PORT_TELNET; - conn->curl_do = Curl_telnet; - conn->curl_done = Curl_telnet_done; -#else - failf(data, LIBCURL_NAME - " was built with TELNET disabled!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - else if (strequal(conn->protostr, "DICT")) { -#ifndef CURL_DISABLE_DICT - conn->protocol |= PROT_DICT; - conn->port = PORT_DICT; - conn->remote_port = PORT_DICT; - conn->curl_do = Curl_dict; - /* no DICT-specific done */ - conn->curl_done = (Curl_done_func)ZERO_NULL; -#else - failf(data, LIBCURL_NAME - " was built with DICT disabled!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - else if (strequal(conn->protostr, "LDAP")) { -#ifndef CURL_DISABLE_LDAP - conn->protocol |= PROT_LDAP; - conn->port = PORT_LDAP; - conn->remote_port = PORT_LDAP; - conn->curl_do = Curl_ldap; - /* no LDAP-specific done */ - conn->curl_done = (Curl_done_func)ZERO_NULL; -#else - failf(data, LIBCURL_NAME - " was built with LDAP disabled!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - -#ifdef HAVE_LDAP_SSL - else if (strequal(conn->protostr, "LDAPS")) { -#ifndef CURL_DISABLE_LDAP - conn->protocol |= PROT_LDAP|PROT_SSL; - conn->port = PORT_LDAPS; - conn->remote_port = PORT_LDAPS; - conn->curl_do = Curl_ldap; - /* no LDAP-specific done */ - conn->curl_done = (Curl_done_func)ZERO_NULL; -#else - failf(data, LIBCURL_NAME - " was built with LDAP disabled!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } -#endif /* CURL_LDAP_USE_SSL */ - - else if (strequal(conn->protostr, "FILE")) { -#ifndef CURL_DISABLE_FILE - conn->protocol |= PROT_FILE; - - conn->curl_do = Curl_file; - conn->curl_done = Curl_file_done; -#else - failf(data, LIBCURL_NAME - " was built with FILE disabled!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - else if (strequal(conn->protostr, "TFTP")) { -#ifndef CURL_DISABLE_TFTP - char *type; - conn->socktype = SOCK_DGRAM; /* UDP datagram based */ - conn->protocol |= PROT_TFTP; - conn->port = PORT_TFTP; - conn->remote_port = PORT_TFTP; - conn->curl_connect = Curl_tftp_connect; - conn->curl_do = Curl_tftp; - conn->curl_done = Curl_tftp_done; - /* TFTP URLs support an extension like ";mode=" that - * we'll try to get now! */ - type=strstr(data->reqdata.path, ";mode="); - if(!type) { - type=strstr(conn->host.rawalloc, ";mode="); + conn->port = p->defport; + conn->remote_port = p->defport; + conn->protocol |= p->protocol; + return CURLE_OK; } - if(type) { - char command; - *type=0; /* it was in the middle of the hostname */ - command = (char)toupper((int)type[6]); - switch(command) { - case 'A': /* ASCII mode */ - case 'N': /* NETASCII mode */ - data->set.prefer_ascii = TRUE; - break; - case 'O': /* octet mode */ - case 'I': /* binary mode */ - default: - /* switch off ASCII */ - data->set.prefer_ascii = FALSE; - break; - } - } -#else - failf(data, LIBCURL_NAME - " was built with TFTP disabled!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - else if (strequal(conn->protostr, "SCP")) { -#ifdef USE_LIBSSH2 - conn->port = PORT_SSH; - conn->remote_port = PORT_SSH; - conn->protocol = PROT_SCP; - conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ - conn->curl_do = Curl_scp_do; - conn->curl_done = Curl_scp_done; - conn->curl_connecting = Curl_ssh_multi_statemach; - conn->curl_doing = Curl_scp_doing; - conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; -#else - failf(data, LIBCURL_NAME - " was built without LIBSSH2, scp: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - else if (strequal(conn->protostr, "SFTP")) { -#ifdef USE_LIBSSH2 - conn->port = PORT_SSH; - conn->remote_port = PORT_SSH; - conn->protocol = PROT_SFTP; - conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ - conn->curl_do = Curl_sftp_do; - conn->curl_done = Curl_sftp_done; - conn->curl_connecting = Curl_ssh_multi_statemach; - conn->curl_doing = Curl_sftp_doing; - conn->curl_do_more = (Curl_do_more_func)ZERO_NULL; -#else - failf(data, LIBCURL_NAME - " was built without LIBSSH2, scp: not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - else { - /* We fell through all checks and thus we don't support the specified - protocol */ - failf(data, "Unsupported protocol: %s", conn->protostr); - return CURLE_UNSUPPORTED_PROTOCOL; - } - return CURLE_OK; + /* Protocol not found in table. */ + conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined. */ + failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME, + conn->protostr); + return CURLE_UNSUPPORTED_PROTOCOL; } /**************************************************************** @@ -4495,8 +4326,8 @@ CURLcode Curl_done(struct connectdata **connp, } /* this calls the protocol-specific function pointer previously set */ - if(conn->curl_done) - result = conn->curl_done(conn, status, premature); + if(conn->handler->done) + result = conn->handler->done(conn, status, premature); else result = CURLE_OK; @@ -4548,9 +4379,9 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) conn->bits.done = FALSE; /* Curl_done() is not called yet */ conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ - if(conn->curl_do) { + if(conn->handler->do_it) { /* generic protocol-specific function pointer set in curl_connect() */ - result = conn->curl_do(conn, done); + result = conn->handler->do_it(conn, done); /* This was formerly done in transfer.c, but we better do it here */ @@ -4599,7 +4430,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) } /* ... finally back to actually retry the DO phase */ - result = conn->curl_do(conn, done); + result = conn->handler->do_it(conn, done); } } } @@ -4611,8 +4442,8 @@ CURLcode Curl_do_more(struct connectdata *conn) { CURLcode result=CURLE_OK; - if(conn->curl_do_more) - result = conn->curl_do_more(conn); + if(conn->handler->do_more) + result = conn->handler->do_more(conn); return result; } -- cgit v1.2.1 From 7831c1ae445b9920440dd40e52e6ead31dfbe962 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 12 Oct 2007 18:49:14 +0000 Subject: Fixed a few compile errors and warnings. --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bc3d235a8..59a2d09cd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -194,7 +194,7 @@ extern sigjmp_buf curl_jmpenv; * Protocol table. */ -static const struct Curl_handler * protocols[] = { +static const struct Curl_handler * const protocols[] = { #ifndef CURL_DISABLE_HTTP &Curl_handler_http, @@ -3020,7 +3020,7 @@ static CURLcode setup_range(struct SessionHandle *data) static CURLcode setup_connection_internals(struct SessionHandle *data, struct connectdata *conn) { - const struct Curl_handler * * pp; + const struct Curl_handler * const * pp; const struct Curl_handler * p; CURLcode result; @@ -3028,7 +3028,7 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, /* Scan protocol handler table. */ - for (pp = protocols; p = *pp; pp++) + for (pp = protocols; (p = *pp) != NULL; pp++) if (strequal(p->scheme, conn->protostr)) { /* Protocol found in table. Perform setup complement if some. */ conn->handler = p; -- cgit v1.2.1 From a9f47b93641b3c59f7f8b01639540aafa7d33881 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Oct 2007 20:53:43 +0000 Subject: another Curl_handler fix, the #ifdefs got a bit mixed up... --- lib/url.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 59a2d09cd..047df97a9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -189,6 +189,20 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); extern sigjmp_buf curl_jmpenv; #endif +#ifdef SIGALRM +static +RETSIGTYPE alarmfunc(int sig) +{ + /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ + (void)sig; +#ifdef HAVE_SIGSETJMP + siglongjmp(curl_jmpenv, 1); +#endif + return; +} +#endif /* SIGALRM */ +#endif /* WIN32 */ +#endif /* USE_ARES */ /* * Protocol table. @@ -264,22 +278,6 @@ const struct Curl_handler Curl_handler_dummy = { 0 /* protocol */ }; - -#ifdef SIGALRM -static -RETSIGTYPE alarmfunc(int sig) -{ - /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ - (void)sig; -#ifdef HAVE_SIGSETJMP - siglongjmp(curl_jmpenv, 1); -#endif - return; -} -#endif /* SIGALRM */ -#endif /* WIN32 */ -#endif /* USE_ARES */ - #ifdef CURL_DISABLE_VERBOSE_STRINGS #define verboseconnect(x) do { } while (0) #endif -- cgit v1.2.1 From 61ffcd781599ac9a9f85b92f4be10588f2015721 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Sat, 13 Oct 2007 00:47:53 +0000 Subject: Made a few more functions static with the protocol handler table in place. --- lib/url.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 047df97a9..549e640b3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -169,6 +169,10 @@ static struct SessionHandle* gethandleathead(struct curl_llist *pipeline); static void flush_cookies(struct SessionHandle *data, int cleanup); #endif +#ifdef CURL_DISABLE_VERBOSE_STRINGS +#define verboseconnect(x) do { } while (0) +#endif + #define MAX_PIPELINE_LENGTH 5 /* @@ -262,7 +266,7 @@ static const struct Curl_handler * const protocols[] = { * Dummy handler for undefined protocol schemes. */ -const struct Curl_handler Curl_handler_dummy = { +static const struct Curl_handler Curl_handler_dummy = { "", /* scheme */ NULL, /* setup_connection */ NULL, /* do_it */ @@ -278,10 +282,6 @@ const struct Curl_handler Curl_handler_dummy = { 0 /* protocol */ }; -#ifdef CURL_DISABLE_VERBOSE_STRINGS -#define verboseconnect(x) do { } while (0) -#endif - void Curl_safefree(void *ptr) { if(ptr) @@ -3579,7 +3579,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, result = setup_range(data); if(result) { - Curl_file_done(conn, result, FALSE); + if(conn->handler->done) + result = conn->handler->done(conn, result, FALSE); return result; } -- cgit v1.2.1 From 001a2d9b67f3bf685c5a2df6495b999cc3966acc Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 15 Oct 2007 16:24:46 +0000 Subject: Fix LDAP compile error when LDAP is not available. Fixed a typo in the LDAP configure code and made sure NULL is defined in a test programs that need it. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 549e640b3..e6b0d7f27 100644 --- a/lib/url.c +++ b/lib/url.c @@ -242,7 +242,7 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_ldap, #endif -#if defined(HAVE_LDAP_SSL) && !defined(CURL_DISABLE_SSL) +#if !defined(CURL_DISABLE_LDAP) && defined(HAVE_LDAP_SSL) &Curl_handler_ldaps, #endif -- cgit v1.2.1 From a005243908803662d4a05427bc1061db42f4d057 Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Mon, 15 Oct 2007 18:32:01 +0000 Subject: Fix dynamic CURLOPT_POSTFIELDS bug: back to static. CURLOPT_COPYPOSTFIELDS option added for dynamic. Fix some OS400 features. --- lib/url.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e6b0d7f27..35dce9541 100644 --- a/lib/url.c +++ b/lib/url.c @@ -771,6 +771,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, va_list param) { char *argptr; + curl_off_t bigsize; CURLcode result = CURLE_OK; switch(option) { @@ -1029,12 +1030,52 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.httpreq = HTTPREQ_GET; break; - case CURLOPT_POSTFIELDS: + case CURLOPT_COPYPOSTFIELDS: /* * A string with POST data. Makes curl HTTP POST. Even if it is NULL. + * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to + * CURLOPT_COPYPOSTFIELDS and not altered later. */ - result = Curl_setstropt(&data->set.str[STRING_POSTFIELDS], - va_arg(param, char *)); + argptr = va_arg(param, char *); + + if (!argptr || data->set.postfieldsize == -1) + result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); + else { + /* + * Check that request length does not overflow the size_t type. + */ + + if ((curl_off_t) ((size_t) data->set.postfieldsize) != + data->set.postfieldsize || + data->set.postfieldsize < (curl_off_t) 0 || + (size_t) data->set.postfieldsize < (size_t) 0) + result = CURLE_OUT_OF_MEMORY; + else { + char * p; + + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + p = malloc(data->set.postfieldsize); + + if (!p) + result = CURLE_OUT_OF_MEMORY; + else { + memcpy(p, argptr, data->set.postfieldsize); + data->set.str[STRING_COPYPOSTFIELDS] = p; + } + } + } + + data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS]; + data->set.httpreq = HTTPREQ_POST; + break; + + case CURLOPT_POSTFIELDS: + /* + * Like above, but use static data instead of copying it. + */ + data->set.postfields = va_arg(param, void *); + /* Release old copied data. */ + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); data->set.httpreq = HTTPREQ_POST; break; @@ -1043,7 +1084,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * The size of the POSTFIELD data to prevent libcurl to do strlen() to * figure it out. Enables binary posts. */ - data->set.postfieldsize = va_arg(param, long); + bigsize = va_arg(param, long); + + if (data->set.postfieldsize < bigsize && + data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { + /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + data->set.postfields = NULL; + } + + data->set.postfieldsize = bigsize; break; case CURLOPT_POSTFIELDSIZE_LARGE: @@ -1051,7 +1101,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * The size of the POSTFIELD data to prevent libcurl to do strlen() to * figure it out. Enables binary posts. */ - data->set.postfieldsize = va_arg(param, curl_off_t); + bigsize = va_arg(param, curl_off_t); + + if (data->set.postfieldsize < bigsize && + data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { + /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + data->set.postfields = NULL; + } + + data->set.postfieldsize = bigsize; break; case CURLOPT_HTTPPOST: -- cgit v1.2.1 From 65ba6e3337d5f328c614a9e6b8e15b8d74d9b5e9 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 16 Oct 2007 18:09:57 +0000 Subject: Fixed compiler warning re: unused variable `bigsize' --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 35dce9541..461bfe36b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -771,8 +771,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, va_list param) { char *argptr; - curl_off_t bigsize; CURLcode result = CURLE_OK; +#ifndef CURL_DISABLE_HTTP + curl_off_t bigsize; +#endif switch(option) { case CURLOPT_DNS_CACHE_TIMEOUT: -- cgit v1.2.1 From c6ef31955a3990f28a009fd0a63127fada7bbffb Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 16 Oct 2007 23:32:02 +0000 Subject: ANSI C compliant overflow check --- lib/url.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 461bfe36b..e605fdcd0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1047,10 +1047,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Check that request length does not overflow the size_t type. */ - if ((curl_off_t) ((size_t) data->set.postfieldsize) != - data->set.postfieldsize || - data->set.postfieldsize < (curl_off_t) 0 || - (size_t) data->set.postfieldsize < (size_t) 0) + if ((data->set.postfieldsize < 0) || + (data->set.postfieldsize > (curl_off_t)((size_t)-1))) result = CURLE_OUT_OF_MEMORY; else { char * p; -- cgit v1.2.1 From 92433e596b7fbfa5c75926705dcfef0080ebf012 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 17 Oct 2007 16:58:32 +0000 Subject: We use this ZERO_NULL to avoid picky compiler warnings, when assigning a NULL pointer to a function pointer var. --- lib/url.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e605fdcd0..eab1d6d55 100644 --- a/lib/url.c +++ b/lib/url.c @@ -175,14 +175,6 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); #define MAX_PIPELINE_LENGTH 5 -/* - * We use this ZERO_NULL to avoid picky compiler warnings, - * when assigning a NULL pointer to a function pointer var. - */ - -#define ZERO_NULL 0 - - #ifndef USE_ARES /* not for ares builds */ @@ -268,16 +260,16 @@ static const struct Curl_handler * const protocols[] = { static const struct Curl_handler Curl_handler_dummy = { "", /* scheme */ - NULL, /* setup_connection */ - NULL, /* do_it */ - NULL, /* done */ - NULL, /* do_more */ - NULL, /* connect_it */ - NULL, /* connecting */ - NULL, /* doing */ - NULL, /* proto_getsock */ - NULL, /* doing_getsock */ - NULL, /* disconnect */ + ZERO_NULL, /* setup_connection */ + ZERO_NULL, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* disconnect */ 0, /* defport */ 0 /* protocol */ }; -- cgit v1.2.1 From e7387f7557ae3bde7e4b75befedd88ee04913b49 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 17 Oct 2007 18:06:32 +0000 Subject: Fix overflow detection, thanks to Patrick Monnerat detecting test failure condition: http://curl.haxx.se/mail/lib-2007-10/0152.html --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index eab1d6d55..35d2d046b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1039,8 +1039,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Check that request length does not overflow the size_t type. */ - if ((data->set.postfieldsize < 0) || - (data->set.postfieldsize > (curl_off_t)((size_t)-1))) + if ((sizeof(curl_off_t) != sizeof(size_t)) && + ((data->set.postfieldsize < 0) || + (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) result = CURLE_OUT_OF_MEMORY; else { char * p; -- cgit v1.2.1 From 0164f0cf81413948c756e3a7f7003ec5b1094149 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 17 Oct 2007 19:29:06 +0000 Subject: Fix overflow detection, take four. Avoiding zero size malloc. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 35d2d046b..b0bc96a3b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1039,8 +1039,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Check that request length does not overflow the size_t type. */ - if ((sizeof(curl_off_t) != sizeof(size_t)) && - ((data->set.postfieldsize < 0) || + if ((data->set.postfieldsize < 1) || + ((sizeof(curl_off_t) != sizeof(size_t)) && (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) result = CURLE_OUT_OF_MEMORY; else { -- cgit v1.2.1 From bef2e7f2ff93902a34d999e1ede75ba4f9aabcd0 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 18 Oct 2007 01:04:57 +0000 Subject: Avoid a NULL pointer dereference in an OOM condition. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b0bc96a3b..373fd4534 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2126,7 +2126,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_ntlm_cleanup(conn); } - if(conn->handler->disconnect) + if(conn->handler && conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ conn->handler->disconnect(conn); -- cgit v1.2.1 From 8f5909b6648ed2833418827241805fa4eaa609f2 Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Thu, 18 Oct 2007 10:54:49 +0000 Subject: Allow CURLOPT_COPYPOSTFIELDS with explicit data size = 0 --- lib/url.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 373fd4534..6f6d8c226 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1036,10 +1036,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); else { /* - * Check that request length does not overflow the size_t type. + * Check that requested length does not overflow the size_t type. */ - if ((data->set.postfieldsize < 1) || + if ((data->set.postfieldsize < 0) || ((sizeof(curl_off_t) != sizeof(size_t)) && (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) result = CURLE_OUT_OF_MEMORY; @@ -1047,14 +1047,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, char * p; (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); - p = malloc(data->set.postfieldsize); + + /* Allocate even when size == 0. This satisfies the need of possible + later address compare to detect the COPYPOSTFIELDS mode, and + to mark that postfields is used rather than read function or + form data. + */ + p = malloc(data->set.postfieldsize? data->set.postfieldsize: 1); if (!p) result = CURLE_OUT_OF_MEMORY; else { - memcpy(p, argptr, data->set.postfieldsize); + if (data->set.postfieldsize) + memcpy(p, argptr, data->set.postfieldsize); + data->set.str[STRING_COPYPOSTFIELDS] = p; - } + } } } -- cgit v1.2.1 From 5c8fc7dce9668a141a01781159817552a7cb4ef8 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 20 Oct 2007 15:11:51 +0000 Subject: Fix compiler warning: conversion from "int" to "unsigned short" may lose significant bits --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6f6d8c226..e7ef80246 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3101,7 +3101,7 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, } conn->port = p->defport; - conn->remote_port = p->defport; + conn->remote_port = (unsigned short)p->defport; conn->protocol |= p->protocol; return CURLE_OK; } -- cgit v1.2.1 From 7fe89c5d29c633ef0777bd5f5689649d1ad7eec7 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 20 Oct 2007 15:47:16 +0000 Subject: We use this ZERO_NULL to avoid picky compiler warnings, when assigning a NULL pointer to a function pointer var. --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e7ef80246..8685c61a2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -683,9 +683,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.fread_func = (curl_read_callback)fread; /* conversion callbacks for non-ASCII hosts */ - data->set.convfromnetwork = (curl_conv_callback)ZERO_NULL; - data->set.convtonetwork = (curl_conv_callback)ZERO_NULL; - data->set.convfromutf8 = (curl_conv_callback)ZERO_NULL; + data->set.convfromnetwork = ZERO_NULL; + data->set.convtonetwork = ZERO_NULL; + data->set.convfromutf8 = ZERO_NULL; #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) /* conversion descriptors for iconv calls */ -- cgit v1.2.1 From 1056dc9a26db39bdb31f5f0b49080b13df3cb528 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 22 Oct 2007 09:25:45 +0000 Subject: Bug report #1815530 (http://curl.haxx.se/bug/view.cgi?id=1815530) points out that specifying a proxy with a trailing slash didn't work (unless it also contained a port number). --- lib/url.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8685c61a2..212e184f7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3339,10 +3339,17 @@ static CURLcode parse_proxy(struct SessionHandle *data, /* now set the local port number */ conn->port = atoi(prox_portno); } - else if(data->set.proxyport) { - /* None given in the proxy string, then get the default one if it is - given */ - conn->port = data->set.proxyport; + else { + /* without a port number after the host name, some people seem to use + a slash so we strip everything from the first slash */ + atsign = strchr(proxyptr, '/'); + if(atsign) + *atsign = 0x0; /* cut off path part from host name */ + + if(data->set.proxyport) + /* None given in the proxy string, then get the default one if it is + given */ + conn->port = data->set.proxyport; } /* now, clone the cleaned proxy host name */ @@ -3357,7 +3364,8 @@ static CURLcode parse_proxy(struct SessionHandle *data, } /* Extract the user and password from the authentication string */ -static CURLcode parse_proxy_auth(struct SessionHandle *data, struct connectdata *conn) +static CURLcode parse_proxy_auth(struct SessionHandle *data, + struct connectdata *conn) { char proxyuser[MAX_CURL_USER_LENGTH]=""; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; -- cgit v1.2.1 From 5b358603bd8897dcd38795c1ae971a8f917e97df Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 22 Oct 2007 15:05:35 +0000 Subject: Michal Marek forwarded the bug report https://bugzilla.novell.com/show_bug.cgi?id=332917 about a HTTP redirect to FTP that caused memory havoc. His work together with my efforts created two fixes: #1 - FTP::file was moved to struct ftp_conn, because is has to be dealt with at connection cleanup, at which time the struct HandleData could be used by another connection. Also, the unused char *urlpath member is removed from struct FTP. #2 - provide a Curl_reset_reqproto() function that frees data->reqdata.proto.* on connection setup if needed (that is if the SessionHandle was used by a different connection). --- lib/url.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 212e184f7..1fc11f1c7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2058,6 +2058,9 @@ static void conn_free(struct connectdata *conn) if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) sclose(conn->sock[FIRSTSOCKET]); + if (conn->data->reqdata.current_conn == conn) { + conn->data->reqdata.current_conn = NULL; + } Curl_safefree(conn->user); Curl_safefree(conn->passwd); Curl_safefree(conn->proxyuser); @@ -4514,3 +4517,16 @@ CURLcode Curl_do_more(struct connectdata *conn) return result; } + +/* Called on connect, and if there's already a protocol-specific struct + allocated for a different connection, this frees it that it can be setup + properly later on. */ +void Curl_reset_reqproto(struct connectdata *conn) +{ + struct SessionHandle *data = conn->data; + if (data->reqdata.proto.generic && data->reqdata.current_conn != conn) { + free(data->reqdata.proto.generic); + data->reqdata.proto.generic = NULL; + } + data->reqdata.current_conn = conn; +} -- cgit v1.2.1 From 949ff9715a55886ab13fd6cb59d4b4043d457793 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 23 Oct 2007 21:00:51 +0000 Subject: Bug report #1812190 (http://curl.haxx.se/bug/view.cgi?id=1812190) points out that libcurl tried to re-use connections a bit too much when using non-SSL protocols tunneled over a HTTP proxy. --- lib/url.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1fc11f1c7..9d6be5315 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2399,14 +2399,18 @@ ConnectionExists(struct SessionHandle *data, /* don't do mixed SSL and non-SSL connections */ continue; - if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) { - /* The requested connection does not use a HTTP proxy or it - uses SSL. */ + if(needle->bits.proxy != check->bits.proxy) + /* don't do mixed proxy and non-proxy connections */ + continue; - if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy) - /* we don't do SSL but the cached connection has a proxy, - then don't match this */ - continue; + if(!needle->bits.httpproxy || needle->protocol&PROT_SSL || + (needle->bits.httpproxy && check->bits.httpproxy && + needle->bits.tunnel_proxy && check->bits.tunnel_proxy && + strequal(needle->proxy.name, check->proxy.name) && + (needle->port == check->port))) { + /* The requested connection does not use a HTTP proxy or it uses SSL or + it is a non-SSL protocol tunneled over the same http proxy name and + port number */ if(strequal(needle->protostr, check->protostr) && strequal(needle->host.name, check->host.name) && -- cgit v1.2.1 From ca67dcbc055bb1a017e9d215859362348dbbcbaa Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 25 Oct 2007 09:41:35 +0000 Subject: Don't assume there's a sessionhandle around when a connection is disconnected, so do the data->reqdata.current_conn assignment when we know there is an easy handle existing! Fixes the valgrind report on test 509. --- lib/url.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9d6be5315..c87eeaa81 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2058,9 +2058,6 @@ static void conn_free(struct connectdata *conn) if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) sclose(conn->sock[FIRSTSOCKET]); - if (conn->data->reqdata.current_conn == conn) { - conn->data->reqdata.current_conn = NULL; - } Curl_safefree(conn->user); Curl_safefree(conn->passwd); Curl_safefree(conn->proxyuser); @@ -2170,6 +2167,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) } conn_free(conn); + data->reqdata.current_conn = NULL; return CURLE_OK; } -- cgit v1.2.1 From 07dbfa25a096faf730c1e77f19e6466b191b6bd9 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 26 Oct 2007 01:12:33 +0000 Subject: typecast to prevent compiler warning --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c87eeaa81..be8bad35f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1053,7 +1053,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, to mark that postfields is used rather than read function or form data. */ - p = malloc(data->set.postfieldsize? data->set.postfieldsize: 1); + p = malloc((size_t)(data->set.postfieldsize?data->set.postfieldsize:1)); if (!p) result = CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 59b05ac383f45ac3fe2e9fba899b440def9da2bd Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 30 Oct 2007 23:00:40 +0000 Subject: Fixed an OOM problem with file: URLs Moved Curl_file_connect into the protocol handler struct. --- lib/url.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index be8bad35f..d122a90fb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3638,10 +3638,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, * file: is a special case in that it doesn't need a network connection ***********************************************************************/ #ifndef CURL_DISABLE_FILE - if (strequal(conn->protostr, "FILE")) { + if(conn->protocol & PROT_FILE) { + bool done; /* this is supposed to be the connect function so we better at least check that the file is present here! */ - result = Curl_file_connect(conn); + DEBUGASSERT(conn->handler->connect_it); + result = conn->handler->connect_it(conn, &done); /* Setup a "faked" transfer that'll do nothing */ if(CURLE_OK == result) { @@ -3652,8 +3654,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, result = setup_range(data); if(result) { - if(conn->handler->done) - result = conn->handler->done(conn, result, FALSE); + DEBUGASSERT(conn->handler->done); + conn->handler->done(conn, result, FALSE); return result; } -- cgit v1.2.1 From ad6e28073c985a42e8b15d2234baa7ef67ffcb35 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Nov 2007 09:45:09 +0000 Subject: removed space after if and while before the parenthesis for better source code consistency --- lib/url.c | 192 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 96 insertions(+), 96 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d122a90fb..675ef0e06 100644 --- a/lib/url.c +++ b/lib/url.c @@ -300,15 +300,15 @@ static CURLcode Curl_setstropt(char **charp, char * s) /* Release the previous storage at `charp' and replace by a dynamic storage copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ - if (*charp) { + if(*charp) { free(*charp); *charp = (char *) NULL; } - if (s) { + if(s) { s = strdup(s); - if (!s) + if(!s) return CURLE_OUT_OF_MEMORY; *charp = s; @@ -332,7 +332,7 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) /* duplicate all strings */ for(i=(enum dupstring)0; i< STRING_LAST; i++) { r = Curl_setstropt(&dst->set.str[i], src->set.str[i]); - if (r != CURLE_OK) + if(r != CURLE_OK) break; } @@ -454,8 +454,8 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } - if ( ! (data->share && data->share->hostcache) ) { - if ( !Curl_global_host_cache_use(data)) { + if( ! (data->share && data->share->hostcache) ) { + if( !Curl_global_host_cache_use(data)) { Curl_hash_destroy(data->dns.hostcache); } } @@ -493,19 +493,19 @@ CURLcode Curl_close(struct SessionHandle *data) #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) /* close iconv conversion descriptors */ - if (data->inbound_cd != (iconv_t)-1) { + if(data->inbound_cd != (iconv_t)-1) { iconv_close(data->inbound_cd); } - if (data->outbound_cd != (iconv_t)-1) { + if(data->outbound_cd != (iconv_t)-1) { iconv_close(data->outbound_cd); } - if (data->utf8_cd != (iconv_t)-1) { + if(data->utf8_cd != (iconv_t)-1) { iconv_close(data->utf8_cd); } #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ /* No longer a dirty share, if it exists */ - if (data->share) { + if(data->share) { Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); data->share->dirty--; Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); @@ -526,7 +526,7 @@ struct conncache *Curl_mk_connc(int type, struct conncache *c; long default_amount; - if (type == CONNCACHE_PRIVATE) { + if(type == CONNCACHE_PRIVATE) { default_amount = (amount < 0) ? 5 : amount; } else { @@ -537,7 +537,7 @@ struct conncache *Curl_mk_connc(int type, if(!c) return NULL; - if ((size_t)(default_amount) > ((size_t)-1) / sizeof(struct connectdata *)) + if((size_t)(default_amount) > ((size_t)-1) / sizeof(struct connectdata *)) default_amount = ((size_t)-1) / sizeof(struct connectdata *); c->connects = calloc(sizeof(struct connectdata *), (size_t)default_amount); @@ -650,10 +650,10 @@ CURLcode Curl_open(struct SessionHandle **curl) data->magic = CURLEASY_MAGIC_NUMBER; #ifdef USE_ARES - if ((status = ares_init(&data->state.areschannel)) != ARES_SUCCESS) { + if((status = ares_init(&data->state.areschannel)) != ARES_SUCCESS) { DEBUGF(fprintf(stderr, "Error: ares_init failed\n")); free(data); - if (status == ARES_ENOMEM) + if(status == ARES_ENOMEM) return CURLE_OUT_OF_MEMORY; else return CURLE_FAILED_INIT; @@ -775,7 +775,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_DNS_USE_GLOBAL_CACHE: { long use_cache = va_arg(param, long); - if (use_cache) + if(use_cache) Curl_global_host_cache_init(); data->set.global_dns_cache = (bool)(0 != use_cache); @@ -1032,14 +1032,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ argptr = va_arg(param, char *); - if (!argptr || data->set.postfieldsize == -1) + if(!argptr || data->set.postfieldsize == -1) result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); else { /* * Check that requested length does not overflow the size_t type. */ - if ((data->set.postfieldsize < 0) || + if((data->set.postfieldsize < 0) || ((sizeof(curl_off_t) != sizeof(size_t)) && (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) result = CURLE_OUT_OF_MEMORY; @@ -1055,10 +1055,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ p = malloc((size_t)(data->set.postfieldsize?data->set.postfieldsize:1)); - if (!p) + if(!p) result = CURLE_OUT_OF_MEMORY; else { - if (data->set.postfieldsize) + if(data->set.postfieldsize) memcpy(p, argptr, data->set.postfieldsize); data->set.str[STRING_COPYPOSTFIELDS] = p; @@ -1087,7 +1087,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ bigsize = va_arg(param, long); - if (data->set.postfieldsize < bigsize && + if(data->set.postfieldsize < bigsize && data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); @@ -1104,7 +1104,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ bigsize = va_arg(param, curl_off_t); - if (data->set.postfieldsize < bigsize && + if(data->set.postfieldsize < bigsize && data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); @@ -1475,7 +1475,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = Curl_setstropt(&data->set.str[STRING_SET_URL], va_arg(param, char *)); data->change.url = data->set.str[STRING_SET_URL]; - if (data->change.url) + if(data->change.url) data->change.url_changed = TRUE; break; case CURLOPT_PORT: @@ -1694,7 +1694,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * String that holds the SSL crypto engine. */ argptr = va_arg(param, char *); - if (argptr && argptr[0]) + if(argptr && argptr[0]) result = Curl_ssl_set_engine(data, argptr); break; @@ -1849,7 +1849,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(data->share->cookies) { /* use shared cookie list, first free own one if any */ - if (data->cookies) + if(data->cookies) Curl_cookie_cleanup(data->cookies); data->cookies = data->share->cookies; } @@ -2049,7 +2049,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, static void conn_free(struct connectdata *conn) { - if (!conn) + if(!conn) return; /* close possibly still open sockets */ @@ -2161,7 +2161,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_ssl_close(conn, FIRSTSOCKET); /* Indicate to all handles on the pipe that we're dead */ - if (IsPipeliningEnabled(data)) { + if(IsPipeliningEnabled(data)) { signalPipeClose(conn->send_pipe); signalPipeClose(conn->recv_pipe); } @@ -2192,7 +2192,7 @@ static bool SocketIsDead(curl_socket_t sock) static bool IsPipeliningPossible(const struct SessionHandle *handle) { - if (handle->multi && Curl_multi_canPipeline(handle->multi) && + if(handle->multi && Curl_multi_canPipeline(handle->multi) && (handle->set.httpreq == HTTPREQ_GET || handle->set.httpreq == HTTPREQ_HEAD) && handle->set.httpversion != CURL_HTTP_VERSION_1_0) @@ -2203,7 +2203,7 @@ static bool IsPipeliningPossible(const struct SessionHandle *handle) static bool IsPipeliningEnabled(const struct SessionHandle *handle) { - if (handle->multi && Curl_multi_canPipeline(handle->multi)) + if(handle->multi && Curl_multi_canPipeline(handle->multi)) return TRUE; return FALSE; @@ -2219,7 +2219,7 @@ CURLcode Curl_addHandleToPipeline(struct SessionHandle *data, infof(data, "PIPE when no PIPE supposed!\n"); } #endif - if (!Curl_llist_insert_next(pipeline, pipeline->tail, data)) + if(!Curl_llist_insert_next(pipeline, pipeline->tail, data)) return CURLE_OUT_OF_MEMORY; return CURLE_OK; } @@ -2231,8 +2231,8 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle, struct curl_llist_element *curr; curr = pipeline->head; - while (curr) { - if (curr->ptr == handle) { + while(curr) { + if(curr->ptr == handle) { Curl_llist_remove(pipeline, curr, NULL); return 1; /* we removed a handle */ } @@ -2248,7 +2248,7 @@ static void Curl_printPipeline(struct curl_llist *pipeline) struct curl_llist_element *curr; curr = pipeline->head; - while (curr) { + while(curr) { struct SessionHandle *data = (struct SessionHandle *) curr->ptr; infof(data, "Handle in pipeline: %s\n", data->reqdata.path); curr = curr->next; @@ -2260,7 +2260,7 @@ bool Curl_isHandleAtHead(struct SessionHandle *handle, struct curl_llist *pipeline) { struct curl_llist_element *curr = pipeline->head; - if (curr) { + if(curr) { return (bool)(curr->ptr == handle); } @@ -2270,7 +2270,7 @@ bool Curl_isHandleAtHead(struct SessionHandle *handle, static struct SessionHandle* gethandleathead(struct curl_llist *pipeline) { struct curl_llist_element *curr = pipeline->head; - if (curr) { + if(curr) { return (struct SessionHandle *) curr->ptr; } @@ -2281,11 +2281,11 @@ static void signalPipeClose(struct curl_llist *pipeline) { struct curl_llist_element *curr; - if (!pipeline) + if(!pipeline) return; curr = pipeline->head; - while (curr) { + while(curr) { struct curl_llist_element *next = curr->next; struct SessionHandle *data = (struct SessionHandle *) curr->ptr; @@ -2336,7 +2336,7 @@ ConnectionExists(struct SessionHandle *data, pipeLen = check->send_pipe->size + check->recv_pipe->size; - if (check->connectindex == -1) { + if(check->connectindex == -1) { check->connectindex = i; /* Set this appropriately since it might have been set to -1 when the easy was removed from the multi */ @@ -2351,7 +2351,7 @@ ConnectionExists(struct SessionHandle *data, #ifdef CURLRES_ASYNCH /* ip_addr_str is NULL only if the resolving of the name hasn't completed yet and until then we don't re-use this connection */ - if (!check->ip_addr_str) { + if(!check->ip_addr_str) { infof(data, "Connection #%ld hasn't finished name resolve, can't reuse\n", check->connectindex); @@ -2359,13 +2359,13 @@ ConnectionExists(struct SessionHandle *data, } #endif - if ((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { + if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { /* Don't pick a connection that hasn't connected yet or that is going to get closed. */ infof(data, "Connection #%ld isn't open enough, can't reuse\n", check->connectindex); #ifdef CURLDEBUG - if (check->recv_pipe->size > 0) { + if(check->recv_pipe->size > 0) { infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", check->connectindex); } @@ -2373,21 +2373,21 @@ ConnectionExists(struct SessionHandle *data, continue; } - if (pipeLen >= MAX_PIPELINE_LENGTH) { + if(pipeLen >= MAX_PIPELINE_LENGTH) { infof(data, "Connection #%ld has its pipeline full, can't reuse\n", check->connectindex); continue; } - if (canPipeline) { + if(canPipeline) { /* Make sure the pipe has only GET requests */ struct SessionHandle* sh = gethandleathead(check->send_pipe); struct SessionHandle* rh = gethandleathead(check->recv_pipe); - if (sh) { + if(sh) { if(!IsPipeliningPossible(sh)) continue; } - else if (rh) { + else if(rh) { if(!IsPipeliningPossible(rh)) continue; } @@ -2451,7 +2451,7 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - if (!IsPipeliningEnabled(data)) { + if(!IsPipeliningEnabled(data)) { /* The check for a dead socket makes sense only in the non-pipelining case */ bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); @@ -2468,7 +2468,7 @@ ConnectionExists(struct SessionHandle *data, check->inuse = TRUE; /* mark this as being in use so that no other handle in a multi stack may nick it */ - if (canPipeline) { + if(canPipeline) { /* Mark the connection as being in a pipeline */ check->is_in_pipeline = TRUE; } @@ -2534,7 +2534,7 @@ static void ConnectionDone(struct connectdata *conn) { conn->inuse = FALSE; - if (!conn->send_pipe && !conn->recv_pipe) + if(!conn->send_pipe && !conn->recv_pipe) conn->is_in_pipeline = FALSE; } @@ -2763,7 +2763,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, /* it has started, possibly even completed but that knowledge isn't stored in this bit! */ - if (!result) + if(!result) conn->bits.protoconnstart = TRUE; } @@ -2778,8 +2778,8 @@ static bool is_ASCII_name(const char *hostname) { const unsigned char *ch = (const unsigned char*)hostname; - while (*ch) { - if (*ch++ & 0x80) + while(*ch) { + if(*ch++ & 0x80) return FALSE; } return TRUE; @@ -2802,24 +2802,24 @@ static bool tld_check_name(struct SessionHandle *data, /* Convert (and downcase) ACE-name back into locale's character set */ rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); - if (rc != IDNA_SUCCESS) + if(rc != IDNA_SUCCESS) return (FALSE); rc = tld_check_lz(uc_name, &err_pos, NULL); #ifndef CURL_DISABLE_VERBOSE_STRINGS #ifdef HAVE_TLD_STRERROR - if (rc != TLD_SUCCESS) + if(rc != TLD_SUCCESS) tld_errmsg = (char *)tld_strerror((Tld_rc)rc); #endif - if (rc == TLD_INVALID) + if(rc == TLD_INVALID) infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", tld_errmsg, err_pos, uc_name[err_pos], uc_name[err_pos] & 255); - else if (rc != TLD_SUCCESS) + else if(rc != TLD_SUCCESS) infof(data, "WARNING: TLD check for %s failed; %s\n", uc_name, tld_errmsg); #endif /* CURL_DISABLE_VERBOSE_STRINGS */ - if (uc_name) + if(uc_name) idn_free(uc_name); return (bool)(rc == TLD_SUCCESS); } @@ -2842,13 +2842,13 @@ static void fix_hostname(struct SessionHandle *data, /************************************************************* * Check name for non-ASCII and convert hostname to ACE form. *************************************************************/ - if (!is_ASCII_name(host->name) && + if(!is_ASCII_name(host->name) && stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { char *ace_hostname = NULL; int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); infof (data, "Input domain encoded as `%s'\n", stringprep_locale_charset ()); - if (rc != IDNA_SUCCESS) + if(rc != IDNA_SUCCESS) infof(data, "Failed to convert %s to ACE; %s\n", host->name, Curl_idn_strerror(conn,rc)); else { @@ -2937,7 +2937,7 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, /* clear path */ path[0]=0; - if (2 > sscanf(data->change.url, + if(2 > sscanf(data->change.url, "%15[^\n:]://%[^\n/]%[^\n]", conn->protostr, conn->host.name, path)) { @@ -2965,9 +2965,9 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, if(checkprefix("FTP.", conn->host.name)) strcpy(conn->protostr, "ftp"); - else if (checkprefix("DICT.", conn->host.name)) + else if(checkprefix("DICT.", conn->host.name)) strcpy(conn->protostr, "DICT"); - else if (checkprefix("LDAP.", conn->host.name)) + else if(checkprefix("LDAP.", conn->host.name)) strcpy(conn->protostr, "LDAP"); else { strcpy(conn->protostr, "http"); @@ -3053,8 +3053,8 @@ static CURLcode setup_range(struct SessionHandle *data) struct HandleData *req = &data->reqdata; req->resume_from = data->set.set_resume_from; - if (req->resume_from || data->set.str[STRING_SET_RANGE]) { - if (req->rangestringalloc) + if(req->resume_from || data->set.str[STRING_SET_RANGE]) { + if(req->rangestringalloc) free(req->range); if(req->resume_from) @@ -3092,14 +3092,14 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, /* Scan protocol handler table. */ for (pp = protocols; (p = *pp) != NULL; pp++) - if (strequal(p->scheme, conn->protostr)) { + if(strequal(p->scheme, conn->protostr)) { /* Protocol found in table. Perform setup complement if some. */ conn->handler = p; - if (p->setup_connection) { + if(p->setup_connection) { result = (*p->setup_connection)(conn); - if (result != CURLE_OK) + if(result != CURLE_OK) return result; p = conn->handler; /* May have changed. */ @@ -3229,7 +3229,7 @@ static char *detect_proxy(struct connectdata *conn) conn->bits.httpproxy = TRUE; } } - } /* if (!nope) - it wasn't specified non-proxy */ + } /* if(!nope) - it wasn't specified non-proxy */ } /* NO_PROXY wasn't specified or '*' */ if(no_proxy) free(no_proxy); @@ -3338,7 +3338,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, /* Get port number off proxy.server.com:1080 */ prox_portno = strchr(portptr, ':'); - if (prox_portno) { + if(prox_portno) { *prox_portno = 0x0; /* cut off number from host name */ prox_portno ++; /* now set the local port number */ @@ -3507,18 +3507,18 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; - if (data->multi && Curl_multi_canPipeline(data->multi) && + if(data->multi && Curl_multi_canPipeline(data->multi) && !conn->master_buffer) { /* Allocate master_buffer to be used for pipelining */ conn->master_buffer = calloc(BUFSIZE, sizeof (char)); - if (!conn->master_buffer) + if(!conn->master_buffer) return CURLE_OUT_OF_MEMORY; } /* Initialize the pipeline lists */ conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if (!conn->send_pipe || !conn->recv_pipe) + if(!conn->send_pipe || !conn->recv_pipe) return CURLE_OUT_OF_MEMORY; /* This initing continues below, see the comment "Continue connectdata @@ -3556,7 +3556,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->host.name[0] = 0; result = ParseURLAndFillConnection(data, conn); - if (result != CURLE_OK) { + if(result != CURLE_OK) { return result; } @@ -3565,14 +3565,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, *************************************************************/ if(conn->bits.proxy_user_passwd) { result = parse_proxy_auth(data, conn); - if (result != CURLE_OK) + if(result != CURLE_OK) return result; } /************************************************************* * Detect what (if any) proxy to use *************************************************************/ - if (data->set.str[STRING_PROXY]) { + if(data->set.str[STRING_PROXY]) { proxy = strdup(data->set.str[STRING_PROXY]); /* if global proxy is set, this is it */ if(NULL == proxy) { @@ -3581,9 +3581,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, } } - if (!proxy) + if(!proxy) proxy = detect_proxy(conn); - if (proxy && !*proxy) { + if(proxy && !*proxy) { free(proxy); /* Don't bother with an empty proxy string */ proxy = NULL; } @@ -3614,7 +3614,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Setup internals depending on protocol *************************************************************/ result = setup_connection_internals(data, conn); - if (result != CURLE_OK) { + if(result != CURLE_OK) { Curl_safefree(proxy); return result; } @@ -3625,11 +3625,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, * host name, so that we can re-use an existing connection * that may exist registered to the same proxy host. ***********************************************************************/ - if (proxy) { + if(proxy) { result = parse_proxy(data, conn, proxy); /* parse_proxy has freed the proxy string, so don't try to use it again */ proxy = NULL; - if (result != CURLE_OK) + if(result != CURLE_OK) return result; } @@ -3704,7 +3704,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, user[0] =0; /* to make everything well-defined */ passwd[0]=0; - if (conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) { + if(conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) { /* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the * possible user+password pair in a string like: * ftp://user:password@ftp.my.site:8021/README */ @@ -3721,7 +3721,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * set user/passwd, but doing that first adds more cases here :-( */ - if (data->set.use_netrc != CURL_NETRC_REQUIRED) { + if(data->set.use_netrc != CURL_NETRC_REQUIRED) { /* We could use the one in the URL */ conn->bits.user_passwd = 1; /* enable user+password */ @@ -3747,7 +3747,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, the unconverted name, it'll be wrong but what the heck */ free(newname); } - if (passwd[0]) { + if(passwd[0]) { /* we have a password found in the URL, decode it! */ char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); if(!newpasswd) @@ -3810,7 +3810,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, data->change.url_alloc = TRUE; } } - else if (tmp) { + else if(tmp) { /* no CURLOPT_PORT given, extract the one from the URL */ char *rest; @@ -3818,11 +3818,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ - if (rest != (tmp+1) && *rest == '\0') { + if(rest != (tmp+1) && *rest == '\0') { /* The colon really did have only digits after it, * so it is either a port number or a mistake */ - if (port > 0xffff) { /* Single unix standard says port numbers are + if(port > 0xffff) { /* Single unix standard says port numbers are * 16 bits long */ failf(data, "Port number too large: %lu", port); return CURLE_URL_MALFORMAT; @@ -3842,7 +3842,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * user_password is set in "inherit initial knowledge' above, * so it doesn't have to be set in this block */ - if (data->set.str[STRING_USERPWD] != NULL) { + if(data->set.str[STRING_USERPWD] != NULL) { /* the name is given, get user+password */ sscanf(data->set.str[STRING_USERPWD], "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" @@ -3851,7 +3851,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } conn->bits.netrc = FALSE; - if (data->set.use_netrc != CURL_NETRC_IGNORED) { + if(data->set.use_netrc != CURL_NETRC_IGNORED) { if(Curl_parsenetrc(conn->host.name, user, passwd, data->set.str[STRING_NETRC_FILE])) { @@ -3870,7 +3870,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } /* If our protocol needs a password and we have none, use the defaults */ - if ( (conn->protocol & PROT_FTP) && + if( (conn->protocol & PROT_FTP) && !conn->bits.user_passwd) { conn->user = strdup(CURL_DEFAULT_USER); @@ -3941,7 +3941,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* get the user+password information from the old_conn struct since it may * be new for this request even when we re-use an existing connection */ conn->bits.user_passwd = old_conn->bits.user_passwd; - if (conn->bits.user_passwd) { + if(conn->bits.user_passwd) { /* use the new user namd and password though */ Curl_safefree(conn->user); Curl_safefree(conn->passwd); @@ -3952,7 +3952,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; - if (conn->bits.proxy_user_passwd) { + if(conn->bits.proxy_user_passwd) { /* use the new proxy user name and proxy password though */ Curl_safefree(conn->proxyuser); Curl_safefree(conn->proxypasswd); @@ -3963,7 +3963,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, } /* host can change, when doing keepalive with a proxy ! */ - if (conn->bits.proxy) { + if(conn->bits.proxy) { free(conn->host.rawalloc); conn->host=old_conn->host; } @@ -4013,7 +4013,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->fread_func = data->set.fread_func; conn->fread_in = data->set.in; - if ((conn->protocol&PROT_HTTP) && + if((conn->protocol&PROT_HTTP) && data->set.upload && (data->set.infilesize == -1) && (data->set.httpversion != CURL_HTTP_VERSION_1_0)) { @@ -4098,7 +4098,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, hostaddr = NULL; /* we'll need to clear conn->dns_entry later in Curl_disconnect() */ - if (conn->bits.proxy) + if(conn->bits.proxy) fix_hostname(data, conn, &conn->host); } else { @@ -4261,7 +4261,7 @@ static CURLcode SetupConnection(struct connectdata *conn, authentication information */ if(conn->bits.proxy_connect_closed) { /* reset the error buffer */ - if (data->set.errorbuffer) + if(data->set.errorbuffer) data->set.errorbuffer[0] = '\0'; data->state.errorbuf = FALSE; continue; @@ -4291,7 +4291,7 @@ static CURLcode SetupConnection(struct connectdata *conn, * characters (you get mangled text files, and corrupted binary files when * you download to stdout and redirect it to a file). */ - if ((data->set.out)->_handle == NULL) { + if((data->set.out)->_handle == NULL) { _fsetmode(stdout, "b"); } #endif @@ -4332,7 +4332,7 @@ CURLcode Curl_connect(struct SessionHandle *data, } } else { - if ((*in_connect)->is_in_pipeline) + if((*in_connect)->is_in_pipeline) data->state.is_in_pipeline = TRUE; } @@ -4528,7 +4528,7 @@ CURLcode Curl_do_more(struct connectdata *conn) void Curl_reset_reqproto(struct connectdata *conn) { struct SessionHandle *data = conn->data; - if (data->reqdata.proto.generic && data->reqdata.current_conn != conn) { + if(data->reqdata.proto.generic && data->reqdata.current_conn != conn) { free(data->reqdata.proto.generic); data->reqdata.proto.generic = NULL; } -- cgit v1.2.1 From e87c996fe04ea16468af0fa13d89034b15fd36de Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 8 Nov 2007 19:28:25 +0000 Subject: Fix compiler warning: integral size mismatch in argument --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 675ef0e06..93d3bad34 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1059,7 +1059,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = CURLE_OUT_OF_MEMORY; else { if(data->set.postfieldsize) - memcpy(p, argptr, data->set.postfieldsize); + memcpy(p, argptr, (size_t)data->set.postfieldsize); data->set.str[STRING_COPYPOSTFIELDS] = p; } -- cgit v1.2.1 From c5b16d44680cdb81aab2c3af0f5b3ec220aafc39 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Nov 2007 21:38:43 +0000 Subject: Bug report #1830637 (http://curl.haxx.se/bug/view.cgi?id=1830637), which was forwarded from the Gentoo bug tracker by Daniel Black and was originally submitted by Robin Johnson, pointed out that libcurl would do bad memory references when it failed and bailed out before the handler thing was setup. My fix is not done like the provided patch does it, but instead I make sure that there's never any chance for a NULL pointer in that struct member. --- lib/url.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 93d3bad34..3897925a9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2134,7 +2134,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_ntlm_cleanup(conn); } - if(conn->handler && conn->handler->disconnect) + if(conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ conn->handler->disconnect(conn); @@ -2668,7 +2668,7 @@ int Curl_doing_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) { - if(conn && conn->handler && conn->handler->doing_getsock) + if(conn && conn->handler->doing_getsock) return conn->handler->doing_getsock(conn, socks, numsocks); return GETSOCK_BLANK; } @@ -2684,7 +2684,7 @@ CURLcode Curl_protocol_connecting(struct connectdata *conn, { CURLcode result=CURLE_OK; - if(conn && conn->handler && conn->handler->connecting) { + if(conn && conn->handler->connecting) { *done = FALSE; result = conn->handler->connecting(conn, done); } @@ -2703,7 +2703,7 @@ CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) { CURLcode result=CURLE_OK; - if(conn && conn->handler && conn->handler->doing) { + if(conn && conn->handler->doing) { *done = FALSE; result = conn->handler->doing(conn, done); } @@ -3111,8 +3111,9 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, return CURLE_OK; } - /* Protocol not found in table. */ - conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined. */ + /* Protocol not found in table, but we don't have to assign it to anything + since it is already assign to a dummy-struct in the CreateConnection() + struct when the connectdata struct is allocated. */ failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME, conn->protostr); return CURLE_UNSUPPORTED_PROTOCOL; @@ -3470,6 +3471,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, any failure */ *in_connect = conn; + conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined + already from start to avoid NULL + situations and checks */ + /* and we setup a few fields in case we end up actually using this struct */ conn->data = data; /* Setup the association between this connection -- cgit v1.2.1 From f5971f54ff264218446363bb5003d44ec9b88c98 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 Nov 2007 21:42:20 +0000 Subject: comment language --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3897925a9..4ecfeee3e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3111,9 +3111,9 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, return CURLE_OK; } - /* Protocol not found in table, but we don't have to assign it to anything - since it is already assign to a dummy-struct in the CreateConnection() - struct when the connectdata struct is allocated. */ + /* The protocol was not found in the table, but we don't have to assign it + to anything since it is already assigned to a dummy-struct in the + CreateConnection() function when the connectdata struct is allocated. */ failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME, conn->protostr); return CURLE_UNSUPPORTED_PROTOCOL; -- cgit v1.2.1 From 50feea3eef87f1c07b954ad3020fdb836c7f279f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 15 Nov 2007 21:45:45 +0000 Subject: Rearranged code and changed Curl_readwrite_init() and Curl_pre_readwrite() into do_init() and do_complete() which now are called first and last in the DO function. It simplified the flow in multi.c and the functions got more sensible names! --- lib/url.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4ecfeee3e..5d8d042ed 100644 --- a/lib/url.c +++ b/lib/url.c @@ -121,6 +121,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "select.h" #include "multiif.h" #include "easyif.h" +#include "speedcheck.h" /* And now for the protocols */ #include "ftp.h" @@ -164,6 +165,8 @@ static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipeline); static struct SessionHandle* gethandleathead(struct curl_llist *pipeline); +static CURLcode do_init(struct connectdata *conn); +static void do_complete(struct connectdata *conn); #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) static void flush_cookies(struct SessionHandle *data, int cleanup); @@ -4449,21 +4452,83 @@ CURLcode Curl_done(struct connectdata **connp, return result; } +/* + * do_init() inits the readwrite session. This is inited each time (in the DO + * function before the protocol-specific DO functions are invoked) for a + * transfer, sometimes multiple times on the same SessionHandle. Make sure + * nothing in here depends on stuff that are setup dynamicly for the transfer. + */ + +static CURLcode do_init(struct connectdata *conn) +{ + struct SessionHandle *data = conn->data; + struct Curl_transfer_keeper *k = &data->reqdata.keep; + + conn->bits.done = FALSE; /* Curl_done() is not called yet */ + conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ + + /* NB: the content encoding software depends on this initialization of + Curl_transfer_keeper.*/ + memset(k, 0, sizeof(struct Curl_transfer_keeper)); + + k->start = Curl_tvnow(); /* start time */ + k->now = k->start; /* current time is now */ + k->header = TRUE; /* assume header */ + k->httpversion = -1; /* unknown at this point */ + + k->bytecount = 0; + + k->buf = data->state.buffer; + k->uploadbuf = data->state.uploadbuffer; + k->hbufp = data->state.headerbuff; + k->ignorebody=FALSE; + + Curl_pgrsTime(data, TIMER_PRETRANSFER); + Curl_speedinit(data); + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + + return CURLE_OK; +} + +/* + * do_complete is called when the DO actions are complete. + * + * We init chunking and trailer bits to their default values here immediately + * before receiving any header data for the current request in the pipeline. + */ +static void do_complete(struct connectdata *conn) +{ + struct SessionHandle *data = conn->data; + struct Curl_transfer_keeper *k = &data->reqdata.keep; + conn->bits.chunk=FALSE; + conn->bits.trailerhdrpresent=FALSE; + + k->maxfd = (conn->sockfd>conn->writesockfd? + conn->sockfd:conn->writesockfd)+1; + + k->size = data->reqdata.size; + k->maxdownload = data->reqdata.maxdownload; + k->bytecountp = data->reqdata.bytecountp; + k->writebytecountp = data->reqdata.writebytecountp; + +} + CURLcode Curl_do(struct connectdata **connp, bool *done) { CURLcode result=CURLE_OK; struct connectdata *conn = *connp; struct SessionHandle *data = conn->data; - conn->bits.done = FALSE; /* Curl_done() is not called yet */ - conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ + /* setup and init stuff before DO starts, in preparing for the transfer */ + do_init(conn); if(conn->handler->do_it) { /* generic protocol-specific function pointer set in curl_connect() */ result = conn->handler->do_it(conn, done); /* This was formerly done in transfer.c, but we better do it here */ - if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { /* This was a re-use of a connection and we got a write error in the * DO-phase. Then we DISCONNECT this connection and have another attempt @@ -4513,6 +4578,10 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) } } } + + if(result == CURLE_OK) + /* pre readwrite must be called after the protocol-specific DO function */ + do_complete(conn); } return result; } -- cgit v1.2.1 From ef6dfdc7fdb28845706ff98b36a2d294cfc0a1a1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Nov 2007 22:59:10 +0000 Subject: remove the unconditional enabling of cookies if you set a share to use! --- lib/url.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5d8d042ed..7fee3daff 100644 --- a/lib/url.c +++ b/lib/url.c @@ -354,7 +354,7 @@ static void flush_cookies(struct SessionHandle *data, int cleanup) Curl_cookie_loadfiles(data); } - /* we have a "destination" for all the cookies to get dumped to */ + /* if we have a destination file for all the cookies to get dumped to */ if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) infof(data, "WARNING: failed to save cookies in %s\n", data->set.str[STRING_COOKIEJAR]); @@ -1184,7 +1184,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(!cl) return CURLE_OUT_OF_MEMORY; - data->change.cookielist = cl; + data->change.cookielist = cl; /* store the list for later use */ } break; @@ -1854,17 +1854,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* use shared cookie list, first free own one if any */ if(data->cookies) Curl_cookie_cleanup(data->cookies); + /* enable cookies since we now use a share that uses cookies! */ data->cookies = data->share->cookies; } #endif /* CURL_DISABLE_HTTP */ Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - /* check cookie list is set */ - if(!data->cookies) - data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE ); -#endif /* CURL_DISABLE_HTTP */ /* check for host cache not needed, * it will be done by curl_easy_perform */ } -- cgit v1.2.1 From cb04619de25c2aa03505ccedb8ad76dd39137ee5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 21 Nov 2007 22:37:55 +0000 Subject: Make the do_complete() function not get called until the DO actually is compelete, which bascially means when used with the multi interface --- lib/url.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7fee3daff..0415d519b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4575,8 +4575,8 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) } } - if(result == CURLE_OK) - /* pre readwrite must be called after the protocol-specific DO function */ + if((result == CURLE_OK) && *done) + /* do_complete must be called after the protocol-specific DO function */ do_complete(conn); } return result; @@ -4589,6 +4589,10 @@ CURLcode Curl_do_more(struct connectdata *conn) if(conn->handler->do_more) result = conn->handler->do_more(conn); + if(result == CURLE_OK) + /* do_complete must be called after the protocol-specific DO function */ + do_complete(conn); + return result; } -- cgit v1.2.1 From 13648f8ccda6f99674ac407640474634e856804c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Nov 2007 23:16:55 +0000 Subject: struct HandleData is now called struct SingleRequest, and is only for data that is inited at the start of the DO action. I removed the Curl_transfer_keeper struct completely, and I had to move out a few struct members (that had to be set before DO or used after DONE) to the UrlState struct. The SingleRequest struct is accessed with SessionHandle->req. One of the biggest reasons for doing this was the bunch of duplicate struct members in HandleData and Curl_transfer_keeper since it was really messy to keep track of two variables with the same name and basically the same purpose! --- lib/url.c | 86 ++++++++++++++++++++++++++++----------------------------------- 1 file changed, 38 insertions(+), 48 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0415d519b..bd7923320 100644 --- a/lib/url.c +++ b/lib/url.c @@ -463,12 +463,12 @@ CURLcode Curl_close(struct SessionHandle *data) } } - if(data->reqdata.rangestringalloc) - free(data->reqdata.range); + if(data->state.rangestringalloc) + free(data->state.range); /* Free the pathbuffer */ - Curl_safefree(data->reqdata.pathbuffer); - Curl_safefree(data->reqdata.proto.generic); + Curl_safefree(data->state.pathbuffer); + Curl_safefree(data->state.proto.generic); /* Close down all open SSL info and sessions */ Curl_ssl_close_all(data); @@ -2166,7 +2166,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) } conn_free(conn); - data->reqdata.current_conn = NULL; + data->state.current_conn = NULL; return CURLE_OK; } @@ -2872,7 +2872,7 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, char *at; char *tmp; - char *path = data->reqdata.path; + char *path = data->state.path; /************************************************************* * Parse the URL. @@ -3030,7 +3030,7 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, * So if the URL was A://B/C, * conn->protostr is A * conn->host.name is B - * data->reqdata.path is /C + * data->state.path is /C */ return CURLE_OK; @@ -3049,28 +3049,27 @@ static CURLcode setup_range(struct SessionHandle *data) * If we're doing a resumed transfer, we need to setup our stuff * properly. */ - struct HandleData *req = &data->reqdata; - - req->resume_from = data->set.set_resume_from; - if(req->resume_from || data->set.str[STRING_SET_RANGE]) { - if(req->rangestringalloc) - free(req->range); - - if(req->resume_from) - req->range = aprintf("%" FORMAT_OFF_T "-", req->resume_from); + struct UrlState *s = &data->state; + s->resume_from = data->set.set_resume_from; + if(s->resume_from || data->set.str[STRING_SET_RANGE]) { + if(s->rangestringalloc) + free(s->range); + + if(s->resume_from) + s->range = aprintf("%" FORMAT_OFF_T "-", s->resume_from); else - req->range = strdup(data->set.str[STRING_SET_RANGE]); + s->range = strdup(data->set.str[STRING_SET_RANGE]); - req->rangestringalloc = (unsigned char)(req->range?TRUE:FALSE); + s->rangestringalloc = (bool)(s->range?TRUE:FALSE); - if(!req->range) + if(!s->range) return CURLE_OUT_OF_MEMORY; /* tell ourselves to fetch this range */ - req->use_range = TRUE; /* enable range download */ + s->use_range = TRUE; /* enable range download */ } else - req->use_range = FALSE; /* disable range download */ + s->use_range = FALSE; /* disable range download */ return CURLE_OK; } @@ -3539,7 +3538,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, urllen=LEAST_PATH_ALLOC; /* Free the old buffer */ - Curl_safefree(data->reqdata.pathbuffer); + Curl_safefree(data->state.pathbuffer); /* * We malloc() the buffers below urllen+2 to make room for to possibilities: @@ -3547,10 +3546,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) */ - data->reqdata.pathbuffer=(char *)malloc(urllen+2); - if(NULL == data->reqdata.pathbuffer) + data->state.pathbuffer=(char *)malloc(urllen+2); + if(NULL == data->state.pathbuffer) return CURLE_OUT_OF_MEMORY; /* really bad error */ - data->reqdata.path = data->reqdata.pathbuffer; + data->state.path = data->state.pathbuffer; conn->host.rawalloc=(char *)malloc(urllen+2); if(NULL == conn->host.rawalloc) @@ -3803,7 +3802,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, char *url; url = aprintf("%s://%s:%d%s", conn->protostr, conn->host.name, - conn->remote_port, data->reqdata.path); + conn->remote_port, data->state.path); if(!url) return CURLE_OUT_OF_MEMORY; @@ -4237,7 +4236,7 @@ static CURLcode SetupConnection(struct connectdata *conn, return CURLE_OUT_OF_MEMORY; } - data->reqdata.keep.headerbytecount = 0; + data->req.headerbytecount = 0; #ifdef CURL_DO_LINEEND_CONV data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ @@ -4393,9 +4392,9 @@ CURLcode Curl_done(struct connectdata **connp, conn->writechannel_inuse = FALSE; /* Cleanup possible redirect junk */ - if(data->reqdata.newurl) { - free(data->reqdata.newurl); - data->reqdata.newurl = NULL; + if(data->req.newurl) { + free(data->req.newurl); + data->req.newurl = NULL; } if(conn->dns_entry) { @@ -4458,14 +4457,13 @@ CURLcode Curl_done(struct connectdata **connp, static CURLcode do_init(struct connectdata *conn) { struct SessionHandle *data = conn->data; - struct Curl_transfer_keeper *k = &data->reqdata.keep; + struct SingleRequest *k = &data->req; conn->bits.done = FALSE; /* Curl_done() is not called yet */ conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ - /* NB: the content encoding software depends on this initialization of - Curl_transfer_keeper.*/ - memset(k, 0, sizeof(struct Curl_transfer_keeper)); + /* NB: the content encoding software depends on this initialization */ + Curl_easy_initHandleData(data); k->start = Curl_tvnow(); /* start time */ k->now = k->start; /* current time is now */ @@ -4496,19 +4494,11 @@ static CURLcode do_init(struct connectdata *conn) */ static void do_complete(struct connectdata *conn) { - struct SessionHandle *data = conn->data; - struct Curl_transfer_keeper *k = &data->reqdata.keep; conn->bits.chunk=FALSE; conn->bits.trailerhdrpresent=FALSE; - k->maxfd = (conn->sockfd>conn->writesockfd? - conn->sockfd:conn->writesockfd)+1; - - k->size = data->reqdata.size; - k->maxdownload = data->reqdata.maxdownload; - k->bytecountp = data->reqdata.bytecountp; - k->writebytecountp = data->reqdata.writebytecountp; - + conn->data->req.maxfd = (conn->sockfd>conn->writesockfd? + conn->sockfd:conn->writesockfd)+1; } CURLcode Curl_do(struct connectdata **connp, bool *done) @@ -4602,9 +4592,9 @@ CURLcode Curl_do_more(struct connectdata *conn) void Curl_reset_reqproto(struct connectdata *conn) { struct SessionHandle *data = conn->data; - if(data->reqdata.proto.generic && data->reqdata.current_conn != conn) { - free(data->reqdata.proto.generic); - data->reqdata.proto.generic = NULL; + if(data->state.proto.generic && data->state.current_conn != conn) { + free(data->state.proto.generic); + data->state.proto.generic = NULL; } - data->reqdata.current_conn = conn; + data->state.current_conn = conn; } -- cgit v1.2.1 From 162c039e9d0b19bd98244e35e6265b2ff978c085 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Nov 2007 23:18:21 +0000 Subject: reqdata doesn't exist anymore and the path moved to the UrlState struct --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bd7923320..e7c1412bf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2249,7 +2249,7 @@ static void Curl_printPipeline(struct curl_llist *pipeline) curr = pipeline->head; while(curr) { struct SessionHandle *data = (struct SessionHandle *) curr->ptr; - infof(data, "Handle in pipeline: %s\n", data->reqdata.path); + infof(data, "Handle in pipeline: %s\n", data->state.path); curr = curr->next; } } -- cgit v1.2.1 From 1c93e75375882ed309c7d93a1ce59d27a53f23d3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 2 Dec 2007 23:38:23 +0000 Subject: Michal Marek introduced CURLOPT_PROXY_TRANSFER_MODE which is used to control the appending of the "type=" thing on FTP URLs when they are passed to a HTTP proxy. Some proxies just don't like that appending (which is done unconditionally in 7.17.1), and some proxies treat binary/ascii transfers better with the appending done! --- lib/url.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e7c1412bf..a176ac225 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2036,6 +2036,23 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.new_directory_perms = va_arg(param, long); break; + case CURLOPT_PROXY_TRANSFER_MODE: + /* + * set transfer mode (;type=) when doing FTP via an HTTP proxy + */ + switch (va_arg(param, long)) { + case 0: + data->set.proxy_transfer_mode = FALSE; + break; + case 1: + data->set.proxy_transfer_mode = TRUE; + break; + default: + /* reserve other values for future use */ + result = CURLE_FAILED_INIT; + break; + } + break; default: /* unknown tag and its companion, just ignore: */ -- cgit v1.2.1 From 662bee71930fc30ef3fe43077bf696def44c5c7b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 8 Dec 2007 22:50:55 +0000 Subject: All static functions that were previously name Curl_* something no longer use that prefix as we use that prefix only for library-wide internal global symbols. --- lib/url.c | 76 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a176ac225..085ce9d41 100644 --- a/lib/url.c +++ b/lib/url.c @@ -298,7 +298,7 @@ void Curl_freeset(struct SessionHandle * data) Curl_safefree(data->set.str[i]); } -static CURLcode Curl_setstropt(char **charp, char * s) +static CURLcode setstropt(char **charp, char * s) { /* Release the previous storage at `charp' and replace by a dynamic storage copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ @@ -334,7 +334,7 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) /* duplicate all strings */ for(i=(enum dupstring)0; i< STRING_LAST; i++) { - r = Curl_setstropt(&dst->set.str[i], src->set.str[i]); + r = setstropt(&dst->set.str[i], src->set.str[i]); if(r != CURLE_OK) break; } @@ -743,7 +743,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */ #ifdef CURL_CA_BUNDLE /* This is our preferred CA cert bundle since install time */ - res = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], + res = setstropt(&data->set.str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE); #endif } @@ -786,7 +786,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], + result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], va_arg(param, char *)); break; @@ -795,14 +795,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * 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. */ - result = Curl_setstropt(&data->set.str[STRING_SSL_RANDOM_FILE], + result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE], va_arg(param, char *)); break; case CURLOPT_EGDSOCKET: /* * The Entropy Gathering Daemon socket pathname */ - result = Curl_setstropt(&data->set.str[STRING_SSL_EGDSOCKET], + result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET], va_arg(param, char *)); break; case CURLOPT_MAXCONNECTS: @@ -926,7 +926,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Use this file instead of the $HOME/.netrc file */ - result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE], + result = setstropt(&data->set.str[STRING_NETRC_FILE], va_arg(param, char *)); break; case CURLOPT_TRANSFERTEXT: @@ -979,7 +979,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * */ argptr = va_arg(param, char *); - result = Curl_setstropt(&data->set.str[STRING_ENCODING], + result = setstropt(&data->set.str[STRING_ENCODING], (argptr && !*argptr)? (char *) ALL_CONTENT_ENCODINGS: argptr); break; @@ -1036,7 +1036,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, argptr = va_arg(param, char *); if(!argptr || data->set.postfieldsize == -1) - result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); + result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); else { /* * Check that requested length does not overflow the size_t type. @@ -1049,7 +1049,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, else { char * p; - (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); /* Allocate even when size == 0. This satisfies the need of possible later address compare to detect the COPYPOSTFIELDS mode, and @@ -1079,7 +1079,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.postfields = va_arg(param, void *); /* Release old copied data. */ - (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); data->set.httpreq = HTTPREQ_POST; break; @@ -1093,7 +1093,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(data->set.postfieldsize < bigsize && data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ - (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); data->set.postfields = NULL; } @@ -1110,7 +1110,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(data->set.postfieldsize < bigsize && data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ - (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); data->set.postfields = NULL; } @@ -1134,7 +1134,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, free(data->change.referer); data->change.referer_alloc = FALSE; } - result = Curl_setstropt(&data->set.str[STRING_SET_REFERER], + result = setstropt(&data->set.str[STRING_SET_REFERER], va_arg(param, char *)); data->change.referer = data->set.str[STRING_SET_REFERER]; break; @@ -1143,7 +1143,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * String to use in the HTTP User-Agent field */ - result = Curl_setstropt(&data->set.str[STRING_USERAGENT], + result = setstropt(&data->set.str[STRING_USERAGENT], va_arg(param, char *)); break; @@ -1166,7 +1166,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Cookie string to send to the remote server in the request. */ - result = Curl_setstropt(&data->set.str[STRING_COOKIE], + result = setstropt(&data->set.str[STRING_COOKIE], va_arg(param, char *)); break; @@ -1192,7 +1192,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set cookie file name to dump all cookies to when we're done. */ - result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR], + result = setstropt(&data->set.str[STRING_COOKIEJAR], va_arg(param, char *)); /* @@ -1296,7 +1296,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set a custom string to use as request */ - result = Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST], + result = setstropt(&data->set.str[STRING_CUSTOMREQUEST], va_arg(param, char *)); /* we don't set @@ -1363,7 +1363,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Setting it to NULL, means no proxy but allows the environment variables * to decide for us. */ - result = Curl_setstropt(&data->set.str[STRING_PROXY], + result = setstropt(&data->set.str[STRING_PROXY], va_arg(param, char *)); break; @@ -1390,7 +1390,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Use FTP PORT, this also specifies which IP address to use */ - result = Curl_setstropt(&data->set.str[STRING_FTPPORT], + result = setstropt(&data->set.str[STRING_FTPPORT], va_arg(param, char *)); data->set.ftp_use_port = (bool)(NULL != data->set.str[STRING_FTPPORT]); break; @@ -1475,7 +1475,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, free(data->change.url); data->change.url_alloc=FALSE; } - result = Curl_setstropt(&data->set.str[STRING_SET_URL], + result = setstropt(&data->set.str[STRING_SET_URL], va_arg(param, char *)); data->change.url = data->set.str[STRING_SET_URL]; if(data->change.url) @@ -1514,7 +1514,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password to use in the operation */ - result = Curl_setstropt(&data->set.str[STRING_USERPWD], + result = setstropt(&data->set.str[STRING_USERPWD], va_arg(param, char *)); break; case CURLOPT_POSTQUOTE: @@ -1556,14 +1556,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password needed to use the proxy */ - result = Curl_setstropt(&data->set.str[STRING_PROXYUSERPWD], + result = setstropt(&data->set.str[STRING_PROXYUSERPWD], va_arg(param, char *)); break; case CURLOPT_RANGE: /* * What range of the file you want to transfer */ - result = Curl_setstropt(&data->set.str[STRING_SET_RANGE], + result = setstropt(&data->set.str[STRING_SET_RANGE], va_arg(param, char *)); break; case CURLOPT_RESUME_FROM: @@ -1661,35 +1661,35 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * String that holds file name of the SSL certificate to use */ - result = Curl_setstropt(&data->set.str[STRING_CERT], + result = setstropt(&data->set.str[STRING_CERT], va_arg(param, char *)); break; case CURLOPT_SSLCERTTYPE: /* * String that holds file type of the SSL certificate to use */ - result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE], + result = setstropt(&data->set.str[STRING_CERT_TYPE], va_arg(param, char *)); break; case CURLOPT_SSLKEY: /* * String that holds file name of the SSL certificate to use */ - result = Curl_setstropt(&data->set.str[STRING_KEY], + result = setstropt(&data->set.str[STRING_KEY], va_arg(param, char *)); break; case CURLOPT_SSLKEYTYPE: /* * String that holds file type of the SSL certificate to use */ - result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE], + result = setstropt(&data->set.str[STRING_KEY_TYPE], va_arg(param, char *)); break; case CURLOPT_KEYPASSWD: /* * String that holds the SSL or SSH private key password. */ - result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], + result = setstropt(&data->set.str[STRING_KEY_PASSWD], va_arg(param, char *)); break; case CURLOPT_SSLENGINE: @@ -1719,7 +1719,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set what interface or address/hostname to bind the socket to when * performing an operation and thus what from-IP your connection will use. */ - result = Curl_setstropt(&data->set.str[STRING_DEVICE], + result = setstropt(&data->set.str[STRING_DEVICE], va_arg(param, char *)); break; case CURLOPT_LOCALPORT: @@ -1738,7 +1738,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * A string that defines the kerberos security level. */ - result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], + result = setstropt(&data->set.str[STRING_KRB_LEVEL], va_arg(param, char *)); data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]); break; @@ -1770,7 +1770,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set CA info for SSL connection. Specify file name of the CA certificate */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], + result = setstropt(&data->set.str[STRING_SSL_CAFILE], va_arg(param, char *)); break; case CURLOPT_CAPATH: @@ -1779,7 +1779,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * certificates which have been prepared using openssl c_rehash utility. */ /* This does not work on windows. */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], + result = setstropt(&data->set.str[STRING_SSL_CAPATH], va_arg(param, char *)); break; case CURLOPT_TELNETOPTIONS: @@ -1929,7 +1929,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, These former 3rd party transfer options are deprecated */ case CURLOPT_FTP_ACCOUNT: - result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT], + result = setstropt(&data->set.str[STRING_FTP_ACCOUNT], va_arg(param, char *)); break; @@ -1945,7 +1945,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_FTP_ALTERNATIVE_TO_USER: - result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], + result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], va_arg(param, char *)); break; @@ -1990,7 +1990,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Use this file instead of the $HOME/.ssh/id_dsa.pub file */ - result = Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], + result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], va_arg(param, char *)); break; @@ -1998,7 +1998,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Use this file instead of the $HOME/.ssh/id_dsa file */ - result = Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], + result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], va_arg(param, char *)); break; case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: @@ -2006,7 +2006,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Option to allow for the MD5 of the host public key to be checked * for validation purposes. */ - result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], + result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], va_arg(param, char *)); break; case CURLOPT_HTTP_TRANSFER_DECODING: -- cgit v1.2.1 From 04e4d9a0b3ef5653c816a309866e54a3913fa585 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 26 Dec 2007 23:29:35 +0000 Subject: Dmitry Kurochkin mentioned a flaw (http://curl.haxx.se/mail/lib-2007-12/0252.html) in detect_proxy() which failed to set the bits.proxy variable properly when an environment variable told libcurl to use a http proxy. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 085ce9d41..ee8b916e4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3242,7 +3242,7 @@ static char *detect_proxy(struct connectdata *conn) if(conn->proxytype == CURLPROXY_HTTP) { /* force this connection's protocol to become HTTP */ conn->protocol = PROT_HTTP | bits; - conn->bits.httpproxy = TRUE; + conn->bits.proxy = conn->bits.httpproxy = TRUE; } } } /* if(!nope) - it wasn't specified non-proxy */ -- cgit v1.2.1 From a46b40b7fdf567250451b984b977f5e03c716d5e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 2 Jan 2008 21:40:11 +0000 Subject: Richard Atterer brought a patch that added support for SOCKS4a proxies, which is an inofficial PROXY4 variant that sends the hostname to the proxy instead of the resolved address (which is already supported by SOCKS5). --socks4a is the curl command line option for it and CURLOPT_PROXYTYPE can now be set to CURLPROXY_SOCKS4A as well. --- lib/url.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ee8b916e4..a205f9a7b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1868,7 +1868,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_PROXYTYPE: /* - * Set proxy type. HTTP/SOCKS4/SOCKS5 + * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5 */ data->set.proxytype = (curl_proxytype)va_arg(param, long); break; @@ -2643,8 +2643,12 @@ static CURLcode ConnectPlease(struct SessionHandle *data, /* do nothing here. handled later. */ break; case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, - FIRSTSOCKET, conn); + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, false); + break; + case CURLPROXY_SOCKS4A: + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, true); break; default: failf(data, "unknown proxytype option given"); -- cgit v1.2.1 From 083d3190e50db30405c8ac37aa97fc8d7abb436d Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Thu, 3 Jan 2008 15:18:27 +0000 Subject: 'false' and 'true' are not built-ins on most compilers. Use TRUE/FALSE from setup_once.h. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a205f9a7b..550cb2113 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2644,11 +2644,11 @@ static CURLcode ConnectPlease(struct SessionHandle *data, break; case CURLPROXY_SOCKS4: result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, false); + conn->remote_port, FIRSTSOCKET, conn, FALSE); break; case CURLPROXY_SOCKS4A: result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, true); + conn->remote_port, FIRSTSOCKET, conn, TRUE); break; default: failf(data, "unknown proxytype option given"); -- cgit v1.2.1 From 2e42b0a252416803a90ea232dc94a0a21d5a97e5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 4 Jan 2008 23:01:00 +0000 Subject: Based on Maxim Perenesenko's patch, we now do SOCKS5 operations and let the proxy do the host name resolving and only if --socks5ip (or CURLOPT_SOCKS5_RESOLVE_LOCAL) is used we resolve the host name locally and pass on the IP address only to the proxy. --- lib/url.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 550cb2113..774e25ff2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2054,6 +2054,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } break; + case CURLOPT_SOCKS5_RESOLVE_LOCAL: + /* + * Enable or disable using of SOCKS5 proxy server to resolve domain names + * instead of using platform API like gethostbyname_r etc + */ + data->set.socks5_resolve_local = (bool)(0 != va_arg(param, long)); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From b4305764367f24f06ce7dedc557d90772a00eec1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 5 Jan 2008 22:04:18 +0000 Subject: Based on further discussion on curl-library, I reverted yesterday's SOCKS5 code to instead introduce support for a new proxy type called CURLPROXY_SOCKS5_HOSTNAME that is used to send the host name to the proxy instead of IP address and there's thus no longer any need for a new curl_easy_setopt() option. The default SOCKS5 proxy is again back to sending the IP address to the proxy. The new curl command line option for enabling sending host name to a SOCKS5 proxy is now --socks5-hostname. --- lib/url.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 774e25ff2..550cb2113 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2054,14 +2054,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } break; - case CURLOPT_SOCKS5_RESOLVE_LOCAL: - /* - * Enable or disable using of SOCKS5 proxy server to resolve domain names - * instead of using platform API like gethostbyname_r etc - */ - data->set.socks5_resolve_local = (bool)(0 != va_arg(param, long)); - break; - default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From cadd08f36a383aa03d9789e709155b5016d41df4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 6 Jan 2008 12:54:16 +0000 Subject: make sure CURLPROXY_SOCKS5_HOSTNAME is taken care of as well --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 550cb2113..8e2405373 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2636,8 +2636,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data, switch(data->set.proxytype) { case CURLPROXY_SOCKS5: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn); + case CURLPROXY_SOCKS5_HOSTNAME: + result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, + conn->host.name, conn->remote_port, + FIRSTSOCKET, conn); break; case CURLPROXY_HTTP: /* do nothing here. handled later. */ -- cgit v1.2.1 From f111c9edae27e430ae63a3c03c99282dce81c8da Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 6 Jan 2008 21:41:38 +0000 Subject: more SOCKS5_HOSTNAME adjustments from Richard Atterer --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8e2405373..25d40b922 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1868,7 +1868,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_PROXYTYPE: /* - * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5 + * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME */ data->set.proxytype = (curl_proxytype)va_arg(param, long); break; -- cgit v1.2.1 From de23b98522991dbc1f2c184216d9f73bead83895 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 8 Jan 2008 14:52:05 +0000 Subject: Introducing curl_easy_pause() and new magic return codes for both the read and the write callbacks that now can make a connection's reading and/or writing get paused. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 25d40b922..d7b4c512a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4433,6 +4433,13 @@ CURLcode Curl_done(struct connectdata **connp, Curl_pgrsDone(conn); /* done with the operation */ + /* if the transfer was completed in a paused state there can be buffered + data left to write and then kill */ + if(data->state.tempwrite) { + free(data->state.tempwrite); + data->state.tempwrite = NULL; + } + /* for ares-using, make sure all possible outstanding requests are properly cancelled before we proceed */ ares_cancel(data->state.areschannel); -- cgit v1.2.1 From 18faa509403c39b4914114cfe2966241b62b2959 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 10 Jan 2008 10:30:19 +0000 Subject: Georg Lippitsch brought CURLOPT_SEEKFUNCTION and CURLOPT_SEEKDATA to allow libcurl to seek in a given input stream. This is particularly important when doing upload resumes when there's already a huge part of the file present remotely. Before, and still if this callback isn't used, libcurl will read and through away the entire file up to the point to where the resuming begins (which of course can be a slow opereration depending on file size, I/O bandwidth and more). This new function will also be preferred to get used instead of the CURLOPT_IOCTLFUNCTION for seeking back in a stream when doing multi-stage HTTP auth with POST/PUT. --- lib/url.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d7b4c512a..a5e4565ad 100644 --- a/lib/url.c +++ b/lib/url.c @@ -685,6 +685,10 @@ CURLcode Curl_open(struct SessionHandle **curl) /* use fread as default function to read input */ data->set.fread_func = (curl_read_callback)fread; + /* don't use a seek function by default */ + data->set.seek_func = ZERO_NULL; + data->set.seek_client = ZERO_NULL; + /* conversion callbacks for non-ASCII hosts */ data->set.convfromnetwork = ZERO_NULL; data->set.convtonetwork = ZERO_NULL; @@ -1627,6 +1631,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* When set to NULL, reset to our internal default function */ data->set.fread_func = (curl_read_callback)fread; break; + case CURLOPT_SEEKFUNCTION: + /* + * Seek callback. Might be NULL. + */ + data->set.seek_func = va_arg(param, curl_seek_callback); + break; + case CURLOPT_SEEKDATA: + /* + * Seek control callback. Might be NULL. + */ + data->set.seek_client = va_arg(param, void *); + break; case CURLOPT_CONV_FROM_NETWORK_FUNCTION: /* * "Convert from network encoding" callback @@ -4038,6 +4054,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, * the persistent connection stuff */ conn->fread_func = data->set.fread_func; conn->fread_in = data->set.in; + conn->seek_func = data->set.seek_func; + conn->seek_client = data->set.seek_client; if((conn->protocol&PROT_HTTP) && data->set.upload && -- cgit v1.2.1 From 56f17d2c9f3d229d701bcf0dda83f4d29c0e02ba Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 15 Jan 2008 22:15:55 +0000 Subject: I made the torture test on test 530 go through. This was actually due to silly code left from when we switched to let the multi handle "hold" the dns cache when using the multi interface... Of course this only triggered when a certain function call returned error at the correct moment. --- lib/url.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a5e4565ad..94c363fc2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -457,11 +457,8 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } - if( ! (data->share && data->share->hostcache) ) { - if( !Curl_global_host_cache_use(data)) { - Curl_hash_destroy(data->dns.hostcache); - } - } + if(data->dns.hostcachetype == HCACHE_PRIVATE) + Curl_hash_destroy(data->dns.hostcache); if(data->state.rangestringalloc) free(data->state.range); @@ -782,10 +779,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_DNS_USE_GLOBAL_CACHE: { long use_cache = va_arg(param, long); - if(use_cache) + if(use_cache) { Curl_global_host_cache_init(); - - data->set.global_dns_cache = (bool)(0 != use_cache); + data->dns.hostcachetype = HCACHE_GLOBAL; + } + else + /* not global makes it private by default then */ + data->dns.hostcachetype = HCACHE_PRIVATE; } break; case CURLOPT_SSL_CIPHER_LIST: -- cgit v1.2.1 From 991505e077f4ecdbd0b1d0f42be0c9b548dc743d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 15 Jan 2008 22:44:12 +0000 Subject: Woops, partly revert my previous commit and do it slightly differently instead. The signalling of that a global DNS cache is wanted is done by setting the option but the setting of the internal variable that it is in use must not be done until it finally actually gets used! NOTE and WARNING: I noticed that you can't actually switch off the global dns cache with CURLOPT_DNS_USE_GLOBAL_CACHE but you couldn't do that previously either and the option is very clearly and loudly documented as DO NOTE USE so I won't bother to fix this bug now. --- lib/url.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 94c363fc2..83ebcfefa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -778,14 +778,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_DNS_USE_GLOBAL_CACHE: { + /* remember we want this enabled */ long use_cache = va_arg(param, long); - if(use_cache) { - Curl_global_host_cache_init(); - data->dns.hostcachetype = HCACHE_GLOBAL; - } - else - /* not global makes it private by default then */ - data->dns.hostcachetype = HCACHE_PRIVATE; + data->set.global_dns_cache = (bool)(0 != use_cache); } break; case CURLOPT_SSL_CIPHER_LIST: -- cgit v1.2.1 From b3de497d8316647d988e97703f975e0acd40cacd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 16 Jan 2008 12:24:00 +0000 Subject: Dmitry Kurochkin worked a lot on improving the HTTP Pipelining support that previously had a number of flaws, perhaps most notably when an application fired up N transfers at once as then they wouldn't pipeline at all that nicely as anyone would think... Test case 530 was also updated to take the improved functionality into account. --- lib/url.c | 148 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 74 insertions(+), 74 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 83ebcfefa..7099f116a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -159,7 +159,6 @@ static bool ConnectionExists(struct SessionHandle *data, static long ConnectionStore(struct SessionHandle *data, struct connectdata *conn); static bool IsPipeliningPossible(const struct SessionHandle *handle); -static bool IsPipeliningEnabled(const struct SessionHandle *handle); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipeline); @@ -176,8 +175,6 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); #define verboseconnect(x) do { } while (0) #endif -#define MAX_PIPELINE_LENGTH 5 - #ifndef USE_ARES /* not for ares builds */ @@ -425,6 +422,16 @@ CURLcode Curl_close(struct SessionHandle *data) } } } + pipeline = connptr->pend_pipe; + if(pipeline) { + for (curr = pipeline->head; curr; curr=curr->next) { + if(data == (struct SessionHandle *) curr->ptr) { + fprintf(stderr, + "MAJOR problem we %p are still in pend pipe for %p done %d\n", + data, connptr, connptr->bits.done); + } + } + } } } #endif @@ -2105,6 +2112,7 @@ static void conn_free(struct connectdata *conn) Curl_llist_destroy(conn->send_pipe, NULL); Curl_llist_destroy(conn->recv_pipe, NULL); + Curl_llist_destroy(conn->pend_pipe, NULL); /* possible left-overs from the async name resolvers */ #if defined(USE_ARES) @@ -2188,9 +2196,10 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_ssl_close(conn, FIRSTSOCKET); /* Indicate to all handles on the pipe that we're dead */ - if(IsPipeliningEnabled(data)) { + if(Curl_isPipeliningEnabled(data)) { signalPipeClose(conn->send_pipe); signalPipeClose(conn->recv_pipe); + signalPipeClose(conn->pend_pipe); } conn_free(conn); @@ -2228,7 +2237,7 @@ static bool IsPipeliningPossible(const struct SessionHandle *handle) return FALSE; } -static bool IsPipeliningEnabled(const struct SessionHandle *handle) +bool Curl_isPipeliningEnabled(const struct SessionHandle *handle) { if(handle->multi && Curl_multi_canPipeline(handle->multi)) return TRUE; @@ -2251,9 +2260,8 @@ CURLcode Curl_addHandleToPipeline(struct SessionHandle *data, return CURLE_OK; } - int Curl_removeHandleFromPipeline(struct SessionHandle *handle, - struct curl_llist *pipeline) + struct curl_llist *pipeline) { struct curl_llist_element *curr; @@ -2283,17 +2291,6 @@ static void Curl_printPipeline(struct curl_llist *pipeline) } #endif -bool Curl_isHandleAtHead(struct SessionHandle *handle, - struct curl_llist *pipeline) -{ - struct curl_llist_element *curr = pipeline->head; - if(curr) { - return (bool)(curr->ptr == handle); - } - - return FALSE; -} - static struct SessionHandle* gethandleathead(struct curl_llist *pipeline) { struct curl_llist_element *curr = pipeline->head; @@ -2369,43 +2366,6 @@ ConnectionExists(struct SessionHandle *data, from the multi */ } - if(pipeLen > 0 && !canPipeline) { - /* can only happen within multi handles, and means that another easy - handle is using this connection */ - continue; - } - -#ifdef CURLRES_ASYNCH - /* ip_addr_str is NULL only if the resolving of the name hasn't completed - yet and until then we don't re-use this connection */ - if(!check->ip_addr_str) { - infof(data, - "Connection #%ld hasn't finished name resolve, can't reuse\n", - check->connectindex); - continue; - } -#endif - - if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { - /* Don't pick a connection that hasn't connected yet or that is going to - get closed. */ - infof(data, "Connection #%ld isn't open enough, can't reuse\n", - check->connectindex); -#ifdef CURLDEBUG - if(check->recv_pipe->size > 0) { - infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", - check->connectindex); - } -#endif - continue; - } - - if(pipeLen >= MAX_PIPELINE_LENGTH) { - infof(data, "Connection #%ld has its pipeline full, can't reuse\n", - check->connectindex); - continue; - } - if(canPipeline) { /* Make sure the pipe has only GET requests */ struct SessionHandle* sh = gethandleathead(check->send_pipe); @@ -2418,6 +2378,45 @@ ConnectionExists(struct SessionHandle *data, if(!IsPipeliningPossible(rh)) continue; } + +#ifdef CURLDEBUG + if(pipeLen > MAX_PIPELINE_LENGTH) { + infof(data, "BAD! Connection #%ld has too big pipeline!\n", + check->connectindex); + } +#endif + } + else { + if(pipeLen > 0) { + /* can only happen within multi handles, and means that another easy + handle is using this connection */ + continue; + } + +#ifdef CURLRES_ASYNCH + /* ip_addr_str is NULL only if the resolving of the name hasn't completed + yet and until then we don't re-use this connection */ + if(!check->ip_addr_str) { + infof(data, + "Connection #%ld hasn't finished name resolve, can't reuse\n", + check->connectindex); + continue; + } +#endif + + if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { + /* Don't pick a connection that hasn't connected yet or that is going to + get closed. */ + infof(data, "Connection #%ld isn't open enough, can't reuse\n", + check->connectindex); +#ifdef CURLDEBUG + if(check->recv_pipe->size > 0) { + infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", + check->connectindex); + } +#endif + continue; + } } if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) @@ -2478,7 +2477,7 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - if(!IsPipeliningEnabled(data)) { + if(!Curl_isPipeliningEnabled(data)) { /* The check for a dead socket makes sense only in the non-pipelining case */ bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); @@ -2561,7 +2560,7 @@ static void ConnectionDone(struct connectdata *conn) { conn->inuse = FALSE; - if(!conn->send_pipe && !conn->recv_pipe) + if(!conn->send_pipe && !conn->recv_pipe && !conn->pend_pipe) conn->is_in_pipeline = FALSE; } @@ -3555,7 +3554,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Initialize the pipeline lists */ conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if(!conn->send_pipe || !conn->recv_pipe) + conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe) return CURLE_OUT_OF_MEMORY; /* This initing continues below, see the comment "Continue connectdata @@ -4019,6 +4019,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, Curl_safefree(old_conn->proxypasswd); Curl_llist_destroy(old_conn->send_pipe, NULL); Curl_llist_destroy(old_conn->recv_pipe, NULL); + Curl_llist_destroy(old_conn->pend_pipe, NULL); Curl_safefree(old_conn->master_buffer); free(old_conn); /* we don't need this anymore */ @@ -4353,26 +4354,24 @@ CURLcode Curl_connect(struct SessionHandle *data, if(CURLE_OK == code) { /* no error */ - if(dns || !*asyncp) - /* If an address is available it means that we already have the name - resolved, OR it isn't async. if this is a re-used connection 'dns' - will be NULL here. Continue connecting from here */ - code = SetupConnection(*in_connect, dns, protocol_done); - /* else - response will be received and treated async wise */ + if((*in_connect)->is_in_pipeline) + data->state.is_in_pipeline = TRUE; + else { + if(dns || !*asyncp) + /* If an address is available it means that we already have the name + resolved, OR it isn't async. if this is a re-used connection 'dns' + will be NULL here. Continue connecting from here */ + code = SetupConnection(*in_connect, dns, protocol_done); + /* else + response will be received and treated async wise */ + } } - if(CURLE_OK != code) { + if(CURLE_OK != code && *in_connect) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ - if(*in_connect) { - Curl_disconnect(*in_connect); /* close the connection */ - *in_connect = NULL; /* return a NULL */ - } - } - else { - if((*in_connect)->is_in_pipeline) - data->state.is_in_pipeline = TRUE; + Curl_disconnect(*in_connect); /* close the connection */ + *in_connect = NULL; /* return a NULL */ } return code; @@ -4426,6 +4425,7 @@ CURLcode Curl_done(struct connectdata **connp, if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && conn->writechannel_inuse) conn->writechannel_inuse = FALSE; + Curl_removeHandleFromPipeline(data, conn->pend_pipe); /* Cleanup possible redirect junk */ if(data->req.newurl) { -- cgit v1.2.1 From ef0ed9b7206e186c7d3d08b91885efdd0d0db9df Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 21 Jan 2008 23:48:58 +0000 Subject: Dmitry Kurochkin removed the cancelled state for pipelining, as we agreed that it is bad anyway. Starting now, removing a handle that is in used in a pipeline will break the pipeline - it'll be set back up again but still... --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7099f116a..5a47e289a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2477,7 +2477,7 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - if(!Curl_isPipeliningEnabled(data)) { + if(!check->is_in_pipeline) { /* The check for a dead socket makes sense only in the non-pipelining case */ bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); -- cgit v1.2.1 From 1bfbd250272d019949c89e48bfbeb7cd00d20029 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 29 Jan 2008 12:58:25 +0000 Subject: - Dmitry Kurochkin fixed Curl_done() for pipelining, as it could previously crash! --- lib/url.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5a47e289a..4fab64486 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4414,11 +4414,6 @@ CURLcode Curl_done(struct connectdata **connp, Curl_expire(data, 0); /* stop timer */ - if(conn->bits.done) - return CURLE_OK; /* Curl_done() has already been called */ - - conn->bits.done = TRUE; /* called just now! */ - if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && conn->readchannel_inuse) conn->readchannel_inuse = FALSE; @@ -4427,6 +4422,16 @@ CURLcode Curl_done(struct connectdata **connp, conn->writechannel_inuse = FALSE; Curl_removeHandleFromPipeline(data, conn->pend_pipe); + if(conn->bits.done || + (conn->send_pipe->size + conn->recv_pipe->size != 0 && + !data->set.reuse_forbid && + !conn->bits.close)) + /* Stop if Curl_done() has already been called or pipeline + is not empty and we do not have to close connection. */ + return CURLE_OK; + + conn->bits.done = TRUE; /* called just now! */ + /* Cleanup possible redirect junk */ if(data->req.newurl) { free(data->req.newurl); -- cgit v1.2.1 From b620e62f0f4e90f4d1338117c67580a6f5f37377 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 31 Jan 2008 12:04:33 +0000 Subject: - Dmitry Kurochkin moved several struct fields from the connectdata struct to the SingleRequest one to make pipelining better. It is a bit tricky to keep them in the right place, to keep things related to the actual request or to the actual connection in the right place. --- lib/url.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4fab64486..2e5dd6c32 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3538,7 +3538,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); - conn->bits.no_body = data->set.opt_no_body; conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; @@ -4007,9 +4006,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, else free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ - /* get the newly set value, not the old one */ - conn->bits.no_body = old_conn->bits.no_body; - /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ @@ -4053,18 +4049,6 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->seek_func = data->set.seek_func; conn->seek_client = data->set.seek_client; - if((conn->protocol&PROT_HTTP) && - data->set.upload && - (data->set.infilesize == -1) && - (data->set.httpversion != CURL_HTTP_VERSION_1_0)) { - /* HTTP, upload, unknown file size and not HTTP 1.0 */ - conn->bits.upload_chunky = TRUE; - } - else { - /* else, no chunky upload */ - conn->bits.upload_chunky = FALSE; - } - #ifndef USE_ARES /************************************************************* * Set timeout if that is being used, and we're not using an asynchronous @@ -4542,8 +4526,8 @@ static CURLcode do_init(struct connectdata *conn) */ static void do_complete(struct connectdata *conn) { - conn->bits.chunk=FALSE; - conn->bits.trailerhdrpresent=FALSE; + conn->data->req.chunk=FALSE; + conn->data->req.trailerhdrpresent=FALSE; conn->data->req.maxfd = (conn->sockfd>conn->writesockfd? conn->sockfd:conn->writesockfd)+1; -- cgit v1.2.1 From ffae4f6b48cc8d227a41701f8f043bd8549b4ba3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 3 Feb 2008 12:31:35 +0000 Subject: - Dmitry Kurochkin cleaned up the pipelining code and removed the need for and use of the "is_in_pipeline" struct field. --- lib/url.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2e5dd6c32..234c581bf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -387,9 +387,6 @@ CURLcode Curl_close(struct SessionHandle *data) /* only for debugging, scan through all connections and see if there's a pipe reference still identifying this handle */ - if(data->state.is_in_pipeline) - fprintf(stderr, "CLOSED when in pipeline!\n"); - if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) { struct conncache *c = data->state.connc; long i; @@ -2477,9 +2474,9 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - if(!check->is_in_pipeline) { - /* The check for a dead socket makes sense only in the - non-pipelining case */ + if(pipeLen == 0) { + /* The check for a dead socket makes sense only if there + are no handles in pipeline */ bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); if(dead) { check->data = data; @@ -2494,10 +2491,6 @@ ConnectionExists(struct SessionHandle *data, check->inuse = TRUE; /* mark this as being in use so that no other handle in a multi stack may nick it */ - if(canPipeline) { - /* Mark the connection as being in a pipeline */ - check->is_in_pipeline = TRUE; - } *usethis = check; return TRUE; /* yes, we found one to use! */ @@ -2560,8 +2553,6 @@ static void ConnectionDone(struct connectdata *conn) { conn->inuse = FALSE; - if(!conn->send_pipe && !conn->recv_pipe && !conn->pend_pipe) - conn->is_in_pipeline = FALSE; } /* @@ -4338,8 +4329,10 @@ CURLcode Curl_connect(struct SessionHandle *data, if(CURLE_OK == code) { /* no error */ - if((*in_connect)->is_in_pipeline) - data->state.is_in_pipeline = TRUE; + if((*in_connect)->send_pipe->size + + (*in_connect)->recv_pipe->size != 0) + /* pipelining */ + *protocol_done = TRUE; else { if(dns || !*asyncp) /* If an address is available it means that we already have the name -- cgit v1.2.1 From 48918c304741aaaf8924c377d31cc8b41562fc75 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 15 Feb 2008 21:38:54 +0000 Subject: mention that we explicitly ignore the return code --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 234c581bf..cecb8b6f4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3682,7 +3682,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, result = setup_range(data); if(result) { DEBUGASSERT(conn->handler->done); - conn->handler->done(conn, result, FALSE); + /* we ignore the return code for the protocol-specific DONE */ + (void)conn->handler->done(conn, result, FALSE); return result; } -- cgit v1.2.1 From 240bae4eb2c10d3fb3b31ff78b8ec6e1b5899166 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 Feb 2008 13:43:32 +0000 Subject: In Curl_done() if premature is TRUE, it means this connection was said to be DONE before the entire request operation is complete and thus we can't know in what state it is for re-using, so we're forced to close it. In a perfect world we can add code that keep track of if we really must close it here or not, but currently we have no such detail knowledge. Jerome Muffat-Meridol helped us work this out. --- lib/url.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cecb8b6f4..7b06604d8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4445,8 +4445,15 @@ CURLcode Curl_done(struct connectdata **connp, 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->set.reuse_forbid || conn->bits.close) { + restrictions in our or the server's end + + if premature is TRUE, it means this connection was said to be DONE before + the entire request operation is complete and thus we can't know in what + state it is for re-using, so we're forced to close it. In a perfect world + we can add code that keep track of if we really must close it here or not, + but currently we have no such detail knowledge. + */ + if(data->set.reuse_forbid || conn->bits.close || premature) { CURLcode res2 = Curl_disconnect(conn); /* close the connection */ /* If we had an error already, make sure we return that one. But -- cgit v1.2.1 From 55700cb01f4a01b8187f387e1655371e6fe0703a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Feb 2008 08:28:02 +0000 Subject: - We no longer support setting the CURLOPT_URL option from inside a callback such as the CURLOPT_SSL_CTX_FUNCTION one treat that as if it was a Location: following. The patch that introduced this feature was done for 7.11.0, but this code and functionality has been broken since about 7.15.4 (March 2006) with the introduction of non-blocking OpenSSL "connects". It was a hack to begin with and since it doesn't work and hasn't worked correctly for a long time and nobody has even noticed, I consider it a very suitable subject for plain removal. And so it was done. --- lib/url.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7b06604d8..71a533d25 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1481,8 +1481,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = setstropt(&data->set.str[STRING_SET_URL], va_arg(param, char *)); data->change.url = data->set.str[STRING_SET_URL]; - if(data->change.url) - data->change.url_changed = TRUE; break; case CURLOPT_PORT: /* -- cgit v1.2.1 From 53a549000c3634f6b0a5ed262d5834c3145885d7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Feb 2008 09:56:26 +0000 Subject: - Based on initial work done by Gautam Kachroo to address a bug, we now keep better control at the exact state of the connection's SSL status so that we know exactly when it has completed the SSL negotiation or not so that there won't be accidental re-uses of connections that are wrongly believed to be in SSL-completed-negotiate state. --- lib/url.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 71a533d25..3c3605c1a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2439,10 +2439,17 @@ ConnectionExists(struct SessionHandle *data, ssl options as well */ if(!Curl_ssl_config_matches(&needle->ssl_config, &check->ssl_config)) { - infof(data, - "Connection #%ld has different SSL parameters, " - "can't reuse\n", - check->connectindex ); + DEBUGF(infof(data, + "Connection #%ld has different SSL parameters, " + "can't reuse\n", + check->connectindex)); + continue; + } + else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) { + DEBUGF(infof(data, + "Connection #%ld has not started ssl connect, " + "can't reuse\n", + check->connectindex)); continue; } } -- cgit v1.2.1 From 3bb460222787c68e19b2950e42ac0eb2ccb2b351 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 21 Feb 2008 12:28:45 +0000 Subject: assert that the *connp is a non-NULL pointer when Curl_done() is called --- lib/url.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3c3605c1a..541c11e79 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4392,8 +4392,13 @@ CURLcode Curl_done(struct connectdata **connp, bool premature) { CURLcode result; - struct connectdata *conn = *connp; - struct SessionHandle *data = conn->data; + struct connectdata *conn; + struct SessionHandle *data; + + DEBUGASSERT(*connp); + + conn = *connp; + data = conn->data; Curl_expire(data, 0); /* stop timer */ -- cgit v1.2.1 From 86cbb23282bee426439fc969d09a462acac0abe9 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 20 Mar 2008 08:09:23 +0000 Subject: - Added --with-ca-path=DIRECTORY configure option to use an openSSL CApath by default instead of a ca bundle. The configure script will also look for a ca path if no ca bundle is found and no option given. - Fixed detection of previously installed curl-ca-bundle.crt --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 541c11e79..6b07f2e82 100644 --- a/lib/url.c +++ b/lib/url.c @@ -746,10 +746,12 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.verifypeer = TRUE; data->set.ssl.verifyhost = 2; data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */ -#ifdef CURL_CA_BUNDLE - /* This is our preferred CA cert bundle since install time */ + /* This is our preferred CA cert bundle/path since install time */ +#if defined(CURL_CA_BUNDLE) res = setstropt(&data->set.str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE); +#elif defined(CURL_CA_PATH) + res = setstropt(&data->set.str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH); #endif } -- cgit v1.2.1 From 2c9763da3e5410415533d051ef40b0a24b376acb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Mar 2008 19:19:49 +0000 Subject: - Made setting the CURLOPT_SSL_CTX_FUNCTION option return a failure in case libcurl wasn't built to use OpenSSL as that is a prerequisite for this option to function! --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6b07f2e82..1dc51d189 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1769,6 +1769,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.ssl.verifyhost = va_arg(param, long); break; +#ifdef USE_SSLEAY + /* since these two options are only possible to use on an OpenSSL- + powered libcurl we #ifdef them on this condition so that libcurls + built against other SSL libs will return a proper error when trying + to set this option! */ case CURLOPT_SSL_CTX_FUNCTION: /* * Set a SSL_CTX callback @@ -1781,6 +1786,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.ssl.fsslctxp = va_arg(param, void *); break; +#endif case CURLOPT_CAINFO: /* * Set CA info for SSL connection. Specify file name of the CA certificate -- cgit v1.2.1 From d13be06aaa918f7098570f7f0f7a2a600a48d9a0 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 31 Mar 2008 12:09:43 +0000 Subject: Removed the generated ca-bundle.h file. The verbatim value of $ca and $capath is known to configure, so it can be defined in config.h instead. --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1dc51d189..9d782359b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -137,7 +137,6 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "inet_ntop.h" #include "http_ntlm.h" #include "socks.h" -#include #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) #include "inet_ntoa_r.h" -- cgit v1.2.1 From a9c1ca9fc5a80e858b0c85d8f8c838b4464526db Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Apr 2008 21:44:49 +0000 Subject: - Setting CURLOPT_NOBODY to FALSE will now switch the HTTP request method to GET simply because previously when you set CURLOPT_NOBODY to TRUE first and then FALSE you'd end up in a broken state where a HTTP request would do a HEAD by still act a lot like for a GET and hang waiting for the content etc. --- lib/url.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9d782359b..92f7156d3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -858,9 +858,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Do not include the body part in the output data stream. */ data->set.opt_no_body = (bool)(0 != va_arg(param, long)); - if(data->set.opt_no_body) - /* in HTTP lingo, this means using the HEAD request */ - data->set.httpreq = HTTPREQ_HEAD; + + /* in HTTP lingo, no body means using the HEAD request and if unset there + really is no perfect method that is the "opposite" of HEAD but in + reality most people probably think GET then. The important thing is + that we can't let it remain HEAD if the opt_no_body is set FALSE since + then we'll behave wrong when getting HTTP. */ + data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET; break; case CURLOPT_FAILONERROR: /* -- cgit v1.2.1 From 34d837c2dd1915e4e491460858c3481548ad067f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 5 Apr 2008 21:13:31 +0000 Subject: provide CURL_DEFAULT_PROXY_PORT set to 1080 for the default port libcurl assumes proxies to use --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 92f7156d3..45d8c58c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -719,7 +719,7 @@ CURLcode Curl_open(struct SessionHandle **curl) /* Set the default size of the SSL session ID cache */ data->set.ssl.numsessions = 5; - data->set.proxyport = 1080; + data->set.proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */ data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */ data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */ -- cgit v1.2.1 From 1960eebc2d021ecf5ffc3f6d4e935d54aa592c72 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 22 Apr 2008 22:53:53 +0000 Subject: Added support for running on Symbian OS. --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 45d8c58c0..9cda6dbac 100644 --- a/lib/url.c +++ b/lib/url.c @@ -150,6 +150,10 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by /* The last #include file should be: */ #include "memdebug.h" +#ifdef __SYMBIAN32__ +#undef SIGALRM +#endif + /* Local static prototypes */ static long ConnectionKillOne(struct SessionHandle *data); static bool ConnectionExists(struct SessionHandle *data, -- cgit v1.2.1 From 852989856d3802a9e7bd2f1e368302d92ddf66e2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 Apr 2008 21:20:08 +0000 Subject: - To make it easier for applications that want lots of magic stuff done on redirections and thus cannot use CURLOPT_FOLLOWLOCATION easily, we now introduce the new CURLINFO_REDIRECT_URL option that lets applications extract the URL libcurl would've redirected to if it had been told to. This then enables the application to continue to that URL as it thinks is suitable, without having to re-implement the magic of creating the new URL from the Location: header etc. Test 1029 verifies it. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9cda6dbac..906792332 100644 --- a/lib/url.c +++ b/lib/url.c @@ -494,6 +494,7 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_digest_cleanup(data); Curl_safefree(data->info.contenttype); + Curl_safefree(data->info.wouldredirect); /* this destroys the channel and we cannot use it anymore after this */ ares_destroy(data->state.areschannel); @@ -4440,6 +4441,10 @@ CURLcode Curl_done(struct connectdata **connp, free(data->req.newurl); data->req.newurl = NULL; } + if(data->req.location) { + free(data->req.location); + data->req.location = NULL; + } if(conn->dns_entry) { Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ -- cgit v1.2.1 From 3fe8251dfbb533803e25cc38365114b28c5a1c85 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 6 Jun 2008 18:40:21 +0000 Subject: - Axel Tillequin and Arnaud Ebalard added support for CURLOPT_CRLFILE, for OpenSSL, NSS and GnuTLS-built libcurls. --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 906792332..0e71cede0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1811,6 +1811,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = setstropt(&data->set.str[STRING_SSL_CAPATH], va_arg(param, char *)); break; + case CURLOPT_CRLFILE: + /* + * Set CRL file info for SSL connection. Specify file name of the CRL + * to check certificates revocation + */ + result = setstropt(&data->set.str[STRING_SSL_CRLFILE], + va_arg(param, char *)); + break; case CURLOPT_TELNETOPTIONS: /* * Set a linked list of telnet options @@ -3951,6 +3959,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH]; data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; -- cgit v1.2.1 From 621c2b901527248b4822895bc0305373a7d2dd63 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 6 Jun 2008 20:52:32 +0000 Subject: - Axel Tillequin and Arnaud Ebalard added support for CURLOPT_ISSUERCERT, for OpenSSL, NSS and GnuTLS-built libcurls. --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0e71cede0..a7f1a0c1a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1819,6 +1819,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = setstropt(&data->set.str[STRING_SSL_CRLFILE], va_arg(param, char *)); break; + case CURLOPT_ISSUERCERT: + /* + * Set Issuer certificate file + * to check certificates issuer + */ + result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT], + va_arg(param, char *)); + break; case CURLOPT_TELNETOPTIONS: /* * Set a linked list of telnet options @@ -3960,6 +3968,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH]; data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE]; data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; + data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; -- cgit v1.2.1 From fb2e71b9bd352bca7e3a5533c69bd236132a5d7a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 19 Jun 2008 08:31:22 +0000 Subject: - Dengminwen found a bug in the connection re-use function when using the multi interface with pipelining enabled as it would wrongly check for, detect and close "dead connections" even though that connection was already in use! --- lib/url.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a7f1a0c1a..6391edb28 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2511,9 +2511,10 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - if(pipeLen == 0) { - /* The check for a dead socket makes sense only if there - are no handles in pipeline */ + if(!pipeLen && !check->inuse) { + /* The check for a dead socket makes sense only if there are no + handles in pipeline and the connection isn't already marked in + use */ bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); if(dead) { check->data = data; -- cgit v1.2.1 From 90a6a59a2f27124917ee6931f66594a636a4c591 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Sun, 22 Jun 2008 06:57:00 +0000 Subject: Stopped using ranges in scanf character sequences (e.g. %[a-z]) since that is not ANSI C, just a common extension. This caused problems on at least Open Watcom C. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6391edb28..e61ec298c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3839,7 +3839,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * The conn->host.name is currently [user:passwd@]host[:port] where host * could be a hostname, IPv4 address or IPv6 address. *************************************************************/ - if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && + if((1 == sscanf(conn->host.name, "[%*39[0123456789abcdefABCDEF:.]%c", &endbracket)) && (']' == endbracket)) { /* this is a RFC2732-style specified IP-address */ conn->bits.ipv6_ip = TRUE; -- cgit v1.2.1 From eb60ba23f57eb51aba371c42a5af1e331514a28f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 30 Jun 2008 13:07:05 +0000 Subject: - Stephen Collyer and Tor Arntsen helped identify a flaw in the range code which output the range using a signed variable where it should rather use unsigned. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e61ec298c..f1f0c3cd7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3118,7 +3118,7 @@ static CURLcode setup_range(struct SessionHandle *data) free(s->range); if(s->resume_from) - s->range = aprintf("%" FORMAT_OFF_T "-", s->resume_from); + s->range = aprintf("%" FORMAT_OFF_TU "-", s->resume_from); else s->range = strdup(data->set.str[STRING_SET_RANGE]); -- cgit v1.2.1 From ad1145a2013bb16fa1a7ac782dc9a9b6a556d783 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 1 Jul 2008 21:53:18 +0000 Subject: CreateConnection collided with a function using the exact same name in the INTEGRITY RTOS, so I renamed it to create_conn. It then made sense to also rename SetupConnection to setup_conn to match it. --- lib/url.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f1f0c3cd7..f200e2b1e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3173,7 +3173,7 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, /* The protocol was not found in the table, but we don't have to assign it to anything since it is already assigned to a dummy-struct in the - CreateConnection() function when the connectdata struct is allocated. */ + create_conn() function when the connectdata struct is allocated. */ failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME, conn->protostr); return CURLE_UNSUPPORTED_PROTOCOL; @@ -3453,7 +3453,7 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, } /** - * CreateConnection() sets up a new connectdata struct, or re-uses an already + * create_conn() sets up a new connectdata struct, or re-uses an already * existing one, and resolves host name. * * if this function returns CURLE_OK and *async is set to TRUE, the resolve @@ -3466,12 +3466,12 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, * connection is re-used it will be NULL. * @param async is set TRUE/FALSE depending on the nature of this lookup * @return CURLcode - * @see SetupConnection() + * @see setup_conn() * * *NOTE* this function assigns the conn->data pointer! */ -static CURLcode CreateConnection(struct SessionHandle *data, +static CURLcode create_conn(struct SessionHandle *data, struct connectdata **in_connect, struct Curl_dns_entry **addr, bool *async) @@ -4246,16 +4246,16 @@ static CURLcode CreateConnection(struct SessionHandle *data, return result; } -/* SetupConnection() is called after the name resolve initiated in - * CreateConnection() is all done. +/* setup_conn() is called after the name resolve initiated in + * create_conn() is all done. * * NOTE: the argument 'hostaddr' is NULL when this function is called for a * re-used connection. * - * conn->data MUST already have been setup fine (in CreateConnection) + * conn->data MUST already have been setup fine (in create_conn) */ -static CURLcode SetupConnection(struct connectdata *conn, +static CURLcode setup_conn(struct connectdata *conn, struct Curl_dns_entry *hostaddr, bool *protocol_done) { @@ -4366,7 +4366,7 @@ CURLcode Curl_connect(struct SessionHandle *data, *asyncp = FALSE; /* assume synchronous resolves by default */ /* call the stuff that needs to be called */ - code = CreateConnection(data, in_connect, &dns, asyncp); + code = create_conn(data, in_connect, &dns, asyncp); if(CURLE_OK == code) { /* no error */ @@ -4379,7 +4379,7 @@ CURLcode Curl_connect(struct SessionHandle *data, /* If an address is available it means that we already have the name resolved, OR it isn't async. if this is a re-used connection 'dns' will be NULL here. Continue connecting from here */ - code = SetupConnection(*in_connect, dns, protocol_done); + code = setup_conn(*in_connect, dns, protocol_done); /* else response will be received and treated async wise */ } @@ -4405,7 +4405,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, { #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ defined(USE_THREADING_GETADDRINFO) - CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done); + CURLcode code = setup_conn(conn, conn->async.dns, protocol_done); if(code) /* We're not allowed to return failure with memory left allocated -- cgit v1.2.1 From 7c648782bc7c97be81c619acd8598c38b59c5832 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Jul 2008 06:56:03 +0000 Subject: Introcuding a new timestamp for curl_easy_getinfo(): CURLINFO_APPCONNECT_TIME. This is set with the "application layer" handshake/connection is completed (typically SSL, TLS or SSH). By using this you can figure out the application layer's own connect time. You can extract the time stamp using curl's -w option and the new variable named 'time_appconnect'. This feature was sponsored by Lenny Rachitsky at NeuStar. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f200e2b1e..4238256cb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4328,6 +4328,7 @@ static CURLcode setup_conn(struct connectdata *conn, } else { Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ + Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */ conn->bits.tcpconnect = TRUE; *protocol_done = TRUE; if(data->set.verbose) -- cgit v1.2.1 From 0d058d2174d9b11d0854826d2739f56595434255 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Jul 2008 09:08:27 +0000 Subject: - Daniel Fandrich found out we didn't pass on the user-agent properly when doing "proxy-tunnels" with non-HTTP prototols and that was simply because the code assumed the user-agent was only needed for HTTP. --- lib/url.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4238256cb..58c7331c8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4278,10 +4278,12 @@ static CURLcode setup_conn(struct connectdata *conn, lingering set from a previous invoke */ conn->bits.proxy_connect_closed = FALSE; - /************************************************************* - * Set user-agent for HTTP - *************************************************************/ - if((conn->protocol&PROT_HTTP) && data->set.str[STRING_USERAGENT]) { + /* + * Set user-agent. Used for HTTP, but since we can attempt to tunnel + * basically anything through a http proxy we can't limit this based on + * protocol. + */ + if(data->set.str[STRING_USERAGENT]) { Curl_safefree(conn->allocptr.uagent); conn->allocptr.uagent = aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); -- cgit v1.2.1 From 57625b6c4cc7348f4e2cfd6654acd7479f21f3c9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Jul 2008 09:18:30 +0000 Subject: indent and comment cleanup (no code change) --- lib/url.c | 209 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 101 insertions(+), 108 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 58c7331c8..9baa4b368 100644 --- a/lib/url.c +++ b/lib/url.c @@ -787,16 +787,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.dns_cache_timeout = va_arg(param, long); break; case CURLOPT_DNS_USE_GLOBAL_CACHE: - { - /* remember we want this enabled */ - long use_cache = va_arg(param, long); - data->set.global_dns_cache = (bool)(0 != use_cache); - } - break; + { + /* remember we want this enabled */ + long use_cache = va_arg(param, long); + data->set.global_dns_cache = (bool)(0 != use_cache); + } + break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_RANDOM_FILE: @@ -805,14 +805,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * the random SSL stuff with. The file is only used for reading. */ result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_EGDSOCKET: /* * The Entropy Gathering Daemon socket pathname */ result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_MAXCONNECTS: /* @@ -940,7 +940,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Use this file instead of the $HOME/.netrc file */ result = setstropt(&data->set.str[STRING_NETRC_FILE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_TRANSFERTEXT: /* @@ -993,8 +993,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ argptr = va_arg(param, char *); result = setstropt(&data->set.str[STRING_ENCODING], - (argptr && !*argptr)? - (char *) ALL_CONTENT_ENCODINGS: argptr); + (argptr && !*argptr)? + (char *) ALL_CONTENT_ENCODINGS: argptr); break; case CURLOPT_FOLLOWLOCATION: @@ -1056,8 +1056,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ if((data->set.postfieldsize < 0) || - ((sizeof(curl_off_t) != sizeof(size_t)) && - (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) + ((sizeof(curl_off_t) != sizeof(size_t)) && + (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) result = CURLE_OUT_OF_MEMORY; else { char * p; @@ -1068,7 +1068,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, later address compare to detect the COPYPOSTFIELDS mode, and to mark that postfields is used rather than read function or form data. - */ + */ p = malloc((size_t)(data->set.postfieldsize?data->set.postfieldsize:1)); if(!p) @@ -1104,11 +1104,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, bigsize = va_arg(param, long); if(data->set.postfieldsize < bigsize && - data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { + data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); data->set.postfields = NULL; - } + } data->set.postfieldsize = bigsize; break; @@ -1121,11 +1121,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, bigsize = va_arg(param, curl_off_t); if(data->set.postfieldsize < bigsize && - data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { + data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); data->set.postfields = NULL; - } + } data->set.postfieldsize = bigsize; break; @@ -1148,7 +1148,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->change.referer_alloc = FALSE; } result = setstropt(&data->set.str[STRING_SET_REFERER], - va_arg(param, char *)); + va_arg(param, char *)); data->change.referer = data->set.str[STRING_SET_REFERER]; break; @@ -1157,7 +1157,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * String to use in the HTTP User-Agent field */ result = setstropt(&data->set.str[STRING_USERAGENT], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_HTTPHEADER: @@ -1180,7 +1180,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Cookie string to send to the remote server in the request. */ result = setstropt(&data->set.str[STRING_COOKIE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_COOKIEFILE: @@ -1206,7 +1206,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set cookie file name to dump all cookies to when we're done. */ result = setstropt(&data->set.str[STRING_COOKIEJAR], - va_arg(param, char *)); + va_arg(param, char *)); /* * Activate the cookie parser. This may or may not already @@ -1310,7 +1310,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set a custom string to use as request */ result = setstropt(&data->set.str[STRING_CUSTOMREQUEST], - va_arg(param, char *)); + va_arg(param, char *)); /* we don't set data->set.httpreq = HTTPREQ_CUSTOM; @@ -1377,7 +1377,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * to decide for us. */ result = setstropt(&data->set.str[STRING_PROXY], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_WRITEHEADER: @@ -1404,7 +1404,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Use FTP PORT, this also specifies which IP address to use */ result = setstropt(&data->set.str[STRING_FTPPORT], - va_arg(param, char *)); + va_arg(param, char *)); data->set.ftp_use_port = (bool)(NULL != data->set.str[STRING_FTPPORT]); break; @@ -1489,7 +1489,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->change.url_alloc=FALSE; } result = setstropt(&data->set.str[STRING_SET_URL], - va_arg(param, char *)); + va_arg(param, char *)); data->change.url = data->set.str[STRING_SET_URL]; break; case CURLOPT_PORT: @@ -1526,7 +1526,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * user:password to use in the operation */ result = setstropt(&data->set.str[STRING_USERPWD], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_POSTQUOTE: /* @@ -1568,14 +1568,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * user:password needed to use the proxy */ result = setstropt(&data->set.str[STRING_PROXYUSERPWD], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_RANGE: /* * What range of the file you want to transfer */ result = setstropt(&data->set.str[STRING_SET_RANGE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_RESUME_FROM: /* @@ -1685,35 +1685,35 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * String that holds file name of the SSL certificate to use */ result = setstropt(&data->set.str[STRING_CERT], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_SSLCERTTYPE: /* * String that holds file type of the SSL certificate to use */ result = setstropt(&data->set.str[STRING_CERT_TYPE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_SSLKEY: /* * String that holds file name of the SSL certificate to use */ result = setstropt(&data->set.str[STRING_KEY], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_SSLKEYTYPE: /* * String that holds file type of the SSL certificate to use */ result = setstropt(&data->set.str[STRING_KEY_TYPE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_KEYPASSWD: /* * String that holds the SSL or SSH private key password. */ result = setstropt(&data->set.str[STRING_KEY_PASSWD], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_SSLENGINE: /* @@ -1721,7 +1721,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ argptr = va_arg(param, char *); if(argptr && argptr[0]) - result = Curl_ssl_set_engine(data, argptr); + result = Curl_ssl_set_engine(data, argptr); break; case CURLOPT_SSLENGINE_DEFAULT: @@ -1743,7 +1743,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * performing an operation and thus what from-IP your connection will use. */ result = setstropt(&data->set.str[STRING_DEVICE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_LOCALPORT: /* @@ -1762,7 +1762,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * A string that defines the kerberos security level. */ result = setstropt(&data->set.str[STRING_KRB_LEVEL], - va_arg(param, char *)); + va_arg(param, char *)); data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]); break; case CURLOPT_SSL_VERIFYPEER: @@ -1800,7 +1800,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set CA info for SSL connection. Specify file name of the CA certificate */ result = setstropt(&data->set.str[STRING_SSL_CAFILE], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_CAPATH: /* @@ -1809,7 +1809,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ /* This does not work on windows. */ result = setstropt(&data->set.str[STRING_SSL_CAPATH], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_CRLFILE: /* @@ -1856,60 +1856,60 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_SHARE: - { - struct Curl_share *set; - set = va_arg(param, struct Curl_share *); + { + struct Curl_share *set; + set = va_arg(param, struct Curl_share *); - /* disconnect from old share, if any */ - if(data->share) { - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + /* disconnect from old share, if any */ + if(data->share) { + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - if(data->dns.hostcachetype == HCACHE_SHARED) { - data->dns.hostcache = NULL; - data->dns.hostcachetype = HCACHE_NONE; - } + if(data->dns.hostcachetype == HCACHE_SHARED) { + data->dns.hostcache = NULL; + data->dns.hostcachetype = HCACHE_NONE; + } - if(data->share->cookies == data->cookies) - data->cookies = NULL; + if(data->share->cookies == data->cookies) + data->cookies = NULL; - data->share->dirty--; + data->share->dirty--; - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - data->share = NULL; - } + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + data->share = NULL; + } - /* use new share if it set */ - data->share = set; - if(data->share) { + /* use new share if it set */ + data->share = set; + if(data->share) { - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - data->share->dirty++; + data->share->dirty++; - if(data->share->hostcache) { - /* use shared host cache, first free the private one if any */ - if(data->dns.hostcachetype == HCACHE_PRIVATE) - Curl_hash_destroy(data->dns.hostcache); + if(data->share->hostcache) { + /* use shared host cache, first free the private one if any */ + if(data->dns.hostcachetype == HCACHE_PRIVATE) + Curl_hash_destroy(data->dns.hostcache); - data->dns.hostcache = data->share->hostcache; - data->dns.hostcachetype = HCACHE_SHARED; - } + data->dns.hostcache = data->share->hostcache; + data->dns.hostcachetype = HCACHE_SHARED; + } #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(data->share->cookies) { - /* use shared cookie list, first free own one if any */ - if(data->cookies) - Curl_cookie_cleanup(data->cookies); - /* enable cookies since we now use a share that uses cookies! */ - data->cookies = data->share->cookies; - } + if(data->share->cookies) { + /* use shared cookie list, first free own one if any */ + if(data->cookies) + Curl_cookie_cleanup(data->cookies); + /* enable cookies since we now use a share that uses cookies! */ + data->cookies = data->share->cookies; + } #endif /* CURL_DISABLE_HTTP */ - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - } - /* check for host cache not needed, - * it will be done by curl_easy_perform */ } - break; + /* check for host cache not needed, + * it will be done by curl_easy_perform */ + } + break; case CURLOPT_PROXYTYPE: /* @@ -1965,17 +1965,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.tcp_nodelay = (bool)(0 != va_arg(param, long)); break; - /* - case CURLOPT_SOURCE_URL: - case CURLOPT_SOURCE_USERPWD: - case CURLOPT_SOURCE_QUOTE: - case CURLOPT_SOURCE_PREQUOTE: - case CURLOPT_SOURCE_POSTQUOTE: - These former 3rd party transfer options are deprecated */ - case CURLOPT_FTP_ACCOUNT: result = setstropt(&data->set.str[STRING_FTP_ACCOUNT], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_IGNORE_CONTENT_LENGTH: @@ -1991,7 +1983,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_FTP_ALTERNATIVE_TO_USER: result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_SOCKOPTFUNCTION: @@ -2036,7 +2028,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Use this file instead of the $HOME/.ssh/id_dsa.pub file */ result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_SSH_PRIVATE_KEYFILE: @@ -2044,7 +2036,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Use this file instead of the $HOME/.ssh/id_dsa file */ result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: /* @@ -2052,7 +2044,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * for validation purposes. */ result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], - va_arg(param, char *)); + va_arg(param, char *)); break; case CURLOPT_HTTP_TRANSFER_DECODING: /* @@ -2086,16 +2078,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * set transfer mode (;type=) when doing FTP via an HTTP proxy */ switch (va_arg(param, long)) { - case 0: - data->set.proxy_transfer_mode = FALSE; - break; - case 1: - data->set.proxy_transfer_mode = TRUE; - break; - default: - /* reserve other values for future use */ - result = CURLE_FAILED_INIT; - break; + case 0: + data->set.proxy_transfer_mode = FALSE; + break; + case 1: + data->set.proxy_transfer_mode = TRUE; + break; + default: + /* reserve other values for future use */ + result = CURLE_FAILED_INIT; + break; } break; @@ -4344,11 +4336,12 @@ static CURLcode setup_conn(struct connectdata *conn, set this here perhaps a second time */ #ifdef __EMX__ - /* 20000330 mgs - * the check is quite a hack... - * we're calling _fsetmode to fix the problem with fwrite converting newline - * characters (you get mangled text files, and corrupted binary files when - * you download to stdout and redirect it to a file). */ + /* + * This check is quite a hack. We're calling _fsetmode to fix the problem + * with fwrite converting newline characters (you get mangled text files, + * and corrupted binary files when you download to stdout and redirect it to + * a file). + */ if((data->set.out)->_handle == NULL) { _fsetmode(stdout, "b"); -- cgit v1.2.1 From 5aed78e183e843a6935679d3ebdafd0c10b41114 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 30 Jul 2008 21:55:26 +0000 Subject: - Phil Blundell added the CURLOPT_SCOPE option, as well as adjusted the URL parser to allow numerical IPv6-addresses to be specified with the scope given, as per RFC4007 - with a percent letter that itself needs to be URL escaped. For example, for an address of fe80::1234%1 the HTTP URL is: "http://[fe80::1234%251]/" --- lib/url.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9baa4b368..170310beb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2091,6 +2091,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } break; + case CURLOPT_ADDRESS_SCOPE: + /* + * We always get longs when passed plain numericals, but for this value we + * know that an unsigned int will always hold the value so we blindly + * typecast to this type + */ + data->set.scope = (unsigned int) va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -3080,6 +3089,24 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, path[0] = '/'; } + if (conn->host.name[0] == '[' && !data->state.this_is_a_follow) { + /* This looks like an IPv6 address literal. See if there is an address + scope. */ + char *percent = strstr (conn->host.name, "%25"); + if (percent) { + char *endp; + conn->scope = strtoul (percent + 3, &endp, 10); + if (*endp == ']') { + /* The address scope was well formed. Knock it out of the hostname. */ + strcpy (percent, "]"); + } + } + } + + if (data->set.scope) + /* Override any scope that was set above. */ + conn->scope = data->set.scope; + /* * So if the URL was A://B/C, * conn->protostr is A -- cgit v1.2.1 From fe1d024351a0c061882c2b8df1eba7f37a925830 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 31 Jul 2008 02:18:01 +0000 Subject: Fixed a couple of problems in the IPv6 scope code. First, a host name in an URL in a Location: header didn't have the scope ID removed, so an invalid host name was used. Second, when the scope ID was removed, it also removed any port number that may have existed in the URL. --- lib/url.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 170310beb..e39a3d2a0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3089,16 +3089,19 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, path[0] = '/'; } - if (conn->host.name[0] == '[' && !data->state.this_is_a_follow) { + if (conn->host.name[0] == '[') { /* This looks like an IPv6 address literal. See if there is an address scope. */ char *percent = strstr (conn->host.name, "%25"); if (percent) { char *endp; - conn->scope = strtoul (percent + 3, &endp, 10); + unsigned int scope = strtoul (percent + 3, &endp, 10); if (*endp == ']') { /* The address scope was well formed. Knock it out of the hostname. */ - strcpy (percent, "]"); + memmove(percent, endp, strlen(endp)+1); + if (!data->state.this_is_a_follow) + /* Don't honour a scope given in a Location: header */ + conn->scope = scope; } } } -- cgit v1.2.1 From 660516914e35631714c73a2002ccfa4d854a0290 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 31 Jul 2008 20:04:00 +0000 Subject: Fixed parsing of an IPv6 proxy address to support a scope identifier, as well as IPv4 addresses in IPv6 format. Also, better handle the case of a malformatted IPv6 address (avoid empty and NULL strings). --- lib/url.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e39a3d2a0..2aec5656d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3102,7 +3102,8 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, if (!data->state.this_is_a_follow) /* Don't honour a scope given in a Location: header */ conn->scope = scope; - } + } else + infof(data, "Invalid IPv6 address format\n"); } } @@ -3406,13 +3407,14 @@ static CURLcode parse_proxy(struct SessionHandle *data, /* detect and extract RFC2732-style IPv6-addresses */ if(*proxyptr == '[') { char *ptr = ++proxyptr; /* advance beyond the initial bracket */ - while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':'))) + while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') || (*ptr == '.'))) ptr++; if(*ptr == ']') { /* yeps, it ended nicely with a bracket as well */ - *ptr = 0; - portptr = ptr+1; - } + *ptr++ = 0; + } else + infof(data, "Invalid IPv6 address format\n"); + portptr = ptr; /* Note that if this didn't end with a bracket, we still advanced the * proxyptr first, but I can't see anything wrong with that as no host * name nor a numeric can legally start with a bracket. -- cgit v1.2.1 From b4a5ce89c24a8015c1cb3226fd7a53a7af2048bc Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 31 Jul 2008 22:46:29 +0000 Subject: Fixed a problem with any FTP URL or any URLs containing an IPv6 address being mangled when passed to proxies when CURLOPT_PORT is also set (reported by Pramod Sharma). --- lib/url.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2aec5656d..abad3ba97 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3863,15 +3863,14 @@ static CURLcode create_conn(struct SessionHandle *data, * The conn->host.name is currently [user:passwd@]host[:port] where host * could be a hostname, IPv4 address or IPv6 address. *************************************************************/ - if((1 == sscanf(conn->host.name, "[%*39[0123456789abcdefABCDEF:.]%c", &endbracket)) && + if((1 == sscanf(conn->host.name, "[%*39[0123456789abcdefABCDEF:.%]%c", &endbracket)) && (']' == endbracket)) { /* this is a RFC2732-style specified IP-address */ conn->bits.ipv6_ip = TRUE; - conn->host.name++; /* pass the starting bracket */ + conn->host.name++; /* skip over the starting bracket */ tmp = strchr(conn->host.name, ']'); - *tmp = 0; /* zero terminate */ - tmp++; /* pass the ending bracket */ + *tmp++ = 0; /* zero terminate, killing the bracket */ if(':' != *tmp) tmp = NULL; /* no port number available */ } @@ -3887,9 +3886,18 @@ static CURLcode create_conn(struct SessionHandle *data, if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; + bool isftp = strequal("ftp", conn->protostr) || + strequal("ftps", conn->protostr); - url = aprintf("%s://%s:%d%s", conn->protostr, conn->host.name, - conn->remote_port, data->state.path); + /* + * This synthesized URL isn't always right--suffixes like ;type=A + * are stripped off. It would be better to work directly from the + * original URL and simply replace the port part of it. + */ + url = aprintf("%s://%s%s%s:%d%s%s", conn->protostr, + conn->bits.ipv6_ip?"[":"", conn->host.name, + conn->bits.ipv6_ip?"]":"", conn->remote_port, + isftp?"/":"", data->state.path); if(!url) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 09664f1ab8eda36174b91dde4c84537e834892a0 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 1 Aug 2008 00:55:43 +0000 Subject: Refactored create_conn by breaking it up into many smaller functions --- lib/url.c | 1259 ++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 669 insertions(+), 590 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index abad3ba97..b53cc5053 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2887,6 +2887,9 @@ static bool tld_check_name(struct SessionHandle *data, } #endif +/* + * Perform any necessary IDN conversion of hostname + */ static void fix_hostname(struct SessionHandle *data, struct connectdata *conn, struct hostname *host) { @@ -2926,6 +2929,38 @@ static void fix_hostname(struct SessionHandle *data, #endif } +/* + * Allocate and initialize a new connectdata object. + */ +static struct connectdata *allocate_conn(void) +{ + struct connectdata *conn; + + conn = (struct connectdata *)calloc(1, sizeof(struct connectdata)); + if(!conn) + return NULL; + + conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined + already from start to avoid NULL + situations and checks */ + + /* and we setup a few fields in case we end up actually using this struct */ + + conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->connectindex = -1; /* no index */ + + /* Default protocol-independent behavior doesn't support persistent + connections, so we set this to force-close. Protocols that support + this need to set this to FALSE in their "curl_do" functions. */ + conn->bits.close = TRUE; + + /* Store creation time to help future close decision making */ + conn->created = Curl_tvnow(); + + return conn; +} + /* * Parse URL and fill in the relevant members of the connection struct. */ @@ -3128,12 +3163,12 @@ static void llist_dtor(void *user, void *element) /* Do nothing */ } +/* + * If we're doing a resumed transfer, we need to setup our stuff + * properly. + */ static CURLcode setup_range(struct SessionHandle *data) { - /* - * If we're doing a resumed transfer, we need to setup our stuff - * properly. - */ struct UrlState *s = &data->state; s->resume_from = data->set.set_resume_from; if(s->resume_from || data->set.str[STRING_SET_RANGE]) { @@ -3326,7 +3361,8 @@ static char *detect_proxy(struct connectdata *conn) return proxy; } -/* If this is supposed to use a proxy, we need to figure out the proxy +/* + * If this is supposed to use a proxy, we need to figure out the proxy * host name, so that we can re-use an existing connection * that may exist registered to the same proxy host. * proxy will be freed before this function returns. @@ -3453,7 +3489,9 @@ static CURLcode parse_proxy(struct SessionHandle *data, return CURLE_OK; } -/* Extract the user and password from the authentication string */ +/* + * Extract the user and password from the authentication string + */ static CURLcode parse_proxy_auth(struct SessionHandle *data, struct connectdata *conn) { @@ -3476,162 +3514,606 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, return CURLE_OK; } -/** - * create_conn() sets up a new connectdata struct, or re-uses an already - * existing one, and resolves host name. +/* * - * if this function returns CURLE_OK and *async is set to TRUE, the resolve - * response will be coming asynchronously. If *async is FALSE, the name is - * already resolved. + * Parse a user name and password in the URL and strip it out of the host name * - * @param data The sessionhandle pointer - * @param in_connect is set to the next connection data pointer - * @param addr is set to the new dns entry for this connection. If this - * connection is re-used it will be NULL. - * @param async is set TRUE/FALSE depending on the nature of this lookup - * @return CURLcode - * @see setup_conn() + * Inputs: data->set.use_netrc (CURLOPT_NETRC) + * conn->host.name * - * *NOTE* this function assigns the conn->data pointer! + * Outputs: (almost :- all currently undefined) + * conn->bits.user_passwd - non-zero if non-default passwords exist + * user - non-zero length if defined + * passwd - ditto + * conn->host.name - remove user name and password */ - -static CURLcode create_conn(struct SessionHandle *data, - struct connectdata **in_connect, - struct Curl_dns_entry **addr, - bool *async) +static CURLcode parse_url_userpass(struct SessionHandle *data, + struct connectdata *conn, + char *user, char *passwd) { + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->host.name is at most + * [user[:password]]@]hostname + * + * We need somewhere to put the embedded details, so do that first. + */ - char *tmp; - CURLcode result=CURLE_OK; - struct connectdata *conn; - struct connectdata *conn_temp = NULL; - size_t urllen; - struct Curl_dns_entry *hostaddr; -#if defined(HAVE_ALARM) && !defined(USE_ARES) - unsigned int prev_alarm=0; -#endif - char endbracket; - char user[MAX_CURL_USER_LENGTH]; - char passwd[MAX_CURL_PASSWORD_LENGTH]; - int rc; - bool reuse; - char *proxy = NULL; - -#ifndef USE_ARES -#ifdef SIGALRM -#ifdef HAVE_SIGACTION - struct sigaction keep_sigact; /* store the old struct here */ - bool keep_copysig=FALSE; /* did copy it? */ -#else -#ifdef HAVE_SIGNAL - void (*keep_sigact)(int); /* store the old handler here */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ -#endif /* SIGALRM */ -#endif /* USE_ARES */ - - *addr = NULL; /* nothing yet */ - *async = FALSE; + user[0] =0; /* to make everything well-defined */ + passwd[0]=0; - /************************************************************* - * Check input data - *************************************************************/ + if(conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) { + /* This is a FTP, HTTP, SCP or SFTP 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->host.name, '@'); + char *userpass = conn->host.name; + if(ptr != NULL) { + /* there's a user+password given here, to the left of the @ */ - if(!data->change.url) - return CURLE_URL_MALFORMAT; + conn->host.name = ++ptr; - /* First, split up the current URL in parts so that we can use the - parts for checking against the already present connections. In order - to not have to modify everything at once, we allocate a temporary - connection data struct and fill in for comparison purposes. */ + /* So the hostname is sane. Only bother interpreting the + * results if we could care. It could still be wasted + * work because it might be overtaken by the programmatically + * set user/passwd, but doing that first adds more cases here :-( + */ - conn = (struct connectdata *)calloc(1, sizeof(struct connectdata)); - if(!conn) { - *in_connect = NULL; /* clear the pointer */ - return CURLE_OUT_OF_MEMORY; - } - /* We must set the return variable as soon as possible, so that our - parent can cleanup any possible allocs we may have done before - any failure */ - *in_connect = conn; + if(data->set.use_netrc != CURL_NETRC_REQUIRED) { + /* We could use the one in the URL */ - conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined - already from start to avoid NULL - situations and checks */ + conn->bits.user_passwd = 1; /* enable user+password */ - /* and we setup a few fields in case we end up actually using this struct */ + if(*userpass != ':') { + /* the name is given, get user+password */ + sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", + user, passwd); + } + else + /* no name given, get the password only */ + sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); - conn->data = data; /* Setup the association between this connection - and the SessionHandle */ + if(user[0]) { + char *newname=curl_easy_unescape(data, user, 0, NULL); + if(!newname) + return CURLE_OUT_OF_MEMORY; + if(strlen(newname) < MAX_CURL_USER_LENGTH) + strcpy(user, newname); - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->connectindex = -1; /* no index */ + /* if the new name is longer than accepted, then just use + the unconverted name, it'll be wrong but what the heck */ + free(newname); + } + if(passwd[0]) { + /* we have a password found in the URL, decode it! */ + char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); + if(!newpasswd) + return CURLE_OUT_OF_MEMORY; + if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) + strcpy(passwd, newpasswd); - conn->proxytype = data->set.proxytype; /* type */ - conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && - *data->set.str[STRING_PROXY]); - conn->bits.httpproxy = (bool)(conn->bits.proxy - && (conn->proxytype == CURLPROXY_HTTP)); + free(newpasswd); + } + } + } + } + return CURLE_OK; +} +/************************************************************* + * Figure out the remote port number and fix it in the URL + * + * No matter if we use a proxy or not, we have to figure out the remote + * port number of various reasons. + * + * To be able to detect port number flawlessly, we must not confuse them + * IPv6-specified addresses in the [0::1] style. (RFC2732) + * + * The conn->host.name is currently [user:passwd@]host[:port] where host + * could be a hostname, IPv4 address or IPv6 address. + * + * The port number embedded in the URL is replaced, if necessary. + *************************************************************/ +static CURLcode parse_remote_port(struct SessionHandle *data, + struct connectdata *conn) +{ + char *portptr; + char endbracket; - /* Default protocol-independent behavior doesn't support persistent - connections, so we set this to force-close. Protocols that support - this need to set this to FALSE in their "curl_do" functions. */ - conn->bits.close = TRUE; + if((1 == sscanf(conn->host.name, "[%*39[0123456789abcdefABCDEF:.%]%c", &endbracket)) && + (']' == endbracket)) { + /* this is a RFC2732-style specified IP-address */ + conn->bits.ipv6_ip = TRUE; - conn->readchannel_inuse = FALSE; - conn->writechannel_inuse = FALSE; + conn->host.name++; /* skip over the starting bracket */ + portptr = strchr(conn->host.name, ']'); + *portptr++ = 0; /* zero terminate, killing the bracket */ + if(':' != *portptr) + portptr = NULL; /* no port number available */ + } + else + portptr = strrchr(conn->host.name, ':'); - conn->read_pos = 0; - conn->buf_len = 0; + if(data->set.use_port && data->state.allow_port) { + /* if set, we use this and ignore the port possibly given in the URL */ + conn->remote_port = (unsigned short)data->set.use_port; + if(portptr) + *portptr = '\0'; /* cut off the name there anyway - if there was a port + number - since the port number is to be ignored! */ + if(conn->bits.httpproxy) { + /* we need to create new URL with the new port number */ + char *url; + bool isftp = strequal("ftp", conn->protostr) || + strequal("ftps", conn->protostr); - /* Store creation time to help future close decision making */ - conn->created = Curl_tvnow(); + /* + * This synthesized URL isn't always right--suffixes like ;type=A + * are stripped off. It would be better to work directly from the + * original URL and simply replace the port part of it. + */ + url = aprintf("%s://%s%s%s:%d%s%s", conn->protostr, + conn->bits.ipv6_ip?"[":"", conn->host.name, + conn->bits.ipv6_ip?"]":"", conn->remote_port, + isftp?"/":"", data->state.path); + if(!url) + return CURLE_OUT_OF_MEMORY; - conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); - conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; - conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; - conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + if(data->change.url_alloc) + free(data->change.url); - if(data->multi && Curl_multi_canPipeline(data->multi) && - !conn->master_buffer) { - /* Allocate master_buffer to be used for pipelining */ - conn->master_buffer = calloc(BUFSIZE, sizeof (char)); - if(!conn->master_buffer) - return CURLE_OUT_OF_MEMORY; + data->change.url = url; + data->change.url_alloc = TRUE; + } } + else if(portptr) { + /* no CURLOPT_PORT given, extract the one from the URL */ - /* Initialize the pipeline lists */ - conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe) - return CURLE_OUT_OF_MEMORY; + char *rest; + unsigned long port; - /* This initing continues below, see the comment "Continue connectdata - * initialization here" */ + port=strtoul(portptr+1, &rest, 10); /* Port number must be decimal */ - /*********************************************************** - * We need to allocate memory to store the path in. We get the size of the - * full URL to be sure, and we need to make it at least 256 bytes since - * other parts of the code will rely on this fact - ***********************************************************/ -#define LEAST_PATH_ALLOC 256 - urllen=strlen(data->change.url); - if(urllen < LEAST_PATH_ALLOC) - urllen=LEAST_PATH_ALLOC; + if(rest != (portptr+1) && *rest == '\0') { + /* The colon really did have only digits after it, + * so it is either a port number or a mistake */ - /* Free the old buffer */ - Curl_safefree(data->state.pathbuffer); + if(port > 0xffff) { /* Single unix standard says port numbers are + * 16 bits long */ + failf(data, "Port number too large: %lu", port); + return CURLE_URL_MALFORMAT; + } - /* + *portptr = '\0'; /* cut off the name there */ + conn->remote_port = (unsigned short)port; + } + } + return CURLE_OK; +} + +/* + * Override a user name and password from the URL with that in the + * CURLOPT_USERPWD option or a .netrc file, if applicable. + */ +static void override_userpass(struct SessionHandle *data, + struct connectdata *conn, + char *user, char *passwd) +{ + if(data->set.str[STRING_USERPWD] != NULL) { + /* the name is given, get user+password */ + sscanf(data->set.str[STRING_USERPWD], + "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", + user, passwd); + } + + conn->bits.netrc = FALSE; + if(data->set.use_netrc != CURL_NETRC_IGNORED) { + if(Curl_parsenetrc(conn->host.name, + user, passwd, + data->set.str[STRING_NETRC_FILE])) { + infof(data, "Couldn't find host %s in the " + DOT_CHAR "netrc file; using defaults\n", + conn->host.name); + } + else { + /* set bits.netrc TRUE to remember that we got the name from a .netrc + file, so that it is safe to use even if we followed a Location: to a + different host or similar. */ + conn->bits.netrc = TRUE; + + conn->bits.user_passwd = 1; /* enable user+password */ + } + } +} + +/* + * Set password so it's available in the connection. + */ +static CURLcode set_userpass(struct connectdata *conn, + const char *user, const char *passwd) +{ + /* If our protocol needs a password and we have none, use the defaults */ + if( (conn->protocol & PROT_FTP) && + !conn->bits.user_passwd) { + + conn->user = strdup(CURL_DEFAULT_USER); + conn->passwd = strdup(CURL_DEFAULT_PASSWORD); + /* This is the default password, so DON'T set conn->bits.user_passwd */ + } + else { + /* store user + password, zero-length if not set */ + conn->user = strdup(user); + conn->passwd = strdup(passwd); + } + if(!conn->user || !conn->passwd) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +/************************************************************* + * Resolve the address of the server or proxy + *************************************************************/ +static CURLcode resolve_server(struct SessionHandle *data, + struct connectdata *conn, + struct Curl_dns_entry **addr, + bool *async) +{ + CURLcode result=CURLE_OK; +#ifndef USE_ARES +#ifdef SIGALRM +#ifdef HAVE_SIGACTION + struct sigaction keep_sigact; /* store the old struct here */ + bool keep_copysig=FALSE; /* did copy it? */ +#else +#ifdef HAVE_SIGNAL + void (*keep_sigact)(int); /* store the old handler here */ +#endif /* HAVE_SIGNAL */ +#endif /* HAVE_SIGACTION */ +#endif /* SIGALRM */ +#endif /* USE_ARES */ + +#if defined(HAVE_ALARM) && !defined(USE_ARES) + unsigned int prev_alarm=0; +#endif + +#ifndef USE_ARES + /************************************************************* + * Set timeout if that is being used, and we're not using an asynchronous + * name resolve. + *************************************************************/ + if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { + /************************************************************* + * Set signal handler to catch SIGALRM + * Store the old value to be able to set it back later! + *************************************************************/ + +#ifdef SIGALRM +#ifdef HAVE_ALARM + long shortest; +#endif +#ifdef HAVE_SIGACTION + struct sigaction sigact; + sigaction(SIGALRM, NULL, &sigact); + keep_sigact = sigact; + keep_copysig = TRUE; /* yes, we have a copy */ + sigact.sa_handler = alarmfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; +#endif + /* now set the new struct */ + sigaction(SIGALRM, &sigact, NULL); +#else /* HAVE_SIGACTION */ + /* no sigaction(), revert to the much lamer signal() */ +#ifdef HAVE_SIGNAL + keep_sigact = signal(SIGALRM, alarmfunc); +#endif +#endif /* HAVE_SIGACTION */ + + /* We set the timeout on the name resolving phase first, separately from + * the download/upload part to allow a maximum time on everything. This is + * a signal-based timeout, why it won't work and shouldn't be used in + * multi-threaded environments. */ + +#ifdef HAVE_ALARM + shortest = data->set.timeout; /* default to this timeout value */ + if(shortest && data->set.connecttimeout && + (data->set.connecttimeout < shortest)) + /* if both are set, pick the shortest */ + shortest = data->set.connecttimeout; + else if(!shortest) + /* if timeout is not set, use the connect timeout */ + shortest = data->set.connecttimeout; + + if(shortest < 1000) + /* the alarm() function only provide integer second resolution, so if + we want to wait less than one second we must bail out already now. */ + return CURLE_OPERATION_TIMEDOUT; + + /* alarm() makes a signal get sent when the timeout fires off, and that + will abort system calls */ + prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest)); + /* We can expect the conn->created time to be "now", as that was just + recently set in the beginning of this function and nothing slow + has been done since then until now. */ +#endif +#endif /* SIGALRM */ + } +#endif /* USE_ARES */ + + /************************************************************* + * Resolve the name of the server or proxy + *************************************************************/ + if(conn->bits.reuse) { + /* re-used connection, no resolving is necessary */ + *addr = NULL; + /* we'll need to clear conn->dns_entry later in Curl_disconnect() */ + + if(conn->bits.proxy) + fix_hostname(data, conn, &conn->host); + } + else { + /* this is a fresh connect */ + int rc; + struct Curl_dns_entry *hostaddr; + + /* set a pointer to the hostname we display */ + fix_hostname(data, conn, &conn->host); + + if(!conn->proxy.name || !*conn->proxy.name) { + /* 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 */ + + /* Resolve target host right on */ + rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr); + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + + else if(!hostaddr) { + failf(data, "Couldn't resolve host '%s'", conn->host.dispname); + result = CURLE_COULDNT_RESOLVE_HOST; + /* don't return yet, we need to clean up the timeout first */ + } + } + else { + /* This is a proxy that hasn't been resolved yet. */ + + /* IDN-fix the proxy name */ + fix_hostname(data, conn, &conn->proxy); + + /* resolve proxy */ + rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr); + + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + + else if(!hostaddr) { + failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); + result = CURLE_COULDNT_RESOLVE_PROXY; + /* don't return yet, we need to clean up the timeout first */ + } + } + *addr = hostaddr; + } + +#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) + if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { +#ifdef HAVE_SIGACTION + if(keep_copysig) { + /* we got a struct as it looked before, now put that one back nice + and clean */ + sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ + } +#else +#ifdef HAVE_SIGNAL + /* restore the previous SIGALRM handler */ + signal(SIGALRM, keep_sigact); +#endif +#endif /* HAVE_SIGACTION */ + + /* switch back the alarm() to either zero or to what it was before minus + the time we spent until now! */ + if(prev_alarm) { + /* there was an alarm() set before us, now put it back */ + unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); + unsigned long alarm_set; + + /* the alarm period is counted in even number of seconds */ + alarm_set = prev_alarm - elapsed_ms/1000; + + if(!alarm_set || + ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { + /* if the alarm time-left reached zero or turned "negative" (counted + with unsigned values), we should fire off a SIGALRM here, but we + won't, and zero would be to switch it off so we never set it to + less than 1! */ + alarm(1); + result = CURLE_OPERATION_TIMEDOUT; + failf(data, "Previous alarm fired off!"); + } + else + alarm((unsigned int)alarm_set); + } + else + alarm(0); /* just shut it off */ + } +#endif + return result; +} + +/* + * Cleanup the connection just allocated before we can move along and use the + * previously existing one. All relevant data is copied over and old_conn is + * ready for freeing once this function returns. + */ +static void reuse_conn(struct connectdata *old_conn, + struct connectdata *conn) +{ + if(old_conn->proxy.rawalloc) + free(old_conn->proxy.rawalloc); + + /* free the SSL config struct from this connection struct as this was + allocated in vain and is targeted for destruction */ + Curl_free_ssl_config(&old_conn->ssl_config); + + conn->data = old_conn->data; + + /* get the user+password information from the old_conn struct since it may + * be new for this request even when we re-use an existing connection */ + conn->bits.user_passwd = old_conn->bits.user_passwd; + if(conn->bits.user_passwd) { + /* use the new user name and password though */ + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + conn->user = old_conn->user; + conn->passwd = old_conn->passwd; + old_conn->user = NULL; + old_conn->passwd = NULL; + } + + conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; + if(conn->bits.proxy_user_passwd) { + /* use the new proxy user name and proxy password though */ + Curl_safefree(conn->proxyuser); + Curl_safefree(conn->proxypasswd); + conn->proxyuser = old_conn->proxyuser; + conn->proxypasswd = old_conn->proxypasswd; + old_conn->proxyuser = NULL; + old_conn->proxypasswd = NULL; + } + + /* host can change, when doing keepalive with a proxy ! */ + if(conn->bits.proxy) { + free(conn->host.rawalloc); + conn->host=old_conn->host; + } + else + free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ + + /* re-use init */ + conn->bits.reuse = TRUE; /* yes, we're re-using here */ + + Curl_safefree(old_conn->user); + Curl_safefree(old_conn->passwd); + Curl_safefree(old_conn->proxyuser); + Curl_safefree(old_conn->proxypasswd); + Curl_llist_destroy(old_conn->send_pipe, NULL); + Curl_llist_destroy(old_conn->recv_pipe, NULL); + Curl_llist_destroy(old_conn->pend_pipe, NULL); + Curl_safefree(old_conn->master_buffer); +} + +/** + * create_conn() sets up a new connectdata struct, or re-uses an already + * existing one, and resolves host name. + * + * if this function returns CURLE_OK and *async is set to TRUE, the resolve + * response will be coming asynchronously. If *async is FALSE, the name is + * already resolved. + * + * @param data The sessionhandle pointer + * @param in_connect is set to the next connection data pointer + * @param addr is set to the new dns entry for this connection. If this + * connection is re-used it will be NULL. + * @param async is set TRUE/FALSE depending on the nature of this lookup + * @return CURLcode + * @see setup_conn() + * + * *NOTE* this function assigns the conn->data pointer! + */ + +static CURLcode create_conn(struct SessionHandle *data, + struct connectdata **in_connect, + struct Curl_dns_entry **addr, + bool *async) +{ + CURLcode result=CURLE_OK; + struct connectdata *conn; + struct connectdata *conn_temp = NULL; + size_t urllen; + char user[MAX_CURL_USER_LENGTH]; + char passwd[MAX_CURL_PASSWORD_LENGTH]; + bool reuse; + char *proxy = NULL; + + *addr = NULL; /* nothing yet */ + *async = FALSE; + + /************************************************************* + * Check input data + *************************************************************/ + + if(!data->change.url) + return CURLE_URL_MALFORMAT; + + /* First, split up the current URL in parts so that we can use the + parts for checking against the already present connections. In order + to not have to modify everything at once, we allocate a temporary + connection data struct and fill in for comparison purposes. */ + + conn = allocate_conn(); + + /* We must set the return variable as soon as possible, so that our + parent can cleanup any possible allocs we may have done before + any failure */ + *in_connect = conn; + + if(!conn) + return CURLE_OUT_OF_MEMORY; + + conn->data = data; /* Setup the association between this connection + and the SessionHandle */ + + conn->proxytype = data->set.proxytype; /* type */ + conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && + *data->set.str[STRING_PROXY]); + conn->bits.httpproxy = (bool)(conn->bits.proxy + && (conn->proxytype == CURLPROXY_HTTP)); + + + conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); + conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; + conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; + conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + + if(data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ + conn->master_buffer = calloc(BUFSIZE, sizeof (char)); + if(!conn->master_buffer) + return CURLE_OUT_OF_MEMORY; + } + + /* Initialize the pipeline lists */ + conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe) + return CURLE_OUT_OF_MEMORY; + + /* This initing continues below, see the comment "Continue connectdata + * initialization here" */ + + /*********************************************************** + * We need to allocate memory to store the path in. We get the size of the + * full URL to be sure, and we need to make it at least 256 bytes since + * other parts of the code will rely on this fact + ***********************************************************/ +#define LEAST_PATH_ALLOC 256 + urllen=strlen(data->change.url); + if(urllen < LEAST_PATH_ALLOC) + urllen=LEAST_PATH_ALLOC; + + /* * We malloc() the buffers below urllen+2 to make room for to possibilities: * 1 - an extra terminating zero * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) */ + Curl_safefree(data->state.pathbuffer); data->state.pathbuffer=(char *)malloc(urllen+2); if(NULL == data->state.pathbuffer) return CURLE_OUT_OF_MEMORY; /* really bad error */ @@ -3650,7 +4132,7 @@ static CURLcode create_conn(struct SessionHandle *data, } /************************************************************* - * Take care of proxy authentication stuff + * Extract the user and password from the authentication string *************************************************************/ if(conn->bits.proxy_user_passwd) { result = parse_proxy_auth(data, conn); @@ -3722,7 +4204,6 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } - /*********************************************************************** * file: is a special case in that it doesn't need a network connection ***********************************************************************/ @@ -3734,254 +4215,63 @@ static CURLcode create_conn(struct SessionHandle *data, DEBUGASSERT(conn->handler->connect_it); result = conn->handler->connect_it(conn, &done); - /* Setup a "faked" transfer that'll do nothing */ - if(CURLE_OK == result) { - conn->data = data; - conn->bits.tcpconnect = TRUE; /* we are "connected */ - - ConnectionStore(data, conn); - - result = setup_range(data); - if(result) { - DEBUGASSERT(conn->handler->done); - /* we ignore the return code for the protocol-specific DONE */ - (void)conn->handler->done(conn, result, FALSE); - return result; - } - - result = Curl_setup_transfer(conn, -1, -1, FALSE, - NULL, /* no download */ - -1, NULL); /* no upload */ - } - - return result; - } -#endif - - /************************************************************* - * If the protocol is using SSL and HTTP proxy is used, we set - * the tunnel_proxy bit. - *************************************************************/ - if((conn->protocol&PROT_SSL) && conn->bits.httpproxy) - conn->bits.tunnel_proxy = TRUE; - - /************************************************************* - * Take care of user and password authentication stuff - *************************************************************/ - - /* - * Inputs: data->set.userpwd (CURLOPT_USERPWD) - * data->set.fpasswd (CURLOPT_PASSWDFUNCTION) - * data->set.use_netrc (CURLOPT_NETRC) - * conn->host.name - * netrc file - * hard-coded defaults - * - * Outputs: (almost :- all currently undefined) - * conn->bits.user_passwd - non-zero if non-default passwords exist - * conn->user - non-zero length if defined - * conn->passwd - ditto - * conn->host.name - remove user name and password - */ - - /* At this point, we're hoping all the other special cases have - * been taken care of, so conn->host.name is at most - * [user[:password]]@]hostname - * - * We need somewhere to put the embedded details, so do that first. - */ - - user[0] =0; /* to make everything well-defined */ - passwd[0]=0; - - if(conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) { - /* This is a FTP, HTTP, SCP or SFTP 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->host.name, '@'); - char *userpass = conn->host.name; - if(ptr != NULL) { - /* there's a user+password given here, to the left of the @ */ - - conn->host.name = ++ptr; - - /* So the hostname is sane. Only bother interpreting the - * results if we could care. It could still be wasted - * work because it might be overtaken by the programmatically - * set user/passwd, but doing that first adds more cases here :-( - */ - - if(data->set.use_netrc != CURL_NETRC_REQUIRED) { - /* We could use the one in the URL */ - - conn->bits.user_passwd = 1; /* enable user+password */ - - if(*userpass != ':') { - /* the name is given, get user+password */ - sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - user, passwd); - } - else - /* no name given, get the password only */ - sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); - - if(user[0]) { - char *newname=curl_easy_unescape(data, user, 0, NULL); - if(!newname) - return CURLE_OUT_OF_MEMORY; - if(strlen(newname) < sizeof(user)) - strcpy(user, newname); - - /* if the new name is longer than accepted, then just use - the unconverted name, it'll be wrong but what the heck */ - free(newname); - } - if(passwd[0]) { - /* we have a password found in the URL, decode it! */ - char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); - if(!newpasswd) - return CURLE_OUT_OF_MEMORY; - if(strlen(newpasswd) < sizeof(passwd)) - strcpy(passwd, newpasswd); - - free(newpasswd); - } - } - } - } - - /************************************************************* - * Figure out the remote port number - * - * No matter if we use a proxy or not, we have to figure out the remote - * port number of various reasons. - * - * To be able to detect port number flawlessly, we must not confuse them - * IPv6-specified addresses in the [0::1] style. (RFC2732) - * - * The conn->host.name is currently [user:passwd@]host[:port] where host - * could be a hostname, IPv4 address or IPv6 address. - *************************************************************/ - if((1 == sscanf(conn->host.name, "[%*39[0123456789abcdefABCDEF:.%]%c", &endbracket)) && - (']' == endbracket)) { - /* this is a RFC2732-style specified IP-address */ - conn->bits.ipv6_ip = TRUE; - - conn->host.name++; /* skip over the starting bracket */ - tmp = strchr(conn->host.name, ']'); - *tmp++ = 0; /* zero terminate, killing the bracket */ - if(':' != *tmp) - tmp = NULL; /* no port number available */ - } - else - tmp = strrchr(conn->host.name, ':'); - - if(data->set.use_port && data->state.allow_port) { - /* if set, we use this and ignore the port possibly given in the URL */ - conn->remote_port = (unsigned short)data->set.use_port; - if(tmp) - *tmp = '\0'; /* cut off the name there anyway - if there was a port - number - since the port number is to be ignored! */ - if(conn->bits.httpproxy) { - /* we need to create new URL with the new port number */ - char *url; - bool isftp = strequal("ftp", conn->protostr) || - strequal("ftps", conn->protostr); - - /* - * This synthesized URL isn't always right--suffixes like ;type=A - * are stripped off. It would be better to work directly from the - * original URL and simply replace the port part of it. - */ - url = aprintf("%s://%s%s%s:%d%s%s", conn->protostr, - conn->bits.ipv6_ip?"[":"", conn->host.name, - conn->bits.ipv6_ip?"]":"", conn->remote_port, - isftp?"/":"", data->state.path); - if(!url) - return CURLE_OUT_OF_MEMORY; - - if(data->change.url_alloc) - free(data->change.url); - - data->change.url = url; - data->change.url_alloc = TRUE; - } - } - else if(tmp) { - /* no CURLOPT_PORT given, extract the one from the URL */ - - char *rest; - unsigned long port; - - port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */ + /* Setup a "faked" transfer that'll do nothing */ + if(CURLE_OK == result) { + conn->data = data; + conn->bits.tcpconnect = TRUE; /* we are "connected */ - if(rest != (tmp+1) && *rest == '\0') { - /* The colon really did have only digits after it, - * so it is either a port number or a mistake */ + ConnectionStore(data, conn); - if(port > 0xffff) { /* Single unix standard says port numbers are - * 16 bits long */ - failf(data, "Port number too large: %lu", port); - return CURLE_URL_MALFORMAT; + /* + * Setup whatever necessary for a resumed transfer + */ + result = setup_range(data); + if(result) { + DEBUGASSERT(conn->handler->done); + /* we ignore the return code for the protocol-specific DONE */ + (void)conn->handler->done(conn, result, FALSE); + return result; } - *tmp = '\0'; /* cut off the name there */ - conn->remote_port = (unsigned short)port; + result = Curl_setup_transfer(conn, -1, -1, FALSE, + NULL, /* no download */ + -1, NULL); /* no upload */ } - } - /* Programmatically set password: - * - always applies, if available - * - takes precedence over the values we just set above - * so scribble it over the top. - * User-supplied passwords are assumed not to need unescaping. - * - * user_password is set in "inherit initial knowledge' above, - * so it doesn't have to be set in this block - */ - if(data->set.str[STRING_USERPWD] != NULL) { - /* the name is given, get user+password */ - sscanf(data->set.str[STRING_USERPWD], - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - user, passwd); + return result; } +#endif - conn->bits.netrc = FALSE; - if(data->set.use_netrc != CURL_NETRC_IGNORED) { - if(Curl_parsenetrc(conn->host.name, - user, passwd, - data->set.str[STRING_NETRC_FILE])) { - infof(data, "Couldn't find host %s in the " DOT_CHAR - "netrc file, using defaults\n", - conn->host.name); - } - else { - /* set bits.netrc TRUE to remember that we got the name from a .netrc - file, so that it is safe to use even if we followed a Location: to a - different host or similar. */ - conn->bits.netrc = TRUE; + /************************************************************* + * If the protocol is using SSL and HTTP proxy is used, we set + * the tunnel_proxy bit. + *************************************************************/ + if((conn->protocol&PROT_SSL) && conn->bits.httpproxy) + conn->bits.tunnel_proxy = TRUE; - conn->bits.user_passwd = 1; /* enable user+password */ - } - } + /************************************************************* + * Parse a user name and password in the URL and strip it out + * of the host name + *************************************************************/ + result = parse_url_userpass(data, conn, user, passwd); + if(result != CURLE_OK) + return result; - /* If our protocol needs a password and we have none, use the defaults */ - if( (conn->protocol & PROT_FTP) && - !conn->bits.user_passwd) { + /************************************************************* + * Figure out the remote port number and fix it in the URL + *************************************************************/ + result = parse_remote_port(data, conn); + if(result != CURLE_OK) + return result; - conn->user = strdup(CURL_DEFAULT_USER); - conn->passwd = strdup(CURL_DEFAULT_PASSWORD); - /* This is the default password, so DON'T set conn->bits.user_passwd */ - } - else { - /* store user + password, zero-length if not set */ - conn->user = strdup(user); - conn->passwd = strdup(passwd); - } - if(!conn->user || !conn->passwd) - return CURLE_OUT_OF_MEMORY; + /************************************************************* + * Check for an overridden user name and password, then set it + * for use + *************************************************************/ + override_userpass(data, conn, user, passwd); + result = set_userpass(conn, user, passwd); + if(result != CURLE_OK) + return result; /************************************************************* * Check the current list of connections to see if we can @@ -4025,67 +4315,10 @@ static CURLcode create_conn(struct SessionHandle *data, * just allocated before we can move along and use the previously * existing one. */ - struct connectdata *old_conn = conn; - - if(old_conn->proxy.rawalloc) - free(old_conn->proxy.rawalloc); - - /* free the SSL config struct from this connection struct as this was - allocated in vain and is targeted for destruction */ - Curl_free_ssl_config(&conn->ssl_config); - - conn = conn_temp; /* use this connection from now on */ - - conn->data = old_conn->data; - - /* get the user+password information from the old_conn struct since it may - * be new for this request even when we re-use an existing connection */ - conn->bits.user_passwd = old_conn->bits.user_passwd; - if(conn->bits.user_passwd) { - /* use the new user namd and password though */ - Curl_safefree(conn->user); - Curl_safefree(conn->passwd); - conn->user = old_conn->user; - conn->passwd = old_conn->passwd; - old_conn->user = NULL; - old_conn->passwd = NULL; - } - - conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; - if(conn->bits.proxy_user_passwd) { - /* use the new proxy user name and proxy password though */ - Curl_safefree(conn->proxyuser); - Curl_safefree(conn->proxypasswd); - conn->proxyuser = old_conn->proxyuser; - conn->proxypasswd = old_conn->proxypasswd; - old_conn->proxyuser = NULL; - old_conn->proxypasswd = NULL; - } - - /* host can change, when doing keepalive with a proxy ! */ - if(conn->bits.proxy) { - free(conn->host.rawalloc); - conn->host=old_conn->host; - } - else - free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ - - /* re-use init */ - conn->bits.reuse = TRUE; /* yes, we're re-using here */ - - Curl_safefree(old_conn->user); - Curl_safefree(old_conn->passwd); - Curl_safefree(old_conn->proxyuser); - Curl_safefree(old_conn->proxypasswd); - Curl_llist_destroy(old_conn->send_pipe, NULL); - Curl_llist_destroy(old_conn->recv_pipe, NULL); - Curl_llist_destroy(old_conn->pend_pipe, NULL); - Curl_safefree(old_conn->master_buffer); - - free(old_conn); /* we don't need this anymore */ - - *in_connect = conn; /* return this instead! */ - + reuse_conn(conn, conn_temp); + free(conn); /* we don't need this anymore */ + conn = conn_temp; + *in_connect = conn; infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->proxy.name?conn->proxy.dispname:conn->host.dispname); @@ -4098,6 +4331,9 @@ static CURLcode create_conn(struct SessionHandle *data, ConnectionStore(data, conn); } + /* + * Setup whatever necessary for a resumed transfer + */ result = setup_range(data); if(result) return result; @@ -4105,175 +4341,18 @@ static CURLcode create_conn(struct SessionHandle *data, /* Continue connectdata initialization here. */ /* - * * Inherit the proper values from the urldata struct AFTER we have arranged - * the persistent connection stuff */ + * the persistent connection stuff + */ conn->fread_func = data->set.fread_func; conn->fread_in = data->set.in; conn->seek_func = data->set.seek_func; conn->seek_client = data->set.seek_client; -#ifndef USE_ARES - /************************************************************* - * Set timeout if that is being used, and we're not using an asynchronous - * name resolve. - *************************************************************/ - if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { - /************************************************************* - * Set signal handler to catch SIGALRM - * Store the old value to be able to set it back later! - *************************************************************/ - -#ifdef SIGALRM -#ifdef HAVE_ALARM - long shortest; -#endif -#ifdef HAVE_SIGACTION - struct sigaction sigact; - sigaction(SIGALRM, NULL, &sigact); - keep_sigact = sigact; - keep_copysig = TRUE; /* yes, we have a copy */ - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - /* now set the new struct */ - sigaction(SIGALRM, &sigact, NULL); -#else /* HAVE_SIGACTION */ - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - keep_sigact = signal(SIGALRM, alarmfunc); -#endif -#endif /* HAVE_SIGACTION */ - - /* We set the timeout on the name resolving phase first, separately from - * the download/upload part to allow a maximum time on everything. This is - * a signal-based timeout, why it won't work and shouldn't be used in - * multi-threaded environments. */ - -#ifdef HAVE_ALARM - shortest = data->set.timeout; /* default to this timeout value */ - if(shortest && data->set.connecttimeout && - (data->set.connecttimeout < shortest)) - /* if both are set, pick the shortest */ - shortest = data->set.connecttimeout; - else if(!shortest) - /* if timeout is not set, use the connect timeout */ - shortest = data->set.connecttimeout; - - if(shortest < 1000) - /* the alarm() function only provide integer second resolution, so if - we want to wait less than one second we must bail out already now. */ - return CURLE_OPERATION_TIMEDOUT; - - /* alarm() makes a signal get sent when the timeout fires off, and that - will abort system calls */ - prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest)); - /* We can expect the conn->created time to be "now", as that was just - recently set in the beginning of this function and nothing slow - has been done since then until now. */ -#endif -#endif /* SIGALRM */ - } -#endif /* USE_ARES */ - /************************************************************* - * Resolve the name of the server or proxy + * Resolve the address of the server or proxy *************************************************************/ - if(conn->bits.reuse) { - /* re-used connection, no resolving is necessary */ - hostaddr = NULL; - /* we'll need to clear conn->dns_entry later in Curl_disconnect() */ - - if(conn->bits.proxy) - fix_hostname(data, conn, &conn->host); - } - else { - /* this is a fresh connect */ - - /* set a pointer to the hostname we display */ - fix_hostname(data, conn, &conn->host); - - if(!conn->proxy.name || !*conn->proxy.name) { - /* 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 */ - - /* Resolve target host right on */ - rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - - else if(!hostaddr) { - failf(data, "Couldn't resolve host '%s'", conn->host.dispname); - result = CURLE_COULDNT_RESOLVE_HOST; - /* don't return yet, we need to clean up the timeout first */ - } - } - else { - /* This is a proxy that hasn't been resolved yet. */ - - /* IDN-fix the proxy name */ - fix_hostname(data, conn, &conn->proxy); - - /* resolve proxy */ - rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr); - - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - - else if(!hostaddr) { - failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); - result = CURLE_COULDNT_RESOLVE_PROXY; - /* don't return yet, we need to clean up the timeout first */ - } - } - } - *addr = hostaddr; - -#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) - if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { -#ifdef HAVE_SIGACTION - if(keep_copysig) { - /* we got a struct as it looked before, now put that one back nice - and clean */ - sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ - } -#else -#ifdef HAVE_SIGNAL - /* restore the previous SIGALRM handler */ - signal(SIGALRM, keep_sigact); -#endif -#endif /* HAVE_SIGACTION */ - - /* switch back the alarm() to either zero or to what it was before minus - the time we spent until now! */ - if(prev_alarm) { - /* there was an alarm() set before us, now put it back */ - unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); - unsigned long alarm_set; - - /* the alarm period is counted in even number of seconds */ - alarm_set = prev_alarm - elapsed_ms/1000; - - if(!alarm_set || - ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { - /* if the alarm time-left reached zero or turned "negative" (counted - with unsigned values), we should fire off a SIGALRM here, but we - won't, and zero would be to switch it off so we never set it to - less than 1! */ - alarm(1); - result = CURLE_OPERATION_TIMEDOUT; - failf(data, "Previous alarm fired off!"); - } - else - alarm((unsigned int)alarm_set); - } - else - alarm(0); /* just shut it off */ - } -#endif + result = resolve_server(data, conn, addr, async); return result; } -- cgit v1.2.1 From 9251dd7b2412214d3b25da666f7755a7ab207d39 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 1 Aug 2008 02:09:08 +0000 Subject: User names embedded in proxy URLs without a password were parsed incorrectly--the host name is treated as part of the user name and the port number becomes the password. This can be observed in test 279 (was KNOWN_ISSUE #54). --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b53cc5053..c77850794 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3396,7 +3396,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, proxypasswd[0] = 0; if(1 <= sscanf(proxyptr, - "%" MAX_CURL_USER_LENGTH_TXT"[^:]:" + "%" MAX_CURL_USER_LENGTH_TXT"[^:@]:" "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", proxyuser, proxypasswd)) { CURLcode res = CURLE_OK; -- cgit v1.2.1 From 019bde82ce8fd9d0a335edb30441088a96906d1b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 Aug 2008 19:26:01 +0000 Subject: - Constantine Sapuntzakis filed bug report #2042440 (http://curl.haxx.se/bug/view.cgi?id=2042440) with a patch. He identified a problem when using NTLM over a proxy but the end-point does Basic, and then libcurl would do wrong when the host sent "Connection: close" as the proxy's NTLM state was erroneously cleared. --- lib/url.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c77850794..76603494d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2179,22 +2179,31 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_expire(data, 0); /* shut off timers */ Curl_hostcache_prune(data); /* kill old DNS cache entries */ - if((conn->ntlm.state != NTLMSTATE_NONE) || - (conn->proxyntlm.state != NTLMSTATE_NONE)) { + { + int has_host_ntlm = (conn->ntlm.state != NTLMSTATE_NONE); + int has_proxy_ntlm = (conn->proxyntlm.state != NTLMSTATE_NONE); + /* Authentication data is a mix of connection-related and sessionhandle- related stuff. NTLM is connection-related so when we close the shop we shall forget. */ - data->state.authhost.done = FALSE; - data->state.authhost.picked = - data->state.authhost.want; - data->state.authproxy.done = FALSE; - data->state.authproxy.picked = - data->state.authproxy.want; + if (has_host_ntlm) { + data->state.authhost.done = FALSE; + data->state.authhost.picked = + data->state.authhost.want; + } + + if (has_proxy_ntlm) { + data->state.authproxy.done = FALSE; + data->state.authproxy.picked = + data->state.authproxy.want; + } - data->state.authproblem = FALSE; + if (has_host_ntlm || has_proxy_ntlm) { + data->state.authproblem = FALSE; - Curl_ntlm_cleanup(conn); + Curl_ntlm_cleanup(conn); + } } if(conn->handler->disconnect) -- cgit v1.2.1 From 66fb9ca5f6de6eb74c2c3ade7ee651a299247749 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 15 Aug 2008 02:58:15 +0000 Subject: For congruency sake with the naming of other CURL_XXXXXX_CURL_OFF_T macros, the names of the curl_off_t formatting string directives now become CURL_FORMAT_CURL_OFF_T and CURL_FORMAT_CURL_OFF_TU. CURL_FMT_OFF_T -> CURL_FORMAT_CURL_OFF_T CURL_FMT_OFF_TU -> CURL_FORMAT_CURL_OFF_TU Remove the use of an internal name for the curl_off_t formatting string directives and use the common one available from the inside and outside of the library. FORMAT_OFF_T -> CURL_FORMAT_CURL_OFF_T FORMAT_OFF_TU -> CURL_FORMAT_CURL_OFF_TU --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 76603494d..6dd79a08f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3185,7 +3185,7 @@ static CURLcode setup_range(struct SessionHandle *data) free(s->range); if(s->resume_from) - s->range = aprintf("%" FORMAT_OFF_TU "-", s->resume_from); + s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from); else s->range = strdup(data->set.str[STRING_SET_RANGE]); -- cgit v1.2.1 From ad638da2c29a61babb50fdced0333393416a199a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 16 Aug 2008 01:33:59 +0000 Subject: Library internal only C preprocessor macros FORMAT_OFF_T and FORMAT_OFF_TU remain in use as internal curl_off_t print formatting strings for the internal *printf functions which still cannot handle print formatting string directives such as "I64d", "I64u", and others available on MSVC, MinGW, Intel's ICC, and other DOS/Windows compilers. This reverts previous commit part which did: FORMAT_OFF_T -> CURL_FORMAT_CURL_OFF_T FORMAT_OFF_TU -> CURL_FORMAT_CURL_OFF_TU --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6dd79a08f..76603494d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3185,7 +3185,7 @@ static CURLcode setup_range(struct SessionHandle *data) free(s->range); if(s->resume_from) - s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from); + s->range = aprintf("%" FORMAT_OFF_TU "-", s->resume_from); else s->range = strdup(data->set.str[STRING_SET_RANGE]); -- cgit v1.2.1 From 17e1f58fd67d630390f6c6bce78e319e8a5831b9 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Thu, 21 Aug 2008 16:20:38 +0000 Subject: Work around a scanf() bug in djgpp 2.04. The assignments for this format is working okay. But the return value is incorrectly EOF. --- lib/url.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 76603494d..6da9c9ea0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2978,8 +2978,8 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, { char *at; char *tmp; - char *path = data->state.path; + int rc; /************************************************************* * Parse the URL. @@ -3052,13 +3052,20 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ - if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]", - conn->host.name, path)) ) { + if(1 > (rc = sscanf(data->change.url, "%[^\n/]%[^\n]", + conn->host.name, path)) ) { /* * We couldn't even get this format. + * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is + * assigned, but the return value is EOF! */ - failf(data, " malformed"); - return CURLE_URL_MALFORMAT; +#if defined(__DJGPP__) && (DJGPP_MINOR == 4) + if (!(rc == -1 && *conn->host.name)) +#endif + { + failf(data, " malformed"); + return CURLE_URL_MALFORMAT; + } } /* @@ -3161,7 +3168,7 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, * conn->host.name is B * data->state.path is /C */ - + (void)rc; return CURLE_OK; } @@ -3652,7 +3659,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; - bool isftp = strequal("ftp", conn->protostr) || + bool isftp = strequal("ftp", conn->protostr) || strequal("ftps", conn->protostr); /* @@ -3662,7 +3669,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, */ url = aprintf("%s://%s%s%s:%d%s%s", conn->protostr, conn->bits.ipv6_ip?"[":"", conn->host.name, - conn->bits.ipv6_ip?"]":"", conn->remote_port, + conn->bits.ipv6_ip?"]":"", conn->remote_port, isftp?"/":"", data->state.path); if(!url) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 4b01dfe369896a8a93a3c82228c755a03da731e9 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 26 Aug 2008 21:28:57 +0000 Subject: Fixed out of memory problems that caused torture test failures in tests 1021 and 1067. --- lib/url.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6da9c9ea0..41222f0ec 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2206,6 +2206,12 @@ CURLcode Curl_disconnect(struct connectdata *conn) } } + /* Cleanup possible redirect junk */ + if(data->req.newurl) { + free(data->req.newurl); + data->req.newurl = NULL; + } + if(conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ conn->handler->disconnect(conn); @@ -4483,7 +4489,7 @@ static CURLcode setup_conn(struct connectdata *conn, } #endif - return CURLE_OK; + return result; } CURLcode Curl_connect(struct SessionHandle *data, -- cgit v1.2.1 From 8ce78ca488f589d9b1987e7713f28f9da15cba0f Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 28 Aug 2008 06:28:07 +0000 Subject: Fixed test case 1065 by changing the handling of CURLOPT_UPLOAD to set the HTTP method to GET (or HEAD) when given a value of 0. --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 41222f0ec..a70b471b2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -888,6 +888,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(data->set.upload) /* If this is HTTP, PUT is what's needed to "upload" */ data->set.httpreq = HTTPREQ_PUT; + else + /* In HTTP, the opposite of upload is either GET or a HEAD */ + data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET; break; case CURLOPT_FILETIME: /* -- cgit v1.2.1 From 099b62f1246602af876f39f9155ddae2ef909181 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 28 Aug 2008 07:37:29 +0000 Subject: - Dengminwen reported that libcurl would lock a (cookie) share twice (without an unlock in between) for a certain case and that in fact works when using regular windows mutexes but not with pthreads'! Locks should of course not get locked again so this is now fixed. http://curl.haxx.se/mail/lib-2008-08/0422.html --- lib/url.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a70b471b2..da757a377 100644 --- a/lib/url.c +++ b/lib/url.c @@ -346,14 +346,16 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) static void flush_cookies(struct SessionHandle *data, int cleanup) { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); if(data->set.str[STRING_COOKIEJAR]) { if(data->change.cookielist) { /* If there is a list of cookie files to read, do it first so that - we have all the told files read before we write the new jar */ + we have all the told files read before we write the new jar. + Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */ Curl_cookie_loadfiles(data); } + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + /* if we have a destination file for all the cookies to get dumped to */ if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) infof(data, "WARNING: failed to save cookies in %s\n", @@ -364,6 +366,7 @@ static void flush_cookies(struct SessionHandle *data, int cleanup) /* since nothing is written, we can just free the list of cookie file names */ curl_slist_free_all(data->change.cookielist); /* clean up list */ + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); } if(cleanup && (!data->share || (data->cookies != data->share->cookies))) { -- cgit v1.2.1 From 934708d950617688c7d294ea1ab583667f383ab1 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 2 Sep 2008 17:41:20 +0000 Subject: Made some variables const which eliminated some casts --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index da757a377..57ffffe53 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2878,7 +2878,7 @@ static bool tld_check_name(struct SessionHandle *data, char *uc_name = NULL; int rc; #ifndef CURL_DISABLE_VERBOSE_STRINGS - char *tld_errmsg = (char *)""; + const char *tld_errmsg = ""; #else (void)data; #endif @@ -2892,7 +2892,7 @@ static bool tld_check_name(struct SessionHandle *data, #ifndef CURL_DISABLE_VERBOSE_STRINGS #ifdef HAVE_TLD_STRERROR if(rc != TLD_SUCCESS) - tld_errmsg = (char *)tld_strerror((Tld_rc)rc); + tld_errmsg = tld_strerror((Tld_rc)rc); #endif if(rc == TLD_INVALID) infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n", -- cgit v1.2.1 From 3dcd2b82c4095e34342c8d0778d45d547c23b06d Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 4 Sep 2008 18:59:05 +0000 Subject: fix print formatting string directives --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 57ffffe53..b000fe2e3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -411,7 +411,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "MAJOR problem we %p are still in send pipe for %p done %d\n", - data, connptr, connptr->bits.done); + data, connptr, (int)connptr->bits.done); } } } @@ -421,7 +421,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "MAJOR problem we %p are still in recv pipe for %p done %d\n", - data, connptr, connptr->bits.done); + data, connptr, (int)connptr->bits.done); } } } @@ -431,7 +431,7 @@ CURLcode Curl_close(struct SessionHandle *data) if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "MAJOR problem we %p are still in pend pipe for %p done %d\n", - data, connptr, connptr->bits.done); + data, connptr, (int)connptr->bits.done); } } } -- cgit v1.2.1 From 4c9768565ec3a9baf26ac8a547bca6e42cc64fa5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Sep 2008 14:29:21 +0000 Subject: - Introducing CURLOPT_CERTINFO and the corresponding CURLINFO_CERTINFO. By enabling this feature with CURLOPT_CERTINFO for a request using SSL (HTTPS or FTPS), libcurl will gather lots of server certificate info and that info can then get extracted by a client after the request has completed with curl_easy_getinfo()'s CURLINFO_CERTINFO option. Linus Nielsen Feltzing helped me test and smoothen out this feature. Unfortunately, this feature currently only works with libcurl built to use OpenSSL. This feature was sponsored by networking4all.com - thanks! --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b000fe2e3..d6dec0d0a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -481,6 +481,7 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_ssl_close_all(data); Curl_safefree(data->state.first_host); Curl_safefree(data->state.scratch); + Curl_ssl_free_certinfo(data); if(data->change.referer_alloc) free(data->change.referer); @@ -1800,6 +1801,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.ssl.fsslctxp = va_arg(param, void *); break; + case CURLOPT_CERTINFO: + data->set.ssl.certinfo = (bool)(0 != va_arg(param, long)); + break; #endif case CURLOPT_CAINFO: /* -- cgit v1.2.1 From 18110b519c56a464bca4258332279c580f07a52f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Sep 2008 16:13:20 +0000 Subject: - Martin Drasar provided the CURLOPT_POSTREDIR patch. It renames CURLOPT_POST301 (but adds a define for backwards compatibility for you who don't define CURL_NO_OLDIES). This option allows you to now also change the libcurl behavior for a HTTP response 302 after a POST to not use GET in the subsequent request (when CURLOPT_FOLLOWLOCATION is enabled). I edited the patch somewhat before commit. The curl tool got a matching --post302 option. Test case 1076 was added to verify this. --- lib/url.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d6dec0d0a..a51ba4394 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1028,12 +1028,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.maxredirs = va_arg(param, long); break; - case CURLOPT_POST301: + case CURLOPT_POSTREDIR: + { /* - * Obey RFC 2616/10.3.2 and resubmit a POST as a POST after a 301. + * Set the behaviour of POST when redirecting + * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 + * CURL_REDIR_POST_301 - POST is kept as POST after 301 + * CURL_REDIR_POST_302 - POST is kept as POST after 302 + * CURL_REDIR_POST_ALL - POST is kept as POST after 301 and 302 + * other - POST is kept as POST after 301 and 302 */ - data->set.post301 = (bool)(0 != va_arg(param, long)); - break; + long postRedir = va_arg(param, long); + data->set.post301 = (postRedir & CURL_REDIR_POST_301)?1:0; + data->set.post302 = (postRedir & CURL_REDIR_POST_302)?1:0; + } + break; case CURLOPT_POST: /* Does this option serve a purpose anymore? Yes it does, when @@ -2200,13 +2209,13 @@ CURLcode Curl_disconnect(struct connectdata *conn) if (has_host_ntlm) { data->state.authhost.done = FALSE; data->state.authhost.picked = - data->state.authhost.want; + data->state.authhost.want; } if (has_proxy_ntlm) { data->state.authproxy.done = FALSE; data->state.authproxy.picked = - data->state.authproxy.want; + data->state.authproxy.want; } if (has_host_ntlm || has_proxy_ntlm) { -- cgit v1.2.1 From 91ff93803512e3438ce165b23bb5b9fb404df288 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 5 Sep 2008 17:58:53 +0000 Subject: Improved the logic the decides whether to use HTTP 1.1 features or not in a request. Detect cases where an upload must be sent chunked and the server supports only HTTP 1.0 and return CURLE_UPLOAD_FAILED. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a51ba4394..cf661f2aa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4689,7 +4689,8 @@ CURLcode Curl_done(struct connectdata **connp, * do_init() inits the readwrite session. This is inited each time (in the DO * function before the protocol-specific DO functions are invoked) for a * transfer, sometimes multiple times on the same SessionHandle. Make sure - * nothing in here depends on stuff that are setup dynamicly for the transfer. + * nothing in here depends on stuff that are setup dynamically for the + * transfer. */ static CURLcode do_init(struct connectdata *conn) @@ -4706,7 +4707,6 @@ static CURLcode do_init(struct connectdata *conn) k->start = Curl_tvnow(); /* start time */ k->now = k->start; /* current time is now */ k->header = TRUE; /* assume header */ - k->httpversion = -1; /* unknown at this point */ k->bytecount = 0; -- cgit v1.2.1 From 861b647e7b1da564b831a5b07312a30feb7b6c58 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Sep 2008 04:28:43 +0000 Subject: remove unnecessary typecasting of realloc() --- lib/url.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cf661f2aa..7bd812628 100644 --- a/lib/url.c +++ b/lib/url.c @@ -602,8 +602,7 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, data->state.lastconnect = -1; } if(newamount > 0) { - newptr= (struct connectdata **) - realloc(c->connects, sizeof(struct connectdata *) * newamount); + newptr = realloc(c->connects, sizeof(struct connectdata *) * newamount); if(!newptr) /* we closed a few connections in vain, but so what? */ return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From a622fd90b4c563a4fced20c5b88cb57537e809b0 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Sep 2008 04:47:14 +0000 Subject: remove unnecessary typecasting of calloc() --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7bd812628..8b4bdaeca 100644 --- a/lib/url.c +++ b/lib/url.c @@ -651,7 +651,7 @@ CURLcode Curl_open(struct SessionHandle **curl) #endif /* Very simple start-up: alloc the struct, init it with zeroes and return */ - data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle)); + data = calloc(1, sizeof(struct SessionHandle)); if(!data) { /* this is a very serious error */ DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n")); @@ -2969,7 +2969,7 @@ static struct connectdata *allocate_conn(void) { struct connectdata *conn; - conn = (struct connectdata *)calloc(1, sizeof(struct connectdata)); + conn = calloc(1, sizeof(struct connectdata)); if(!conn) return NULL; -- cgit v1.2.1 From 59e378f48fed849e8e41f0bc6a10bf7a1732ae8a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Sep 2008 05:29:05 +0000 Subject: remove unnecessary typecasting of malloc() --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8b4bdaeca..197548a12 100644 --- a/lib/url.c +++ b/lib/url.c @@ -675,7 +675,7 @@ CURLcode Curl_open(struct SessionHandle **curl) /* We do some initial setup here, all those fields that can't be just 0 */ - data->state.headerbuff=(char*)malloc(HEADERSIZE); + data->state.headerbuff = malloc(HEADERSIZE); if(!data->state.headerbuff) { DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); res = CURLE_OUT_OF_MEMORY; @@ -4154,12 +4154,12 @@ static CURLcode create_conn(struct SessionHandle *data, */ Curl_safefree(data->state.pathbuffer); - data->state.pathbuffer=(char *)malloc(urllen+2); + data->state.pathbuffer = malloc(urllen+2); if(NULL == data->state.pathbuffer) return CURLE_OUT_OF_MEMORY; /* really bad error */ data->state.path = data->state.pathbuffer; - conn->host.rawalloc=(char *)malloc(urllen+2); + conn->host.rawalloc = malloc(urllen+2); if(NULL == conn->host.rawalloc) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 2ef72f7abb0f955d08a7f26d1a65a21be26b1af9 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 8 Sep 2008 19:34:58 +0000 Subject: fix compiler warning --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 197548a12..a79ab9d78 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1038,8 +1038,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * other - POST is kept as POST after 301 and 302 */ long postRedir = va_arg(param, long); - data->set.post301 = (postRedir & CURL_REDIR_POST_301)?1:0; - data->set.post302 = (postRedir & CURL_REDIR_POST_302)?1:0; + data->set.post301 = (bool)((postRedir & CURL_REDIR_POST_301)?TRUE:FALSE); + data->set.post302 = (bool)((postRedir & CURL_REDIR_POST_302)?TRUE:FALSE); } break; @@ -3683,8 +3683,8 @@ static CURLcode parse_remote_port(struct SessionHandle *data, if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; - bool isftp = strequal("ftp", conn->protostr) || - strequal("ftps", conn->protostr); + bool isftp = (bool)(strequal("ftp", conn->protostr) || + strequal("ftps", conn->protostr)); /* * This synthesized URL isn't always right--suffixes like ;type=A -- cgit v1.2.1 From a6c915aab98a51b69a77a23ebe1ad8eaf0fd251f Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 18 Sep 2008 16:21:09 +0000 Subject: fix compiler warning: external declaration in primary source file --- lib/url.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a79ab9d78..15c5cc7a4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -184,10 +184,6 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); #ifndef WIN32 /* not for WIN32 builds */ -#ifdef HAVE_SIGSETJMP -extern sigjmp_buf curl_jmpenv; -#endif - #ifdef SIGALRM static RETSIGTYPE alarmfunc(int sig) -- cgit v1.2.1 From dfa0fd5b3348d1f94a97960e2d3b4f7910eebfa3 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 19 Sep 2008 00:43:51 +0000 Subject: Don't bother to install a SIGALRM handler unless alarm() is available. Also, leave the existing SIGALRM handler alone if the timeout is too small to handle. --- lib/url.c | 69 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 15c5cc7a4..cd5c983e0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -185,6 +185,11 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); /* not for WIN32 builds */ #ifdef SIGALRM +/* + * This signal handler jumps back into the main libcurl code and continues + * execution. This effectively causes the remainder of the application to run + * within a signal handler which is nonportable and could lead to problems. + */ static RETSIGTYPE alarmfunc(int sig) { @@ -3796,8 +3801,8 @@ static CURLcode resolve_server(struct SessionHandle *data, bool *async) { CURLcode result=CURLE_OK; -#ifndef USE_ARES -#ifdef SIGALRM + +#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) #ifdef HAVE_SIGACTION struct sigaction keep_sigact; /* store the old struct here */ bool keep_copysig=FALSE; /* did copy it? */ @@ -3806,45 +3811,16 @@ static CURLcode resolve_server(struct SessionHandle *data, void (*keep_sigact)(int); /* store the old handler here */ #endif /* HAVE_SIGNAL */ #endif /* HAVE_SIGACTION */ -#endif /* SIGALRM */ -#endif /* USE_ARES */ -#if defined(HAVE_ALARM) && !defined(USE_ARES) unsigned int prev_alarm=0; -#endif -#ifndef USE_ARES /************************************************************* * Set timeout if that is being used, and we're not using an asynchronous * name resolve. *************************************************************/ if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { - /************************************************************* - * Set signal handler to catch SIGALRM - * Store the old value to be able to set it back later! - *************************************************************/ - -#ifdef SIGALRM -#ifdef HAVE_ALARM - long shortest; -#endif #ifdef HAVE_SIGACTION struct sigaction sigact; - sigaction(SIGALRM, NULL, &sigact); - keep_sigact = sigact; - keep_copysig = TRUE; /* yes, we have a copy */ - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - /* now set the new struct */ - sigaction(SIGALRM, &sigact, NULL); -#else /* HAVE_SIGACTION */ - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - keep_sigact = signal(SIGALRM, alarmfunc); -#endif #endif /* HAVE_SIGACTION */ /* We set the timeout on the name resolving phase first, separately from @@ -3852,8 +3828,7 @@ static CURLcode resolve_server(struct SessionHandle *data, * a signal-based timeout, why it won't work and shouldn't be used in * multi-threaded environments. */ -#ifdef HAVE_ALARM - shortest = data->set.timeout; /* default to this timeout value */ + long shortest = data->set.timeout; /* default to this timeout value */ if(shortest && data->set.connecttimeout && (data->set.connecttimeout < shortest)) /* if both are set, pick the shortest */ @@ -3867,16 +3842,36 @@ static CURLcode resolve_server(struct SessionHandle *data, we want to wait less than one second we must bail out already now. */ return CURLE_OPERATION_TIMEDOUT; + /************************************************************* + * Set signal handler to catch SIGALRM + * Store the old value to be able to set it back later! + *************************************************************/ +#ifdef HAVE_SIGACTION + sigaction(SIGALRM, NULL, &sigact); + keep_sigact = sigact; + keep_copysig = TRUE; /* yes, we have a copy */ + sigact.sa_handler = alarmfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; +#endif + /* now set the new struct */ + sigaction(SIGALRM, &sigact, NULL); +#else /* HAVE_SIGACTION */ + /* no sigaction(), revert to the much lamer signal() */ +#ifdef HAVE_SIGNAL + keep_sigact = signal(SIGALRM, alarmfunc); +#endif +#endif /* HAVE_SIGACTION */ + /* alarm() makes a signal get sent when the timeout fires off, and that will abort system calls */ prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest)); /* We can expect the conn->created time to be "now", as that was just recently set in the beginning of this function and nothing slow has been done since then until now. */ -#endif -#endif /* SIGALRM */ } -#endif /* USE_ARES */ +#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */ /************************************************************* * Resolve the name of the server or proxy @@ -3975,7 +3970,7 @@ static CURLcode resolve_server(struct SessionHandle *data, else alarm(0); /* just shut it off */ } -#endif +#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */ return result; } -- cgit v1.2.1 From 459e67b2a7290bc57dec773756d24d4503ac6d48 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Fri, 19 Sep 2008 17:46:59 +0000 Subject: Only define alarmfunc when signals are used --- lib/url.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cd5c983e0..7cfe7cc0a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -150,10 +150,6 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by /* The last #include file should be: */ #include "memdebug.h" -#ifdef __SYMBIAN32__ -#undef SIGALRM -#endif - /* Local static prototypes */ static long ConnectionKillOne(struct SessionHandle *data); static bool ConnectionExists(struct SessionHandle *data, @@ -178,13 +174,10 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); #define verboseconnect(x) do { } while (0) #endif -#ifndef USE_ARES -/* not for ares builds */ - #ifndef WIN32 /* not for WIN32 builds */ -#ifdef SIGALRM +#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) /* * This signal handler jumps back into the main libcurl code and continues * execution. This effectively causes the remainder of the application to run @@ -200,9 +193,8 @@ RETSIGTYPE alarmfunc(int sig) #endif return; } -#endif /* SIGALRM */ +#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */ #endif /* WIN32 */ -#endif /* USE_ARES */ /* * Protocol table. -- cgit v1.2.1 From 515893595dafd99d83c1603533524076742aaa51 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 24 Sep 2008 01:08:01 +0000 Subject: Make sure not to dereference the wrong UrlState proto union member when switching from one protocol to another in a single request (e.g. redirecting from HTTP to FTP as in test 1055) by resetting state.expect100header before every request. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7cfe7cc0a..352ec20c7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4682,6 +4682,7 @@ static CURLcode do_init(struct connectdata *conn) conn->bits.done = FALSE; /* Curl_done() is not called yet */ conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ + data->state.expect100header = FALSE; /* NB: the content encoding software depends on this initialization */ Curl_easy_initHandleData(data); -- cgit v1.2.1 From 4e909ee8b1e7e9f174af629615224180568a7e92 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 24 Sep 2008 12:22:16 +0000 Subject: ntoa() and inet_ntoa_r() no longer used --- lib/url.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 352ec20c7..53e2bf7e0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -138,15 +138,10 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "http_ntlm.h" #include "socks.h" -#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) -#include "inet_ntoa_r.h" -#endif - #define _MPRINTF_REPLACE /* use our functions only */ #include #include "memory.h" - /* The last #include file should be: */ #include "memdebug.h" -- cgit v1.2.1 From 4adcf7e9ed32ed055470a17f715ee222285c1308 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 29 Sep 2008 21:02:22 +0000 Subject: Moved all signal-based name resolution timeout handling into a single new Curl_resolv_timeout function to reduce coupling. --- lib/url.c | 143 ++++++++------------------------------------------------------ 1 file changed, 17 insertions(+), 126 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 53e2bf7e0..df3e3cafc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -60,9 +60,6 @@ #ifdef HAVE_SYS_IOCTL_H #include #endif -#ifdef HAVE_SIGNAL_H -#include -#endif #ifdef HAVE_SYS_PARAM_H #include @@ -73,10 +70,6 @@ #include #endif -#ifdef HAVE_SETJMP_H -#include -#endif - #ifndef HAVE_SOCKET #error "We can't compile without socket() support!" #endif @@ -169,27 +162,6 @@ static void flush_cookies(struct SessionHandle *data, int cleanup); #define verboseconnect(x) do { } while (0) #endif -#ifndef WIN32 -/* not for WIN32 builds */ - -#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) -/* - * This signal handler jumps back into the main libcurl code and continues - * execution. This effectively causes the remainder of the application to run - * within a signal handler which is nonportable and could lead to problems. - */ -static -RETSIGTYPE alarmfunc(int sig) -{ - /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ - (void)sig; -#ifdef HAVE_SIGSETJMP - siglongjmp(curl_jmpenv, 1); -#endif - return; -} -#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */ -#endif /* WIN32 */ /* * Protocol table. @@ -3788,34 +3760,19 @@ static CURLcode resolve_server(struct SessionHandle *data, bool *async) { CURLcode result=CURLE_OK; - -#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) -#ifdef HAVE_SIGACTION - struct sigaction keep_sigact; /* store the old struct here */ - bool keep_copysig=FALSE; /* did copy it? */ -#else -#ifdef HAVE_SIGNAL - void (*keep_sigact)(int); /* store the old handler here */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ - - unsigned int prev_alarm=0; + long shortest = 0; /* default to no timeout */ /************************************************************* - * Set timeout if that is being used, and we're not using an asynchronous - * name resolve. + * Set timeout if that is being used *************************************************************/ - if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { -#ifdef HAVE_SIGACTION - struct sigaction sigact; -#endif /* HAVE_SIGACTION */ + if(data->set.timeout || data->set.connecttimeout) { /* We set the timeout on the name resolving phase first, separately from * the download/upload part to allow a maximum time on everything. This is * a signal-based timeout, why it won't work and shouldn't be used in * multi-threaded environments. */ - long shortest = data->set.timeout; /* default to this timeout value */ + shortest = data->set.timeout; /* default to this timeout value */ if(shortest && data->set.connecttimeout && (data->set.connecttimeout < shortest)) /* if both are set, pick the shortest */ @@ -3823,42 +3780,10 @@ static CURLcode resolve_server(struct SessionHandle *data, else if(!shortest) /* if timeout is not set, use the connect timeout */ shortest = data->set.connecttimeout; - - if(shortest < 1000) - /* the alarm() function only provide integer second resolution, so if - we want to wait less than one second we must bail out already now. */ - return CURLE_OPERATION_TIMEDOUT; - - /************************************************************* - * Set signal handler to catch SIGALRM - * Store the old value to be able to set it back later! - *************************************************************/ -#ifdef HAVE_SIGACTION - sigaction(SIGALRM, NULL, &sigact); - keep_sigact = sigact; - keep_copysig = TRUE; /* yes, we have a copy */ - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - /* now set the new struct */ - sigaction(SIGALRM, &sigact, NULL); -#else /* HAVE_SIGACTION */ - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - keep_sigact = signal(SIGALRM, alarmfunc); -#endif -#endif /* HAVE_SIGACTION */ - - /* alarm() makes a signal get sent when the timeout fires off, and that - will abort system calls */ - prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest)); - /* We can expect the conn->created time to be "now", as that was just - recently set in the beginning of this function and nothing slow - has been done since then until now. */ + /* We can expect the conn->created time to be "now", as that was just + recently set in the beginning of this function and nothing slow + has been done since then until now. */ } -#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */ /************************************************************* * Resolve the name of the server or proxy @@ -3885,10 +3810,14 @@ static CURLcode resolve_server(struct SessionHandle *data, conn->port = conn->remote_port; /* it is the same port */ /* Resolve target host right on */ - rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr); + rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port, + &hostaddr, shortest); if(rc == CURLRESOLV_PENDING) *async = TRUE; + else if (rc == CURLRESOLV_TIMEDOUT) + result = CURLE_OPERATION_TIMEDOUT; + else if(!hostaddr) { failf(data, "Couldn't resolve host '%s'", conn->host.dispname); result = CURLE_COULDNT_RESOLVE_HOST; @@ -3902,11 +3831,15 @@ static CURLcode resolve_server(struct SessionHandle *data, fix_hostname(data, conn, &conn->proxy); /* resolve proxy */ - rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr); + rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port, + &hostaddr, shortest); if(rc == CURLRESOLV_PENDING) *async = TRUE; + else if (rc == CURLRESOLV_TIMEDOUT) + result = CURLE_OPERATION_TIMEDOUT; + else if(!hostaddr) { failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); result = CURLE_COULDNT_RESOLVE_PROXY; @@ -3916,48 +3849,6 @@ static CURLcode resolve_server(struct SessionHandle *data, *addr = hostaddr; } -#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES) - if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) { -#ifdef HAVE_SIGACTION - if(keep_copysig) { - /* we got a struct as it looked before, now put that one back nice - and clean */ - sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ - } -#else -#ifdef HAVE_SIGNAL - /* restore the previous SIGALRM handler */ - signal(SIGALRM, keep_sigact); -#endif -#endif /* HAVE_SIGACTION */ - - /* switch back the alarm() to either zero or to what it was before minus - the time we spent until now! */ - if(prev_alarm) { - /* there was an alarm() set before us, now put it back */ - unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); - unsigned long alarm_set; - - /* the alarm period is counted in even number of seconds */ - alarm_set = prev_alarm - elapsed_ms/1000; - - if(!alarm_set || - ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { - /* if the alarm time-left reached zero or turned "negative" (counted - with unsigned values), we should fire off a SIGALRM here, but we - won't, and zero would be to switch it off so we never set it to - less than 1! */ - alarm(1); - result = CURLE_OPERATION_TIMEDOUT; - failf(data, "Previous alarm fired off!"); - } - else - alarm((unsigned int)alarm_set); - } - else - alarm(0); /* just shut it off */ - } -#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */ return result; } -- cgit v1.2.1 From f3ab5d5500f81b052e215b60fe55dcf88fe6635f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 Sep 2008 21:46:04 +0000 Subject: - Daniel Egger provided a patch that allows you to disable proxy support in libcurl to somewhat reduce the size of the binary. Run configure --disable-proxy. --- lib/url.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index df3e3cafc..51bfbf6a7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2666,17 +2666,14 @@ static CURLcode ConnectPlease(struct SessionHandle *data, result = Curl_store_ip_addr(conn); if(CURLE_OK == result) { - switch(data->set.proxytype) { +#ifndef CURL_DISABLE_PROXY case CURLPROXY_SOCKS5: case CURLPROXY_SOCKS5_HOSTNAME: result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn->host.name, conn->remote_port, FIRSTSOCKET, conn); break; - case CURLPROXY_HTTP: - /* do nothing here. handled later. */ - break; case CURLPROXY_SOCKS4: result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, FIRSTSOCKET, conn, FALSE); @@ -2685,6 +2682,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data, result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, FIRSTSOCKET, conn, TRUE); break; +#endif /* CURL_DISABLE_PROXY */ + case CURLPROXY_HTTP: + /* do nothing here. handled later. */ + break; default: failf(data, "unknown proxytype option given"); result = CURLE_COULDNT_CONNECT; @@ -3237,6 +3238,7 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } +#ifndef CURL_DISABLE_PROXY /**************************************************************** * Detect what (if any) proxy to use. Remember that this selects a host * name and is not limited to HTTP proxies only. @@ -3513,6 +3515,7 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, return CURLE_OK; } +#endif /* CURL_DISABLE_PROXY */ /* * @@ -4040,6 +4043,7 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } +#ifndef CURL_DISABLE_PROXY /************************************************************* * Extract the user and password from the authentication string *************************************************************/ @@ -4068,6 +4072,7 @@ static CURLcode create_conn(struct SessionHandle *data, proxy = NULL; } /* proxy must be freed later unless NULL */ +#endif /* CURL_DISABLE_PROXY */ /************************************************************* * No protocol part in URL was used, add it! -- cgit v1.2.1 From 2393c943632f78ed38122d24b7d0535fffe6efa3 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 29 Sep 2008 22:45:25 +0000 Subject: Fixed a compile problem with --disable-proxy --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 51bfbf6a7..bb09d2fd3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4105,6 +4105,7 @@ static CURLcode create_conn(struct SessionHandle *data, } +#ifndef CURL_DISABLE_PROXY /*********************************************************************** * If this is supposed to use a proxy, we need to figure out the proxy * host name, so that we can re-use an existing connection @@ -4117,6 +4118,7 @@ static CURLcode create_conn(struct SessionHandle *data, if(result != CURLE_OK) return result; } +#endif /* CURL_DISABLE_PROXY */ /*********************************************************************** * file: is a special case in that it doesn't need a network connection -- cgit v1.2.1 From 61cfbecc7458edd4cc2d538d0a361648131a2c93 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 7 Oct 2008 21:56:56 +0000 Subject: - Fixed CURLINFO_PRIMARY_IP: When libcurl created a connection to host A then the app re-used the handle to do a connection to host B and then again re-used the handle to host A, it would not update the info with host A's IP address (due to the connection being re-used) but it would instead report the info from host B. --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bb09d2fd3..17b34c68e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4238,6 +4238,12 @@ static CURLcode create_conn(struct SessionHandle *data, infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->proxy.name?conn->proxy.dispname:conn->host.dispname); + /* copy this IP address to the common buffer for the easy handle so that + the address can actually survice the removal of this connection. strcpy + is safe since the target buffer is big enough to hold the largest + possible IP address */ + strcpy(data->info.ip, conn->ip_addr_str); + } else { /* -- cgit v1.2.1 From 08cf6780ba8ea242cb451f07e14bb572079e22cf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 8 Oct 2008 10:39:43 +0000 Subject: - Igor Novoseltsev brought a patch that introduced two new options to curl_easy_setopt: CURLOPT_USERNAME and CURLOPT_PASSWORD that sort of deprecates the good old CURLOPT_USERPWD since they allow applications to set the user name and password independently and perhaps more importantly allow both to contain colon(s) which CURLOPT_USERPWD doesn't fully support. --- lib/url.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 17b34c68e..a1174a63b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1500,7 +1500,45 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password to use in the operation */ - result = setstropt(&data->set.str[STRING_USERPWD], + { + char* userpwd = va_arg(param, char *); + char* separator = strchr(userpwd, ':'); + if (separator != NULL) { + + /* store username part of option */ + char * p; + size_t username_len = (size_t)(separator-userpwd); + p = malloc(username_len+1); + if(!p) + result = CURLE_OUT_OF_MEMORY; + else { + memcpy(p, userpwd, username_len); + p[username_len] = '\0'; + data->set.str[STRING_USERNAME] = p; + } + + /* store password part of option */ + if (result == CURLE_OK) { + result = setstropt(&data->set.str[STRING_PASSWORD], separator+1); + } + } + else { + result = setstropt(&data->set.str[STRING_USERNAME], userpwd); + } + } + break; + case CURLOPT_USERNAME: + /* + * user:password to use in the operation + */ + result = setstropt(&data->set.str[STRING_USERNAME], + va_arg(param, char *)); + break; + case CURLOPT_PASSWORD: + /* + * user:password to use in the operation + */ + result = setstropt(&data->set.str[STRING_PASSWORD], va_arg(param, char *)); break; case CURLOPT_POSTQUOTE: @@ -3701,12 +3739,13 @@ static void override_userpass(struct SessionHandle *data, struct connectdata *conn, char *user, char *passwd) { - if(data->set.str[STRING_USERPWD] != NULL) { - /* the name is given, get user+password */ - sscanf(data->set.str[STRING_USERPWD], - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - user, passwd); + if(data->set.str[STRING_USERNAME] != NULL) { + strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH); + user[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ + } + if(data->set.str[STRING_PASSWORD] != NULL) { + strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH); + passwd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ } conn->bits.netrc = FALSE; @@ -3985,7 +4024,7 @@ static CURLcode create_conn(struct SessionHandle *data, && (conn->proxytype == CURLPROXY_HTTP)); - conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]); + conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; -- cgit v1.2.1 From 4754880099059865cad14f54af683bf416ad4439 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 8 Oct 2008 18:32:06 +0000 Subject: fix missing null-pointer check --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a1174a63b..fe32cba77 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1501,8 +1501,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * user:password to use in the operation */ { - char* userpwd = va_arg(param, char *); - char* separator = strchr(userpwd, ':'); + char* userpwd; + char* separator; + + userpwd = va_arg(param, char *); + if(userpwd == NULL) + break; + + separator = strchr(userpwd, ':'); if (separator != NULL) { /* store username part of option */ -- cgit v1.2.1 From 450348d6bd8a9d0fc22eb53f066443b5d0180113 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 8 Oct 2008 20:14:46 +0000 Subject: Fixed a memory leak in the new CURLOPT_USERPWD handling --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fe32cba77..cfaab0601 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1520,6 +1520,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, else { memcpy(p, userpwd, username_len); p[username_len] = '\0'; + Curl_safefree(data->set.str[STRING_USERNAME]); data->set.str[STRING_USERNAME] = p; } -- cgit v1.2.1 From bb1f6e681830aba56db14c84512af371877f8601 Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Fri, 10 Oct 2008 15:54:07 +0000 Subject: _ Adapt OS400 EBCDIC wrappers to new options. _ Update RPG binding accordingly. _ Fix new options comments. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cfaab0601..e22ddee6e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1536,14 +1536,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_USERNAME: /* - * user:password to use in the operation + * authentication user name to use in the operation */ result = setstropt(&data->set.str[STRING_USERNAME], va_arg(param, char *)); break; case CURLOPT_PASSWORD: /* - * user:password to use in the operation + * authentication password to use in the operation */ result = setstropt(&data->set.str[STRING_PASSWORD], va_arg(param, char *)); -- cgit v1.2.1 From ad61b58036bf2b64916b4a66f46f393c68da872c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 14 Oct 2008 02:35:39 +0000 Subject: fix compiler warning --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e22ddee6e..d1393d2e6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3176,13 +3176,13 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, char *percent = strstr (conn->host.name, "%25"); if (percent) { char *endp; - unsigned int scope = strtoul (percent + 3, &endp, 10); + unsigned long scope = strtoul (percent + 3, &endp, 10); if (*endp == ']') { /* The address scope was well formed. Knock it out of the hostname. */ memmove(percent, endp, strlen(endp)+1); if (!data->state.this_is_a_follow) /* Don't honour a scope given in a Location: header */ - conn->scope = scope; + conn->scope = (unsigned int)scope; } else infof(data, "Invalid IPv6 address format\n"); } -- cgit v1.2.1 From a579d6706436615845f57692921e0891fb6e3719 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 15 Oct 2008 21:43:48 +0000 Subject: - Pascal Terjan filed bug #2154627 (http://curl.haxx.se/bug/view.cgi?id=2154627) which pointed out that libcurl uses strcasecmp() in multiple places where it causes failures when the Turkish locale is used. This is because 'i' and 'I' isn't the same letter so strcasecmp() on those letters are different in Turkish than in English (or just about all other languages). I thus introduced a totally new internal function in libcurl (called Curl_ascii_equal) for doing case insentive comparisons for english-(ascii?) style strings that thus will make "file" and "FILE" match even if the Turkish locale is selected. --- lib/url.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d1393d2e6..448133c6d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1216,17 +1216,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(argptr == NULL) break; - if(strequal(argptr, "ALL")) { + if(Curl_ascii_equal(argptr, "ALL")) { /* clear all cookies */ Curl_cookie_clearall(data->cookies); break; } - else if(strequal(argptr, "SESS")) { + else if(Curl_ascii_equal(argptr, "SESS")) { /* clear session cookies */ Curl_cookie_clearsess(data->cookies); break; } - else if(strequal(argptr, "FLUSH")) { + else if(Curl_ascii_equal(argptr, "FLUSH")) { /* flush cookies to file */ flush_cookies(data, 0); break; @@ -2496,14 +2496,14 @@ ConnectionExists(struct SessionHandle *data, if(!needle->bits.httpproxy || needle->protocol&PROT_SSL || (needle->bits.httpproxy && check->bits.httpproxy && needle->bits.tunnel_proxy && check->bits.tunnel_proxy && - strequal(needle->proxy.name, check->proxy.name) && + Curl_ascii_equal(needle->proxy.name, check->proxy.name) && (needle->port == check->port))) { /* The requested connection does not use a HTTP proxy or it uses SSL or it is a non-SSL protocol tunneled over the same http proxy name and port number */ - if(strequal(needle->protostr, check->protostr) && - strequal(needle->host.name, check->host.name) && + if(Curl_ascii_equal(needle->protostr, check->protostr) && + Curl_ascii_equal(needle->host.name, check->host.name) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same @@ -2542,7 +2542,7 @@ ConnectionExists(struct SessionHandle *data, is the checked one using the same host, port and type? */ if(check->bits.proxy && (needle->proxytype == check->proxytype) && - strequal(needle->proxy.name, check->proxy.name) && + Curl_ascii_equal(needle->proxy.name, check->proxy.name) && needle->port == check->port) { /* This is the same proxy connection, use it! */ match = TRUE; @@ -3021,7 +3021,7 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, ************************************************************/ if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", conn->protostr, - path)) && strequal(conn->protostr, "file")) { + path)) && Curl_ascii_equal(conn->protostr, "file")) { if(path[0] == '/' && path[1] == '/') { /* Allow omitted hostname (e.g. file:/). This is not strictly * speaking a valid file: URL by RFC 1738, but treating file:/ as @@ -3256,7 +3256,7 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, /* Scan protocol handler table. */ for (pp = protocols; (p = *pp) != NULL; pp++) - if(strequal(p->scheme, conn->protostr)) { + if(Curl_ascii_equal(p->scheme, conn->protostr)) { /* Protocol found in table. Perform setup complement if some. */ conn->handler = p; @@ -3370,7 +3370,7 @@ static char *detect_proxy(struct connectdata *conn) * This can cause 'internal' http/ftp requests to be * arbitrarily redirected by any external attacker. */ - if(!prox && !strequal("http_proxy", proxy_env)) { + if(!prox && !Curl_ascii_equal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ for(envp = proxy_env; *envp; envp++) *envp = (char)toupper((int)*envp); @@ -3691,8 +3691,8 @@ static CURLcode parse_remote_port(struct SessionHandle *data, if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; - bool isftp = (bool)(strequal("ftp", conn->protostr) || - strequal("ftps", conn->protostr)); + bool isftp = (bool)(Curl_ascii_equal("ftp", conn->protostr) || + Curl_ascii_equal("ftps", conn->protostr)); /* * This synthesized URL isn't always right--suffixes like ;type=A -- cgit v1.2.1 From 9d16b4081ed011c11f9876ae2685076e92113593 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Oct 2008 08:23:48 +0000 Subject: Renamed Curl_ascii_equal to Curl_raw_equal and bugfixed the my_toupper function used in strequal.c so now all test cases run fine for me again. --- lib/url.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 448133c6d..0f007fa39 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1216,17 +1216,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(argptr == NULL) break; - if(Curl_ascii_equal(argptr, "ALL")) { + if(Curl_raw_equal(argptr, "ALL")) { /* clear all cookies */ Curl_cookie_clearall(data->cookies); break; } - else if(Curl_ascii_equal(argptr, "SESS")) { + else if(Curl_raw_equal(argptr, "SESS")) { /* clear session cookies */ Curl_cookie_clearsess(data->cookies); break; } - else if(Curl_ascii_equal(argptr, "FLUSH")) { + else if(Curl_raw_equal(argptr, "FLUSH")) { /* flush cookies to file */ flush_cookies(data, 0); break; @@ -2496,14 +2496,14 @@ ConnectionExists(struct SessionHandle *data, if(!needle->bits.httpproxy || needle->protocol&PROT_SSL || (needle->bits.httpproxy && check->bits.httpproxy && needle->bits.tunnel_proxy && check->bits.tunnel_proxy && - Curl_ascii_equal(needle->proxy.name, check->proxy.name) && + Curl_raw_equal(needle->proxy.name, check->proxy.name) && (needle->port == check->port))) { /* The requested connection does not use a HTTP proxy or it uses SSL or it is a non-SSL protocol tunneled over the same http proxy name and port number */ - if(Curl_ascii_equal(needle->protostr, check->protostr) && - Curl_ascii_equal(needle->host.name, check->host.name) && + if(Curl_raw_equal(needle->protostr, check->protostr) && + Curl_raw_equal(needle->host.name, check->host.name) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same @@ -2542,7 +2542,7 @@ ConnectionExists(struct SessionHandle *data, is the checked one using the same host, port and type? */ if(check->bits.proxy && (needle->proxytype == check->proxytype) && - Curl_ascii_equal(needle->proxy.name, check->proxy.name) && + Curl_raw_equal(needle->proxy.name, check->proxy.name) && needle->port == check->port) { /* This is the same proxy connection, use it! */ match = TRUE; @@ -3021,7 +3021,7 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, ************************************************************/ if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", conn->protostr, - path)) && Curl_ascii_equal(conn->protostr, "file")) { + path)) && Curl_raw_equal(conn->protostr, "file")) { if(path[0] == '/' && path[1] == '/') { /* Allow omitted hostname (e.g. file:/). This is not strictly * speaking a valid file: URL by RFC 1738, but treating file:/ as @@ -3256,7 +3256,7 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, /* Scan protocol handler table. */ for (pp = protocols; (p = *pp) != NULL; pp++) - if(Curl_ascii_equal(p->scheme, conn->protostr)) { + if(Curl_raw_equal(p->scheme, conn->protostr)) { /* Protocol found in table. Perform setup complement if some. */ conn->handler = p; @@ -3370,7 +3370,7 @@ static char *detect_proxy(struct connectdata *conn) * This can cause 'internal' http/ftp requests to be * arbitrarily redirected by any external attacker. */ - if(!prox && !Curl_ascii_equal("http_proxy", proxy_env)) { + if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ for(envp = proxy_env; *envp; envp++) *envp = (char)toupper((int)*envp); @@ -3691,8 +3691,8 @@ static CURLcode parse_remote_port(struct SessionHandle *data, if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; - bool isftp = (bool)(Curl_ascii_equal("ftp", conn->protostr) || - Curl_ascii_equal("ftps", conn->protostr)); + bool isftp = (bool)(Curl_raw_equal("ftp", conn->protostr) || + Curl_raw_equal("ftps", conn->protostr)); /* * This synthesized URL isn't always right--suffixes like ;type=A -- cgit v1.2.1 From a9a4300a367a4beeef0674240e6721d68f1b1ae3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Oct 2008 20:21:22 +0000 Subject: - Igor Novoseltsev added CURLOPT_PROXYUSER and CURLOPT_PROXYPASSWORD that then make CURLOPT_PROXYUSERPWD sort of deprecated. The primary motive for adding these new options is that they have no problems with the colon separator that the CURLOPT_PROXYUSERPWD option does. --- lib/url.c | 101 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 39 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0f007fa39..b385e2dee 100644 --- a/lib/url.c +++ b/lib/url.c @@ -280,6 +280,39 @@ static CURLcode setstropt(char **charp, char * s) return CURLE_OK; } +static CURLcode setstropt_userpwd(char *option, char **user_storage, + char **pwd_storage) +{ + char* separator; + CURLcode result = CURLE_OK; + + separator = strchr(option, ':'); + if (separator != NULL) { + + /* store username part of option */ + char * p; + size_t username_len = (size_t)(separator-option); + p = malloc(username_len+1); + if(!p) + result = CURLE_OUT_OF_MEMORY; + else { + memcpy(p, option, username_len); + p[username_len] = '\0'; + Curl_safefree(*user_storage); + *user_storage = p; + } + + /* store password part of option */ + if (result == CURLE_OK) { + result = setstropt(pwd_storage, separator+1); + } + } + else { + result = setstropt(user_storage, option); + } + return result; +} + CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) { CURLcode r = CURLE_OK; @@ -1500,39 +1533,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password to use in the operation */ - { - char* userpwd; - char* separator; - - userpwd = va_arg(param, char *); - if(userpwd == NULL) - break; - - separator = strchr(userpwd, ':'); - if (separator != NULL) { - - /* store username part of option */ - char * p; - size_t username_len = (size_t)(separator-userpwd); - p = malloc(username_len+1); - if(!p) - result = CURLE_OUT_OF_MEMORY; - else { - memcpy(p, userpwd, username_len); - p[username_len] = '\0'; - Curl_safefree(data->set.str[STRING_USERNAME]); - data->set.str[STRING_USERNAME] = p; - } - - /* store password part of option */ - if (result == CURLE_OK) { - result = setstropt(&data->set.str[STRING_PASSWORD], separator+1); - } - } - else { - result = setstropt(&data->set.str[STRING_USERNAME], userpwd); - } - } + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_USERNAME], + &data->set.str[STRING_PASSWORD]); break; case CURLOPT_USERNAME: /* @@ -1587,7 +1590,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * user:password needed to use the proxy */ - result = setstropt(&data->set.str[STRING_PROXYUSERPWD], + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_PROXYUSERNAME], + &data->set.str[STRING_PROXYPASSWORD]); + break; + case CURLOPT_PROXYUSERNAME: + /* + * authentication user name to use in the operation + */ + result = setstropt(&data->set.str[STRING_PROXYUSERNAME], + va_arg(param, char *)); + break; + case CURLOPT_PROXYPASSWORD: + /* + * authentication password to use in the operation + */ + result = setstropt(&data->set.str[STRING_PROXYPASSWORD], va_arg(param, char *)); break; case CURLOPT_RANGE: @@ -3545,10 +3563,15 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, char proxyuser[MAX_CURL_USER_LENGTH]=""; char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - sscanf(data->set.str[STRING_PROXYUSERPWD], - "%" MAX_CURL_USER_LENGTH_TXT "[^:]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]", - proxyuser, proxypasswd); + if(data->set.str[STRING_PROXYUSERNAME] != NULL) { + strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME], MAX_CURL_USER_LENGTH); + proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ + } + if(data->set.str[STRING_PROXYPASSWORD] != NULL) { + strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD], + MAX_CURL_PASSWORD_LENGTH); + proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ + } conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); if(!conn->proxyuser) @@ -4032,7 +4055,7 @@ static CURLcode create_conn(struct SessionHandle *data, conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); - conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]); + conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; -- cgit v1.2.1 From 54582bdce9c551d50759c9ed6a092644485806ad Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Oct 2008 20:43:02 +0000 Subject: don't segfault when NULL is passed in to CURLOPT_USERPWD or CURLOPT_PROXYUSERPWD --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b385e2dee..da6d871f8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -286,6 +286,9 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, char* separator; CURLcode result = CURLE_OK; + if(!option) + return result; + separator = strchr(option, ':'); if (separator != NULL) { -- cgit v1.2.1 From a00b6e258de5bbffb325a46c219657f085b7de70 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 16 Oct 2008 22:56:40 +0000 Subject: Return an error when a proxy option is set when configured with --disable-proxy mode. Removed some unnecessary prototypes. --- lib/url.c | 98 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 45 insertions(+), 53 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index da6d871f8..73b396863 100644 --- a/lib/url.c +++ b/lib/url.c @@ -140,24 +140,9 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by /* Local static prototypes */ static long ConnectionKillOne(struct SessionHandle *data); -static bool ConnectionExists(struct SessionHandle *data, - struct connectdata *needle, - struct connectdata **usethis); -static long ConnectionStore(struct SessionHandle *data, - struct connectdata *conn); -static bool IsPipeliningPossible(const struct SessionHandle *handle); static void conn_free(struct connectdata *conn); - static void signalPipeClose(struct curl_llist *pipeline); -static struct SessionHandle* gethandleathead(struct curl_llist *pipeline); -static CURLcode do_init(struct connectdata *conn); -static void do_complete(struct connectdata *conn); - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) -static void flush_cookies(struct SessionHandle *data, int cleanup); -#endif - #ifdef CURL_DISABLE_VERBOSE_STRINGS #define verboseconnect(x) do { } while (0) #endif @@ -1309,13 +1294,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.httpversion = va_arg(param, long); break; - case CURLOPT_HTTPPROXYTUNNEL: - /* - * Tunnel operations through the proxy instead of normal proxy use - */ - data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long)); - break; - case CURLOPT_CUSTOMREQUEST: /* * Set a custom string to use as request @@ -1329,13 +1307,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, and this just changes the actual request keyword */ break; - case CURLOPT_PROXYPORT: - /* - * Explicitly set HTTP proxy port number. - */ - data->set.proxyport = va_arg(param, long); - break; - case CURLOPT_HTTPAUTH: /* * Set HTTP Authentication type BITMASK. @@ -1356,6 +1327,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_HTTPPROXYTUNNEL: + /* + * Tunnel operations through the proxy instead of normal proxy use + */ + data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long)); + break; + + case CURLOPT_PROXYPORT: + /* + * Explicitly set HTTP proxy port number. + */ + data->set.proxyport = va_arg(param, long); + break; + case CURLOPT_PROXYAUTH: /* * Set HTTP Authentication type BITMASK. @@ -1391,6 +1377,32 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, va_arg(param, char *)); break; + case CURLOPT_PROXYTYPE: + /* + * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME + */ + data->set.proxytype = (curl_proxytype)va_arg(param, long); + break; + + case CURLOPT_PROXY_TRANSFER_MODE: + /* + * set transfer mode (;type=) when doing FTP via an HTTP proxy + */ + switch (va_arg(param, long)) { + case 0: + data->set.proxy_transfer_mode = FALSE; + break; + case 1: + data->set.proxy_transfer_mode = TRUE; + break; + default: + /* reserve other values for future use */ + result = CURLE_FAILED_INIT; + break; + } + break; +#endif + case CURLOPT_WRITEHEADER: /* * Custom pointer to pass the header write callback function @@ -1589,6 +1601,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.progress_client = va_arg(param, void *); break; + +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXYUSERPWD: /* * user:password needed to use the proxy @@ -1611,6 +1625,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = setstropt(&data->set.str[STRING_PROXYPASSWORD], va_arg(param, char *)); break; +#endif + case CURLOPT_RANGE: /* * What range of the file you want to transfer @@ -1955,13 +1971,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } break; - case CURLOPT_PROXYTYPE: - /* - * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME - */ - data->set.proxytype = (curl_proxytype)va_arg(param, long); - break; - case CURLOPT_PRIVATE: /* * Set private data pointer. @@ -2117,23 +2126,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.new_directory_perms = va_arg(param, long); break; - case CURLOPT_PROXY_TRANSFER_MODE: - /* - * set transfer mode (;type=) when doing FTP via an HTTP proxy - */ - switch (va_arg(param, long)) { - case 0: - data->set.proxy_transfer_mode = FALSE; - break; - case 1: - data->set.proxy_transfer_mode = TRUE; - break; - default: - /* reserve other values for future use */ - result = CURLE_FAILED_INIT; - break; - } - break; case CURLOPT_ADDRESS_SCOPE: /* -- cgit v1.2.1 From 4acbe8f20c45ed43768ff4d25ec6718c2f1dd6dd Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 17 Oct 2008 12:53:53 +0000 Subject: fix compiler warning --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 73b396863..bf2327589 100644 --- a/lib/url.c +++ b/lib/url.c @@ -231,8 +231,10 @@ void Curl_safefree(void *ptr) static void close_connections(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ - while(-1 != ConnectionKillOne(data)) - ; /* empty loop */ + long i; + do { + i = ConnectionKillOne(data); + while(i != -1L); } void Curl_freeset(struct SessionHandle * data) -- cgit v1.2.1 From c141d990599c9bb6f8c71257b063bc04a0f657c5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Oct 2008 13:23:21 +0000 Subject: fix syntax error --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bf2327589..065b74f62 100644 --- a/lib/url.c +++ b/lib/url.c @@ -232,7 +232,7 @@ static void close_connections(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ long i; - do { + do i = ConnectionKillOne(data); while(i != -1L); } -- cgit v1.2.1 From fb08868e5475ad311baef93fe8ade1b26a9827f8 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 17 Oct 2008 13:33:13 +0000 Subject: oops --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 065b74f62..515188af7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -234,7 +234,7 @@ static void close_connections(struct SessionHandle *data) long i; do i = ConnectionKillOne(data); - while(i != -1L); + } while(i != -1L); } void Curl_freeset(struct SessionHandle * data) -- cgit v1.2.1 From e7886aa9b4dbd436708dfb21a79f19e7b1f2c02c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 17 Oct 2008 13:55:13 +0000 Subject: oops ;-) --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 515188af7..45567b6a0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -232,7 +232,7 @@ static void close_connections(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ long i; - do + do { i = ConnectionKillOne(data); } while(i != -1L); } -- cgit v1.2.1 From 80d0dcc9a3124dcecc9d1f7296f2ac429bc7d704 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 19 Oct 2008 18:20:47 +0000 Subject: clarified an argument's situation due to a false positive alert pointed out by coverity.com --- lib/url.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 45567b6a0..040a64cd1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4355,8 +4355,8 @@ static CURLcode create_conn(struct SessionHandle *data, */ static CURLcode setup_conn(struct connectdata *conn, - struct Curl_dns_entry *hostaddr, - bool *protocol_done) + struct Curl_dns_entry *hostaddr, + bool *protocol_done) { CURLcode result=CURLE_OK; struct SessionHandle *data = conn->data; @@ -4402,7 +4402,12 @@ static CURLcode setup_conn(struct connectdata *conn, if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { bool connected = FALSE; - /* Connect only if not already connected! */ + /* Connect only if not already connected! + * + * NOTE: hostaddr can be NULL when passed to this function, but that is + * only for the case where we re-use an existing connection and thus + * this code section will not be reached with hostaddr == NULL. + */ result = ConnectPlease(data, conn, hostaddr, &connected); if(connected) { -- cgit v1.2.1 From 5779283a52a1369cccbe1a1d314e2ec8ac949e0f Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 19 Oct 2008 20:17:16 +0000 Subject: attempt to fix or allow further detection of an elusive icc SIGSEGV --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 040a64cd1..a21cda0ae 100644 --- a/lib/url.c +++ b/lib/url.c @@ -450,8 +450,11 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } - if(data->dns.hostcachetype == HCACHE_PRIVATE) + if(data->dns.hostcachetype == HCACHE_PRIVATE) { Curl_hash_destroy(data->dns.hostcache); + data->dns.hostcachetype = HCACHE_NONE; + data->dns.hostcache = NULL; + } if(data->state.rangestringalloc) free(data->state.range); -- cgit v1.2.1 From bab5183820dbd2e0ea9ee4f0442844291d05c90e Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 23 Oct 2008 01:20:57 +0000 Subject: Created Curl_raw_nequal() which does a C-locale string case comparison. Changed checkprefix() to use it and those instances of strnequal() that compare host names or other protocol strings that are defined to be independent of case in the C locale. This should fix a few more Turkish locale problems. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a21cda0ae..bf77eab95 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3337,7 +3337,7 @@ static char *detect_proxy(struct connectdata *conn) if(!no_proxy) no_proxy=curl_getenv("NO_PROXY"); - if(!no_proxy || !strequal("*", no_proxy)) { + if(!no_proxy || !Curl_raw_equal("*", no_proxy)) { /* NO_PROXY wasn't specified or it wasn't just an asterisk */ char *nope; -- cgit v1.2.1 From b701ea36a723b2d7700e23ae53e2c3145dfe7bda Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 23 Oct 2008 11:49:19 +0000 Subject: moved the Curl_raw_ functions into the new lib/rawstr.c file for easier curlx_ inclusion by the curl tool without colliding with the curl_strequal functions. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bf77eab95..944741709 100644 --- a/lib/url.c +++ b/lib/url.c @@ -115,6 +115,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "multiif.h" #include "easyif.h" #include "speedcheck.h" +#include "rawstr.h" /* And now for the protocols */ #include "ftp.h" -- cgit v1.2.1 From d0b8b5a1990a31f37fcab925cb8b59bee958d41d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 3 Nov 2008 16:24:56 +0000 Subject: - Bug #2218480 (http://curl.haxx.se/bug/view.cgi?id=2218480) pointed out a problem with my CURLINFO_PRIMARY_IP fix from October 7th that caused a NULL pointer read. I also took the opportunity to clean up this logic (storing of the connection's IP address) somewhat as we had it stored in two different places and ways previously and they are now unified. --- lib/url.c | 60 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 944741709..8612262be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2174,7 +2174,6 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); - Curl_safefree(conn->ip_addr_str); Curl_safefree(conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ @@ -2479,9 +2478,9 @@ ConnectionExists(struct SessionHandle *data, } #ifdef CURLRES_ASYNCH - /* ip_addr_str is NULL only if the resolving of the name hasn't completed - yet and until then we don't re-use this connection */ - if(!check->ip_addr_str) { + /* ip_addr_str[0] is NUL only if the resolving of the name hasn't + completed yet and until then we don't re-use this connection */ + if(!check->ip_addr_str[0]) { infof(data, "Connection #%ld hasn't finished name resolve, can't reuse\n", check->connectindex); @@ -2727,36 +2726,33 @@ static CURLcode ConnectPlease(struct SessionHandle *data, conn->dns_entry = hostaddr; conn->ip_addr = addr; - result = Curl_store_ip_addr(conn); - - if(CURLE_OK == result) { - switch(data->set.proxytype) { + switch(data->set.proxytype) { #ifndef CURL_DISABLE_PROXY - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, - conn->host.name, conn->remote_port, - FIRSTSOCKET, conn); - break; - case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, FALSE); - break; - case CURLPROXY_SOCKS4A: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, TRUE); - break; + case CURLPROXY_SOCKS5: + case CURLPROXY_SOCKS5_HOSTNAME: + result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, + conn->host.name, conn->remote_port, + FIRSTSOCKET, conn); + break; + case CURLPROXY_SOCKS4: + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, FALSE); + break; + case CURLPROXY_SOCKS4A: + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, TRUE); + break; #endif /* CURL_DISABLE_PROXY */ - case CURLPROXY_HTTP: - /* do nothing here. handled later. */ - break; - default: - failf(data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - break; - } - } - } + case CURLPROXY_HTTP: + /* do nothing here. handled later. */ + break; + default: + failf(data, "unknown proxytype option given"); + result = CURLE_COULDNT_CONNECT; + break; + } /* switch proxytype */ + } /* if result is ok */ + if(result) *connected = FALSE; /* mark it as not connected */ -- cgit v1.2.1 From b80c5cff49a6df5835ed8bbf1948c4bc4b98c8d3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 5 Nov 2008 21:46:40 +0000 Subject: corrected and clarified the *_SPEED_LARGE comments --- lib/url.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8612262be..75f9e099d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1487,17 +1487,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_MAX_SEND_SPEED_LARGE: /* - * The max speed limit that sends transfer more than - * CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is - * throttled.. + * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE + * bytes per second the transfer is throttled.. */ data->set.max_send_speed=va_arg(param, curl_off_t); break; case CURLOPT_MAX_RECV_SPEED_LARGE: /* - * The max speed limit that sends transfer more than - * CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is - * throttled.. + * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per + * second the transfer is throttled.. */ data->set.max_recv_speed=va_arg(param, curl_off_t); break; -- cgit v1.2.1 From 797bc8504c0c1d718b088dca0622d920e3c6fcff Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 19 Nov 2008 10:15:19 +0000 Subject: - Andreas Wurf and Markus Koetter helped me analyze a problem that Andreas got when uploading files to a single FTP server using multiple easy handle handles with the multi interface. Occasionally a handle would stall in mysterious ways. The problem turned out to be a side-effect of the ConnectionExists() function's eagerness to re-use a handle for HTTP pipelining so it would select it even if already being in use, due to an inadequate check for its chances of being used for pipelnining. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 75f9e099d..6bb3e3ee7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2509,6 +2509,11 @@ ConnectionExists(struct SessionHandle *data, /* don't do mixed proxy and non-proxy connections */ continue; + if(!canPipeline && check->inuse) + /* this request can't be pipelined but the checked connection is already + in use so we skip it */ + continue; + if(!needle->bits.httpproxy || needle->protocol&PROT_SSL || (needle->bits.httpproxy && check->bits.httpproxy && needle->bits.tunnel_proxy && check->bits.tunnel_proxy && -- cgit v1.2.1 From 479ddb1fee2fa5f7204a64742e9dcc2842d668dd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Dec 2008 15:20:27 +0000 Subject: - Igor Novoseltsev filed bug #2351645 (http://curl.haxx.se/bug/view.cgi?id=2351645) that identified a problem with the multi interface that occured if you removed an easy handle while in progress and the handle was used in a HTTP pipeline. --- lib/url.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6bb3e3ee7..9037bf920 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2359,6 +2359,20 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle, return 0; } +/* remove the specified connection from all (possible) pipelines and related + queues */ +void Curl_getoff_all_pipelines(struct SessionHandle *data, + struct connectdata *conn) +{ + if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && + conn->readchannel_inuse) + conn->readchannel_inuse = FALSE; + if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && + conn->writechannel_inuse) + conn->writechannel_inuse = FALSE; + Curl_removeHandleFromPipeline(data, conn->pend_pipe); +} + #if 0 /* this code is saved here as it is useful for debugging purposes */ static void Curl_printPipeline(struct curl_llist *pipeline) { @@ -4548,13 +4562,7 @@ CURLcode Curl_done(struct connectdata **connp, Curl_expire(data, 0); /* stop timer */ - if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && - conn->readchannel_inuse) - conn->readchannel_inuse = FALSE; - if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && - conn->writechannel_inuse) - conn->writechannel_inuse = FALSE; - Curl_removeHandleFromPipeline(data, conn->pend_pipe); + Curl_getoff_all_pipelines(data, conn); if(conn->bits.done || (conn->send_pipe->size + conn->recv_pipe->size != 0 && -- cgit v1.2.1 From 6e376532b00879ead13d5e07453ab8dd0d97571e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 10 Dec 2008 23:13:31 +0000 Subject: - Internet Explorer had a broken HTTP digest authentication before v7 and there are servers "out there" that relies on the client doing this broken Digest authentication. Apache even comes with an option to work with such broken clients. The difference is only for URLs that contain a query-part (a '?'-letter and text to the right of it). libcurl now supports this quirk, and you enable it by setting the CURLAUTH_DIGEST_IE bit in the bitmask you pass to the CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH options. They are thus individually controlled to server and proxy. --- lib/url.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9037bf920..1cf8b08da 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1319,6 +1319,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ { long auth = va_arg(param, long); + + /* the DIGEST_IE bit is only used to set a special marker, for all the + rest we need to handle it as normal DIGEST */ + data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; + + if(auth & CURLAUTH_DIGEST_IE) { + auth |= CURLAUTH_DIGEST; /* set standard digest bit */ + auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ + } + /* switch off bits we can't support */ #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ @@ -1354,6 +1364,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ { long auth = va_arg(param, long); + + /* the DIGEST_IE bit is only used to set a special marker, for all the + rest we need to handle it as normal DIGEST */ + data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; + + if(auth & CURLAUTH_DIGEST_IE) { + auth |= CURLAUTH_DIGEST; /* set standard digest bit */ + auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ + } /* switch off bits we can't support */ #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ -- cgit v1.2.1 From 1b4af1f8d821d3be0cb540e94f947841a967d70f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 11 Dec 2008 22:22:46 +0000 Subject: - Keshav Krity found out that libcurl failed to deal with dotted IPv6 addresses if they were very long (>39 letters) due to a too strict address validity parser. It now accepts addresses up to 45 bytes long. --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1cf8b08da..3e2b14e9d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3724,7 +3724,8 @@ static CURLcode parse_remote_port(struct SessionHandle *data, char *portptr; char endbracket; - if((1 == sscanf(conn->host.name, "[%*39[0123456789abcdefABCDEF:.%]%c", &endbracket)) && + if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.%]%c", + &endbracket)) && (']' == endbracket)) { /* this is a RFC2732-style specified IP-address */ conn->bits.ipv6_ip = TRUE; -- cgit v1.2.1 From c0dfe6e51d2bdaa0cf6dedfdad8bd7748f9edd36 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 11 Dec 2008 23:27:22 +0000 Subject: Dan F pointed out that we don't need to scan IPv6 addresses for '%'-letters in the parse_remote_port() function as the scope id has already been stripped from the string. --- lib/url.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3e2b14e9d..0f25a9d3e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3724,7 +3724,10 @@ static CURLcode parse_remote_port(struct SessionHandle *data, char *portptr; char endbracket; - if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.%]%c", + /* Note that at this point, the IPv6 address cannot contain any scope + suffix as that has already been removed in the ParseURLAndFillConnection() + function */ + if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c", &endbracket)) && (']' == endbracket)) { /* this is a RFC2732-style specified IP-address */ -- cgit v1.2.1 From 3ca360391a2045a222b36ac1f0e454a02d354d97 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Dec 2008 12:04:10 +0000 Subject: Make the getoff all pipelines function only set _inuse to FALSE if the specified data pointer was head. --- lib/url.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0f25a9d3e..099a4a5af 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2378,20 +2378,6 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle, return 0; } -/* remove the specified connection from all (possible) pipelines and related - queues */ -void Curl_getoff_all_pipelines(struct SessionHandle *data, - struct connectdata *conn) -{ - if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && - conn->readchannel_inuse) - conn->readchannel_inuse = FALSE; - if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && - conn->writechannel_inuse) - conn->writechannel_inuse = FALSE; - Curl_removeHandleFromPipeline(data, conn->pend_pipe); -} - #if 0 /* this code is saved here as it is useful for debugging purposes */ static void Curl_printPipeline(struct curl_llist *pipeline) { @@ -2416,6 +2402,24 @@ static struct SessionHandle* gethandleathead(struct curl_llist *pipeline) return NULL; } +/* remove the specified connection from all (possible) pipelines and related + queues */ +void Curl_getoff_all_pipelines(struct SessionHandle *data, + struct connectdata *conn) +{ + bool recv_head = conn->readchannel_inuse && + (gethandleathead(conn->recv_pipe) == data); + + bool send_head = conn->writechannel_inuse && + (gethandleathead(conn->send_pipe) == data); + + if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head) + conn->readchannel_inuse = FALSE; + if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head) + conn->writechannel_inuse = FALSE; + Curl_removeHandleFromPipeline(data, conn->pend_pipe); +} + static void signalPipeClose(struct curl_llist *pipeline) { struct curl_llist_element *curr; -- cgit v1.2.1 From 07416b61e3c403ea56370858a618f877dcaee57d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Dec 2008 21:14:52 +0000 Subject: - Using the libssh2 0.19 function libssh2_session_block_directions(), libcurl now has an improved ability to do right when the multi interface (both "regular" and multi_socket) is used for SCP and SFTP transfers. This should result in (much) less busy-loop situations and thus less CPU usage with no speed loss. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 099a4a5af..4826192ef 100644 --- a/lib/url.c +++ b/lib/url.c @@ -218,6 +218,7 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* doing */ ZERO_NULL, /* proto_getsock */ ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* disconnect */ 0, /* defport */ 0 /* protocol */ -- cgit v1.2.1 From 83640b2ee5e41292eab2ff3e722c5ac4caea17c9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 29 Dec 2008 22:25:50 +0000 Subject: - Phil Lisiecki filed bug report #2413067 (http://curl.haxx.se/bug/view.cgi?id=2413067) that identified a problem that would cause libcurl to mark a DNS cache entry "in use" eternally if the subsequence TCP connect failed. It would thus never get pruned and refreshed as it should've been. --- lib/url.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4826192ef..24d143420 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4523,22 +4523,28 @@ CURLcode Curl_connect(struct SessionHandle *data, if(CURLE_OK == code) { /* no error */ - if((*in_connect)->send_pipe->size + - (*in_connect)->recv_pipe->size != 0) + if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size) /* pipelining */ *protocol_done = TRUE; else { + if(dns || !*asyncp) /* If an address is available it means that we already have the name resolved, OR it isn't async. if this is a re-used connection 'dns' will be NULL here. Continue connecting from here */ code = setup_conn(*in_connect, dns, protocol_done); - /* else - response will be received and treated async wise */ + + if(dns && code) { + /* We have the dns entry info already but failed to connect to the + * host and thus we must make sure to unlock the dns entry again + * before returning failure from here. + */ + Curl_resolv_unlock(data, dns); + } } } - if(CURLE_OK != code && *in_connect) { + if(code && *in_connect) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ Curl_disconnect(*in_connect); /* close the connection */ -- cgit v1.2.1 From bc93011554f57d4d29087001712329ad9e808862 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 8 Jan 2009 00:31:49 +0000 Subject: Unified much of the SessionHandle initialization done in Curl_open() and curl_easy_reset() by creating Curl_init_userdefined(). This had the side effect of fixing curl_easy_reset() so it now also resets CURLOPT_FTP_FILEMETHOD and CURLOPT_SSL_SESSIONID_CACHE --- lib/url.c | 141 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 64 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 24d143420..0145d4935 100644 --- a/lib/url.c +++ b/lib/url.c @@ -622,6 +622,77 @@ void Curl_rm_connc(struct conncache *c) free(c); } +/* + * Initialize the UserDefined fields within a SessionHandle. + * This may be safely called on a new or existing SessionHandle. + */ +CURLcode Curl_init_userdefined(struct UserDefined *set) +{ + CURLcode res = CURLE_OK; + + set->out = stdout; /* default output to stdout */ + set->in = stdin; /* default input from stdin */ + set->err = stderr; /* default stderr to stderr */ + + /* use fwrite as default function to store output */ + set->fwrite_func = (curl_write_callback)fwrite; + + /* use fread as default function to read input */ + set->fread_func = (curl_read_callback)fread; + + set->seek_func = ZERO_NULL; + set->seek_client = ZERO_NULL; + + /* conversion callbacks for non-ASCII hosts */ + set->convfromnetwork = ZERO_NULL; + set->convtonetwork = ZERO_NULL; + set->convfromutf8 = ZERO_NULL; + + set->infilesize = -1; /* we don't know any size */ + set->postfieldsize = -1; /* unknown size */ + set->maxredirs = -1; /* allow any amount by default */ + + set->httpreq = HTTPREQ_GET; /* Default HTTP request */ + set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ + set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + set->ftp_filemethod = FTPFILE_MULTICWD; + + set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + + /* Set the default size of the SSL session ID cache */ + set->ssl.numsessions = 5; + + set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */ + set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ + set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ + set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ + + /* make libcurl quiet by default: */ + set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ + + /* + * libcurl 7.10 introduced SSL verification *by default*! This needs to be + * switched off unless wanted. + */ + set->ssl.verifypeer = TRUE; + set->ssl.verifyhost = 2; + set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth + type */ + set->ssl.sessionid = TRUE; /* session ID caching enabled by default */ + + set->new_file_perms = 0644; /* Default permissions */ + set->new_directory_perms = 0755; /* Default permissions */ + + /* This is our preferred CA cert bundle/path since install time */ +#if defined(CURL_CA_BUNDLE) + res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE); +#elif defined(CURL_CA_PATH) + res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH); +#endif + + return res; +} + /** * Curl_open() * @@ -669,26 +740,10 @@ CURLcode Curl_open(struct SessionHandle **curl) res = CURLE_OUT_OF_MEMORY; } else { - data->state.headersize=HEADERSIZE; - - 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->set.fwrite_func = (curl_write_callback)fwrite; - - /* use fread as default function to read input */ - data->set.fread_func = (curl_read_callback)fread; - - /* don't use a seek function by default */ - data->set.seek_func = ZERO_NULL; - data->set.seek_client = ZERO_NULL; + Curl_easy_initHandleData(data); + res = Curl_init_userdefined(&data->set); - /* conversion callbacks for non-ASCII hosts */ - data->set.convfromnetwork = ZERO_NULL; - data->set.convtonetwork = ZERO_NULL; - data->set.convfromutf8 = ZERO_NULL; + data->state.headersize=HEADERSIZE; #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) /* conversion descriptors for iconv calls */ @@ -697,57 +752,15 @@ CURLcode Curl_open(struct SessionHandle **curl) data->utf8_cd = (iconv_t)-1; #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ - data->set.infilesize = -1; /* we don't know any size */ - data->set.postfieldsize = -1; - data->set.maxredirs = -1; /* allow any amount by default */ - data->state.current_speed = -1; /* init to negative == impossible */ - - data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */ - data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ - data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ - data->set.ftp_filemethod = FTPFILE_MULTICWD; - data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + /* most recent connection is not yet defined */ + data->state.lastconnect = -1; - /* make libcurl quiet by default: */ - 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->set.ssl.numsessions = 5; - - data->set.proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */ - data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ - data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */ - data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */ + data->state.current_speed = -1; /* init to negative == impossible */ /* This no longer creates a connection cache here. It is instead made on the first call to curl_easy_perform() or when the handle is added to a multi stack. */ - - data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth - type */ - data->set.new_file_perms = 0644; /* Default permissions */ - data->set.new_directory_perms = 0755; /* Default permissions */ - - /* most recent connection is not yet defined */ - data->state.lastconnect = -1; - - Curl_easy_initHandleData(data); - - /* - * libcurl 7.10 introduced SSL verification *by default*! This needs to be - * switched off unless wanted. - */ - data->set.ssl.verifypeer = TRUE; - data->set.ssl.verifyhost = 2; - data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */ - /* This is our preferred CA cert bundle/path since install time */ -#if defined(CURL_CA_BUNDLE) - res = setstropt(&data->set.str[STRING_SSL_CAFILE], - (char *) CURL_CA_BUNDLE); -#elif defined(CURL_CA_PATH) - res = setstropt(&data->set.str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH); -#endif } if(res) { -- cgit v1.2.1 From 5591550167092c0e5f307b3c2c87f44518e7159f Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 21 Jan 2009 04:42:47 +0000 Subject: Fixed a couple more locale-dependent toupper conversions, mainly for clarity. This does fix one problem that causes ;type=i FTP URLs to fail in the Turkish locale when CURLOPT_PROXY_TRANSFER_MODE is used (test case 561) Added tests 561 and 1092 through 1094 to test various combinations of ;type= and ;mode= URLs that could potentially fail in the Turkish locale. --- lib/url.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0145d4935..47d2af342 100644 --- a/lib/url.c +++ b/lib/url.c @@ -230,6 +230,21 @@ void Curl_safefree(void *ptr) free(ptr); } +/* Copy an upper case version of the string from src to dest. The + * strings may overlap. No more than n characters of the string are copied + * (including any NUL) and the destination string will NOT be + * NUL-terminated if that limit is reached. + */ +void Curl_strntoupper(char *dest, const char *src, size_t n) +{ + if (n < 1) + return; + + do { + *dest++ = Curl_raw_toupper(*src); + } while (*src++ && --n); +} + static void close_connections(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ @@ -3441,8 +3456,7 @@ static char *detect_proxy(struct connectdata *conn) */ if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ - for(envp = proxy_env; *envp; envp++) - *envp = (char)toupper((int)*envp); + Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); prox=curl_getenv(proxy_env); } -- cgit v1.2.1 From 5aeef9c1c87f2f72f10807a609ced1976ab46cd2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 25 Jan 2009 23:26:25 +0000 Subject: - Craig A West brought CURLOPT_NOPROXY and the corresponding --noproxy option. They basically offer the same thing the NO_PROXY environment variable only offered previously: list a set of host names that shall not use the proxy even if one is specified. --- lib/url.c | 234 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 158 insertions(+), 76 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 47d2af342..6cefda2c1 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1677,6 +1677,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = setstropt(&data->set.str[STRING_PROXYPASSWORD], va_arg(param, char *)); break; + case CURLOPT_NOPROXY: + /* + * proxy exception list + */ + result = setstropt(&data->set.str[STRING_NOPROXY], + va_arg(param, char *)); + break; #endif case CURLOPT_RANGE: @@ -3368,6 +3375,80 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, } #ifndef CURL_DISABLE_PROXY +/**************************************************************** +* Checks if the host is in the noproxy list. returns true if it matches +* and therefore the proxy should NOT be used. +****************************************************************/ +static bool check_noproxy(const char* name, const char* no_proxy) +{ + /* no_proxy=domain1.dom,host.domain2.dom + * (a comma-separated list of hosts which should + * not be proxied, or an asterisk to override + * all proxy variables) + */ + size_t tok_start; + size_t tok_end; + const char* separator = ", "; + size_t no_proxy_len; + size_t namelen; + char *endptr; + + if(no_proxy && no_proxy[0]) { + if(Curl_raw_equal("*", no_proxy)) { + return TRUE; + } + + /* NO_PROXY was specified and it wasn't just an asterisk */ + + no_proxy_len = strlen(no_proxy); + endptr = strchr(name, ':'); + if(endptr) + namelen = endptr - name; + else + namelen = strlen(name); + + tok_start = 0; + for (tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { + while (tok_start < no_proxy_len && + strchr(separator, no_proxy[tok_start]) != NULL) { + /* Look for the beginning of the token. */ + ++tok_start; + } + + if(tok_start == no_proxy_len) + break; /* It was all trailing separator chars, no more tokens. */ + + for (tok_end = tok_start; tok_end < no_proxy_len && + strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) { + /* Look for the end of the token. */ + } + + /* To match previous behaviour, where it was necessary to specify + * ".local.com" to prevent matching "notlocal.com", we will leave + * the '.' off. + */ + if(no_proxy[tok_start] == '.') + ++tok_start; + + if((tok_end - tok_start) <= namelen) { + /* Match the last part of the name to the domain we are checking. */ + const char *checkn = name + namelen - (tok_end - tok_start); + if(Curl_raw_nequal(no_proxy + tok_start, checkn, tok_end - tok_start)) { + if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') { + /* We either have an exact match, or the previous character is a . + * so it is within the same domain, so no proxy for this host. + */ + return TRUE; + } + } + } /* if((tok_end - tok_start) <= namelen) */ + } /* for (tok_start = 0; tok_start < no_proxy_len; + tok_start = tok_end + 1) */ + } /* NO_PROXY was specified and it wasn't just an asterisk */ + + return FALSE; +} + /**************************************************************** * Detect what (if any) proxy to use. Remember that this selects a host * name and is not limited to HTTP proxies only. @@ -3396,90 +3477,56 @@ static char *detect_proxy(struct connectdata *conn) * checked if the lowercase versions don't exist. */ char *no_proxy=NULL; - char *no_proxy_tok_buf; char proxy_env[128]; no_proxy=curl_getenv("no_proxy"); if(!no_proxy) no_proxy=curl_getenv("NO_PROXY"); - if(!no_proxy || !Curl_raw_equal("*", no_proxy)) { - /* NO_PROXY wasn't specified or it wasn't just an asterisk */ - char *nope; + if(!check_noproxy(conn->host.name, no_proxy)) { + /* It was not listed as without proxy */ + char *protop = conn->protostr; + char *envp = proxy_env; + char *prox; - nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; - while(nope) { - size_t namelen; - char *endptr = strchr(conn->host.name, ':'); - if(endptr) - namelen=endptr-conn->host.name; - else - namelen=strlen(conn->host.name); - - if(strlen(nope) <= namelen) { - char *checkn= - conn->host.name + namelen - strlen(nope); - if(checkprefix(nope, checkn)) { - /* no proxy for this host! */ - break; - } - } - nope=strtok_r(NULL, ", ", &no_proxy_tok_buf); - } - if(!nope) { - /* It was not listed as without proxy */ - char *protop = conn->protostr; - char *envp = proxy_env; - char *prox; + /* Now, build _proxy and check for such a one to use */ + while(*protop) + *envp++ = (char)tolower((int)*protop++); - /* Now, build _proxy and check for such a one to use */ - while(*protop) - *envp++ = (char)tolower((int)*protop++); + /* append _proxy */ + strcpy(envp, "_proxy"); - /* append _proxy */ - strcpy(envp, "_proxy"); + /* read the protocol proxy: */ + prox=curl_getenv(proxy_env); - /* read the protocol proxy: */ + /* + * We don't try the uppercase version of HTTP_PROXY because of + * security reasons: + * + * When curl is used in a webserver application + * environment (cgi or php), this environment variable can + * be controlled by the web server user by setting the + * http header 'Proxy:' to some value. + * + * This can cause 'internal' http/ftp requests to be + * arbitrarily redirected by any external attacker. + */ + if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { + /* There was no lowercase variable, try the uppercase version: */ + Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); prox=curl_getenv(proxy_env); + } - /* - * We don't try the uppercase version of HTTP_PROXY because of - * security reasons: - * - * When curl is used in a webserver application - * environment (cgi or php), this environment variable can - * be controlled by the web server user by setting the - * http header 'Proxy:' to some value. - * - * This can cause 'internal' http/ftp requests to be - * arbitrarily redirected by any external attacker. - */ - if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { - /* There was no lowercase variable, try the uppercase version: */ - Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); - prox=curl_getenv(proxy_env); - } - - if(prox && *prox) { /* don't count "" strings */ - proxy = prox; /* use this */ - } - else { - proxy = curl_getenv("all_proxy"); /* default proxy to use */ - if(!proxy) - proxy=curl_getenv("ALL_PROXY"); - } - - if(proxy && *proxy) { - long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); - - if(conn->proxytype == CURLPROXY_HTTP) { - /* force this connection's protocol to become HTTP */ - conn->protocol = PROT_HTTP | bits; - conn->bits.proxy = conn->bits.httpproxy = TRUE; - } - } - } /* if(!nope) - it wasn't specified non-proxy */ - } /* NO_PROXY wasn't specified or '*' */ + if(prox && *prox) { /* don't count "" strings */ + proxy = prox; /* use this */ + } + else { + proxy = curl_getenv("all_proxy"); /* default proxy to use */ + if(!proxy) + proxy=curl_getenv("ALL_PROXY"); + } + } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified + non-proxy */ if(no_proxy) free(no_proxy); @@ -3629,7 +3676,8 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; if(data->set.str[STRING_PROXYUSERNAME] != NULL) { - strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME], MAX_CURL_USER_LENGTH); + strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME], + MAX_CURL_USER_LENGTH); proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ } if(data->set.str[STRING_PROXYPASSWORD] != NULL) { @@ -4117,15 +4165,26 @@ static CURLcode create_conn(struct SessionHandle *data, and the SessionHandle */ conn->proxytype = data->set.proxytype; /* type */ + +#ifdef CURL_DISABLE_PROXY + + conn->bits.proxy = FALSE; + conn->bits.httpproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; + +#else /* CURL_DISABLE_PROXY */ + conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && *data->set.str[STRING_PROXY]); conn->bits.httpproxy = (bool)(conn->bits.proxy && (conn->proxytype == CURLPROXY_HTTP)); + conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; +#endif /* CURL_DISABLE_PROXY */ conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); - conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; @@ -4205,11 +4264,34 @@ static CURLcode create_conn(struct SessionHandle *data, if(!proxy) proxy = detect_proxy(conn); + else if(data->set.str[STRING_NOPROXY]) { + if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) { + free(proxy); /* proxy is in exception list */ + proxy = NULL; + } + } if(proxy && !*proxy) { free(proxy); /* Don't bother with an empty proxy string */ proxy = NULL; } /* proxy must be freed later unless NULL */ + if(proxy && *proxy) { + long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); + + if(conn->proxytype == CURLPROXY_HTTP) { + /* force this connection's protocol to become HTTP */ + conn->protocol = PROT_HTTP | bits; + conn->bits.httpproxy = TRUE; + } + conn->bits.proxy = TRUE; + } + else { + /* we aren't using the proxy after all... */ + conn->bits.proxy = FALSE; + conn->bits.httpproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; + } #endif /* CURL_DISABLE_PROXY */ /************************************************************* -- cgit v1.2.1 From 0516ce7786e9500c2e447d48aa9b3f24a6ca70f9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Jan 2009 22:43:06 +0000 Subject: - Chad Monroe provided the new CURLOPT_TFTP_BLKSIZE option that allows an app to set desired block size to use for TFTP transfers instead of the default 512 bytes. --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6cefda2c1..be5b20990 100644 --- a/lib/url.c +++ b/lib/url.c @@ -932,6 +932,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.ftp_response_timeout = va_arg( param , long ) * 1000; break; + case CURLOPT_TFTP_BLKSIZE: + /* + * TFTP option that specifies the block size to use for data transmission + */ + data->set.tftp_blksize = va_arg(param, long); + break; case CURLOPT_DIRLISTONLY: /* * An option that changes the command to one that asks for a list -- cgit v1.2.1 From de4610a55f9e99bebaf448ca33e2e43baf977c74 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 28 Jan 2009 21:33:58 +0000 Subject: - Markus Moeller introduced two new options to libcurl: CURLOPT_SOCKS5_GSSAPI_SERVICE and CURLOPT_SOCKS5_GSSAPI_NEC to allow libcurl to do GSS-style authentication with SOCKS5 proxies. The curl tool got the options called --socks5-gssapi-service and --socks5-gssapi-nec to enable these. --- lib/url.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index be5b20990..bd9a7e690 100644 --- a/lib/url.c +++ b/lib/url.c @@ -698,6 +698,20 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->new_file_perms = 0644; /* Default permissions */ set->new_directory_perms = 0755; /* Default permissions */ + +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + /* + * disallow unprotected protection negotiation NEC reference implementation + * seem not to follow rfc1961 section 4.3/4.4 + */ + set->socks5_gssapi_nec = FALSE; + /* set default gssapi service name */ + res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE], + (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE); + if (res != CURLE_OK) + return res; +#endif + /* This is our preferred CA cert bundle/path since install time */ #if defined(CURL_CA_BUNDLE) res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE); @@ -1463,6 +1477,23 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; #endif +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + case CURLOPT_SOCKS5_GSSAPI_SERVICE: + /* + * Set gssapi service name + */ + result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE], + va_arg(param, char *)); + break; + + case CURLOPT_SOCKS5_GSSAPI_NEC: + /* + * set flag for nec socks5 support + */ + data->set.socks5_gssapi_nec = (bool)(0 != va_arg(param, long)); + break; +#endif + case CURLOPT_WRITEHEADER: /* * Custom pointer to pass the header write callback function -- cgit v1.2.1 From bdd4294e79eea15cb6f312f7ee7d388ad40a65e3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Feb 2009 16:19:23 +0000 Subject: - Craig A West brought us: libcurl now defaults to do CONNECT with HTTP version 1.1 instead of 1.0 like before. This change also introduces the new proxy type for libcurl called 'CURLPROXY_HTTP_1_0' that then allows apps to switch (back) to CONNECT 1.0 requests. The curl tool also got a --proxy1.0 option that works exactly like --proxy but sets CURLPROXY_HTTP_1_0. I updated all test cases cases that use CONNECT and I tried to do some using --proxy1.0 and some updated to do CONNECT 1.1 to get both versions run. --- lib/url.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bd9a7e690..7cbe3cec0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1453,7 +1453,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_PROXYTYPE: /* - * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME + * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME */ data->set.proxytype = (curl_proxytype)va_arg(param, long); break; @@ -2857,6 +2857,7 @@ static CURLcode ConnectPlease(struct SessionHandle *data, break; #endif /* CURL_DISABLE_PROXY */ case CURLPROXY_HTTP: + case CURLPROXY_HTTP_1_0: /* do nothing here. handled later. */ break; default: @@ -4214,9 +4215,11 @@ static CURLcode create_conn(struct SessionHandle *data, conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && *data->set.str[STRING_PROXY]); - conn->bits.httpproxy = (bool)(conn->bits.proxy - && (conn->proxytype == CURLPROXY_HTTP)); - conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); + conn->bits.httpproxy = (bool)(conn->bits.proxy && + (conn->proxytype == CURLPROXY_HTTP || + conn->proxytype == CURLPROXY_HTTP_1_0)); + conn->bits.proxy_user_passwd = + (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; #endif /* CURL_DISABLE_PROXY */ @@ -4315,7 +4318,8 @@ static CURLcode create_conn(struct SessionHandle *data, if(proxy && *proxy) { long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); - if(conn->proxytype == CURLPROXY_HTTP) { + if((conn->proxytype == CURLPROXY_HTTP) || + (conn->proxytype == CURLPROXY_HTTP_1_0)) { /* force this connection's protocol to become HTTP */ conn->protocol = PROT_HTTP | bits; conn->bits.httpproxy = TRUE; -- cgit v1.2.1 From d4ac3d53fc13ec9fdf4e693e4b6fe2539ee6592c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Feb 2009 21:36:47 +0000 Subject: - Patrick Scott found a rather large memory leak when using the multi interface and setting CURLMOPT_MAXCONNECTS to something less than the number of handles you add to the multi handle. All the connections that didn't fit in the cache would not be properly disconnected nor freed! --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7cbe3cec0..80d55bd55 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4804,8 +4804,12 @@ CURLcode Curl_done(struct connectdata **connp, state it is for re-using, so we're forced to close it. In a perfect world we can add code that keep track of if we really must close it here or not, but currently we have no such detail knowledge. + + connectindex == -1 here means that the connection has no spot in the + connection cache and thus we must disconnect it here. */ - if(data->set.reuse_forbid || conn->bits.close || premature) { + if(data->set.reuse_forbid || conn->bits.close || premature || + (-1 == conn->connectindex)) { CURLcode res2 = Curl_disconnect(conn); /* close the connection */ /* If we had an error already, make sure we return that one. But -- cgit v1.2.1 From bf44d0f6400bc51a5cddb7d920db150c1d818d5c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 7 Feb 2009 22:53:37 +0000 Subject: Moved Curl_strntoupper() to the rawstr.c file where the other raw string functions are. --- lib/url.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 80d55bd55..6d5bf4207 100644 --- a/lib/url.c +++ b/lib/url.c @@ -230,21 +230,6 @@ void Curl_safefree(void *ptr) free(ptr); } -/* Copy an upper case version of the string from src to dest. The - * strings may overlap. No more than n characters of the string are copied - * (including any NUL) and the destination string will NOT be - * NUL-terminated if that limit is reached. - */ -void Curl_strntoupper(char *dest, const char *src, size_t n) -{ - if (n < 1) - return; - - do { - *dest++ = Curl_raw_toupper(*src); - } while (*src++ && --n); -} - static void close_connections(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ -- cgit v1.2.1 From 8f81fd6be5d3a480eca3f7ebbded5113f66c64be Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 17 Feb 2009 09:07:25 +0000 Subject: - CURLOPT_FTP_CREATE_MISSING_DIRS can now be set to 2 in addition to 1 for plain FTP connections, and it will then allow MKD to fail once and retry the CWD afterwards. This is especially useful if you're doing many simultanoes connections against the same server and they all have this option enabled, as then CWD may first fail but then another connection does MKD before this connection and thus MKD fails but trying CWD works! The numbers can (should?) now be set with the convenience enums now called CURLFTP_CREATE_DIR and CURLFTP_CREATE_DIR_RETRY. Tests has proven that if you're making an application that uploads a set of files to an ftp server, you will get a noticable gain in speed if you're using multiple connections and this option will be then be very useful. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6d5bf4207..c16ad97f3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -922,7 +922,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * An FTP option that modifies an upload to create missing directories on * the server. */ - data->set.ftp_create_missing_dirs = (bool)(0 != va_arg(param, long)); + data->set.ftp_create_missing_dirs = (int)va_arg(param, long); break; case CURLOPT_FTP_RESPONSE_TIMEOUT: /* -- cgit v1.2.1 From df07537ccf98fd7984563dda89218f0d3bd0d6f6 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 28 Feb 2009 01:11:57 +0000 Subject: fix compiler warning --- lib/url.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c16ad97f3..389fdc84f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1356,7 +1356,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; + data->state.authhost.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -1401,7 +1401,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; + data->state.authproxy.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -2465,11 +2465,11 @@ static struct SessionHandle* gethandleathead(struct curl_llist *pipeline) void Curl_getoff_all_pipelines(struct SessionHandle *data, struct connectdata *conn) { - bool recv_head = conn->readchannel_inuse && - (gethandleathead(conn->recv_pipe) == data); + bool recv_head = (bool)(conn->readchannel_inuse && + (gethandleathead(conn->recv_pipe) == data)); - bool send_head = conn->writechannel_inuse && - (gethandleathead(conn->send_pipe) == data); + bool send_head = (bool)(conn->writechannel_inuse && + (gethandleathead(conn->send_pipe) == data)); if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head) conn->readchannel_inuse = FALSE; -- cgit v1.2.1 From 042cc1f69ec0878f542667cb684378869f859911 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Mar 2009 23:05:31 +0000 Subject: - David Kierznowski notified us about a security flaw (http://curl.haxx.se/docs/adv_20090303.html also known as CVE-2009-0037) in which previous libcurl versions (by design) can be tricked to access an arbitrary local/different file instead of a remote one when CURLOPT_FOLLOWLOCATION is enabled. This flaw is now fixed in this release together this the addition of two new setopt options for controlling this new behavior: o CURLOPT_REDIR_PROTOCOLS controls what protocols libcurl is allowed to follow to when CURLOPT_FOLLOWLOCATION is enabled. By default, this option excludes the FILE and SCP protocols and thus you nee to explicitly allow them in your app if you really want that behavior. o CURLOPT_PROTOCOLS controls what protocol(s) libcurl is allowed to fetch using the primary URL option. This is useful if you want to allow a user or other outsiders control what URL to pass to libcurl and yet not allow all protocols libcurl may have been built to support. --- lib/url.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 389fdc84f..6d2e6d4b7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -683,6 +683,12 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->new_file_perms = 0644; /* Default permissions */ set->new_directory_perms = 0755; /* Default permissions */ + /* for the *protocols fields we don't use the CURLPROTO_ALL convenience + define since we internally only use the lower 16 bits for the passed + in bitmask to not conflict with the private bits */ + set->allowed_protocols = PROT_EXTMASK; + set->redir_protocols = + PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */ #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) /* @@ -2217,6 +2223,22 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.scope = (unsigned int) va_arg(param, long); break; + case CURLOPT_PROTOCOLS: + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK; + break; + + case CURLOPT_REDIR_PROTOCOLS: + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK; + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -3371,7 +3393,19 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, for (pp = protocols; (p = *pp) != NULL; pp++) if(Curl_raw_equal(p->scheme, conn->protostr)) { - /* Protocol found in table. Perform setup complement if some. */ + /* Protocol found in table. Check if allowed */ + if(!(data->set.allowed_protocols & p->protocol)) + /* nope, get out */ + break; + + /* it is allowed for "normal" request, now do an extra check if this is + the result of a redirect */ + if(data->state.this_is_a_follow && + !(data->set.redir_protocols & p->protocol)) + /* nope, get out */ + break; + + /* Perform setup complement if some. */ conn->handler = p; if(p->setup_connection) { -- cgit v1.2.1 From ee73fc361ba33a2c6308bac1a75e3c0b8fe639eb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Mar 2009 11:01:24 +0000 Subject: - David James brought a patch that make libcurl close (all) dead connections whenever you attempt to open a new connection. --- lib/url.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6d2e6d4b7..22b8f7dfd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2565,6 +2565,22 @@ ConnectionExists(struct SessionHandle *data, from the multi */ } + if(!pipeLen && !check->inuse) { + /* The check for a dead socket makes sense only if there are no + handles in pipeline and the connection isn't already marked in + use */ + bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); + if(dead) { + check->data = data; + infof(data, "Connection #%d seems to be dead!\n", i); + + Curl_disconnect(check); /* disconnect resources */ + data->state.connc->connects[i]=NULL; /* nothing here */ + + continue; + } + } + if(canPipeline) { /* Make sure the pipe has only GET requests */ struct SessionHandle* sh = gethandleathead(check->send_pipe); @@ -2688,22 +2704,6 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - if(!pipeLen && !check->inuse) { - /* The check for a dead socket makes sense only if there are no - handles in pipeline and the connection isn't already marked in - use */ - bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); - if(dead) { - check->data = data; - infof(data, "Connection #%d seems to be dead!\n", i); - - Curl_disconnect(check); /* disconnect resources */ - data->state.connc->connects[i]=NULL; /* nothing here */ - - return FALSE; - } - } - check->inuse = TRUE; /* mark this as being in use so that no other handle in a multi stack may nick it */ -- cgit v1.2.1 From 379bfa5a36809b3c44bc792cffd36c832b5d9fbb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Apr 2009 18:01:02 +0000 Subject: - bug report #2727981 (http://curl.haxx.se/bug/view.cgi?id=2727981) by Martin Storsjo pointed out how setting CURLOPT_NOBODY to 0 could be downright confusing as it set the method to either GET or HEAD. The example he showed looked like: curl_easy_setopt(curl, CURLOPT_PUT, 1); curl_easy_setopt(curl, CURLOPT_NOBODY, 0); The new way doesn't alter the method until the request is about to start. If CURLOPT_NOBODY is then 1 the HTTP request will be HEAD. If CURLOPT_NOBODY is 0 and the request happens to have been set to HEAD, it will then instead be set to GET. I believe this will be less surprising to users, and hopefully not hit any existing users badly. --- lib/url.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 22b8f7dfd..5c87a3873 100644 --- a/lib/url.c +++ b/lib/url.c @@ -887,13 +887,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Do not include the body part in the output data stream. */ data->set.opt_no_body = (bool)(0 != va_arg(param, long)); - - /* in HTTP lingo, no body means using the HEAD request and if unset there - really is no perfect method that is the "opposite" of HEAD but in - reality most people probably think GET then. The important thing is - that we can't let it remain HEAD if the opt_no_body is set FALSE since - then we'll behave wrong when getting HTTP. */ - data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET; break; case CURLOPT_FAILONERROR: /* @@ -909,12 +902,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * using the PUT request. */ data->set.upload = (bool)(0 != va_arg(param, long)); - if(data->set.upload) + if(data->set.upload) { /* If this is HTTP, PUT is what's needed to "upload" */ data->set.httpreq = HTTPREQ_PUT; + data->set.opt_no_body = FALSE; /* this is implied */ + } else - /* In HTTP, the opposite of upload is either GET or a HEAD */ - data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET; + /* In HTTP, the opposite of upload is GET (unless NOBODY is true as + then this can be changed to HEAD later on) */ + data->set.httpreq = HTTPREQ_GET; break; case CURLOPT_FILETIME: /* @@ -4872,6 +4868,17 @@ static CURLcode do_init(struct connectdata *conn) conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ data->state.expect100header = FALSE; + if(data->set.opt_no_body) + /* in HTTP lingo, no body means using the HEAD request... */ + data->set.httpreq = HTTPREQ_HEAD; + else if(HTTPREQ_HEAD == data->set.httpreq) + /* ... but if unset there really is no perfect method that is the + "opposite" of HEAD but in reality most people probably think GET + then. The important thing is that we can't let it remain HEAD if the + opt_no_body is set FALSE since then we'll behave wrong when getting + HTTP. */ + data->set.httpreq = HTTPREQ_GET; + /* NB: the content encoding software depends on this initialization */ Curl_easy_initHandleData(data); -- cgit v1.2.1 From 33a3753c3f41d546ebf3350685eb7201d25783f4 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 21 Apr 2009 11:46:16 +0000 Subject: libcurl's memory.h renamed to curl_memory.h --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5c87a3873..f177b7ffe 100644 --- a/lib/url.c +++ b/lib/url.c @@ -135,7 +135,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #define _MPRINTF_REPLACE /* use our functions only */ #include -#include "memory.h" +#include "curl_memory.h" /* The last #include file should be: */ #include "memdebug.h" -- cgit v1.2.1 From e84c7db0497478b41f435f047d7b0e75b9289bb6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 8 May 2009 10:59:40 +0000 Subject: - Constantine Sapuntzakis fixed bug report #2784055 (http://curl.haxx.se/bug/view.cgi?id=2784055) identifying a problem to connect to SOCKS proxies when using the multi interface. It turned out to almost not work at all previously. We need to wait for the TCP connect to be properly verified before doing the SOCKS magic. There's still a flaw in the FTP code for this. --- lib/url.c | 80 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 32 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f177b7ffe..684358067 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2814,6 +2814,47 @@ ConnectionStore(struct SessionHandle *data, return i; } +/* after a TCP connection to the proxy has been verified, this function does + the next magic step. + + Note: this function (and its sub-functions) calls failf() + +*/ +CURLcode Curl_connected_proxy(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct SessionHandle *data = conn->data; + + switch(data->set.proxytype) { +#ifndef CURL_DISABLE_PROXY + case CURLPROXY_SOCKS5: + case CURLPROXY_SOCKS5_HOSTNAME: + result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, + conn->host.name, conn->remote_port, + FIRSTSOCKET, conn); + break; + case CURLPROXY_SOCKS4: + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, FALSE); + break; + case CURLPROXY_SOCKS4A: + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, TRUE); + break; +#endif /* CURL_DISABLE_PROXY */ + case CURLPROXY_HTTP: + case CURLPROXY_HTTP_1_0: + /* do nothing here. handled later. */ + break; + default: + failf(data, "unknown proxytype option given"); + result = CURLE_COULDNT_CONNECT; + break; + } /* switch proxytype */ + + return result; +} + static CURLcode ConnectPlease(struct SessionHandle *data, struct connectdata *conn, struct Curl_dns_entry *hostaddr, @@ -2838,39 +2879,14 @@ static CURLcode ConnectPlease(struct SessionHandle *data, &addr, connected); if(CURLE_OK == result) { - /* All is cool, then we store the current information */ + /* All is cool, we store the current information */ conn->dns_entry = hostaddr; conn->ip_addr = addr; - switch(data->set.proxytype) { -#ifndef CURL_DISABLE_PROXY - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, - conn->host.name, conn->remote_port, - FIRSTSOCKET, conn); - break; - case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, FALSE); - break; - case CURLPROXY_SOCKS4A: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, TRUE); - break; -#endif /* CURL_DISABLE_PROXY */ - case CURLPROXY_HTTP: - case CURLPROXY_HTTP_1_0: - /* do nothing here. handled later. */ - break; - default: - failf(data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - break; - } /* switch proxytype */ - } /* if result is ok */ - - if(result) + if(*connected) + result = Curl_connected_proxy(conn); + } + else *connected = FALSE; /* mark it as not connected */ return result; @@ -4761,8 +4777,6 @@ CURLcode Curl_done(struct connectdata **connp, Curl_expire(data, 0); /* stop timer */ - Curl_getoff_all_pipelines(data, conn); - if(conn->bits.done || (conn->send_pipe->size + conn->recv_pipe->size != 0 && !data->set.reuse_forbid && @@ -4773,6 +4787,8 @@ CURLcode Curl_done(struct connectdata **connp, conn->bits.done = TRUE; /* called just now! */ + Curl_getoff_all_pipelines(data, conn); + /* Cleanup possible redirect junk */ if(data->req.newurl) { free(data->req.newurl); -- cgit v1.2.1 From fd5e69f7697c1230b618693ffa697e409a202271 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 9 May 2009 21:34:48 +0000 Subject: ConnectPlease() fixed for the new proxy connect functionality to make sure 'connected' truly is false when the socks connect fails. Curl_done() fixed for the check-conn->bits.done-before-Curl_getoff_all_pipelines case --- lib/url.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 684358067..402a49151 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2886,7 +2886,8 @@ static CURLcode ConnectPlease(struct SessionHandle *data, if(*connected) result = Curl_connected_proxy(conn); } - else + + if(result) *connected = FALSE; /* mark it as not connected */ return result; @@ -4777,18 +4778,21 @@ CURLcode Curl_done(struct connectdata **connp, Curl_expire(data, 0); /* stop timer */ - if(conn->bits.done || - (conn->send_pipe->size + conn->recv_pipe->size != 0 && + if(conn->bits.done) + /* Stop if Curl_done() has already been called */ + return CURLE_OK; + + Curl_getoff_all_pipelines(data, conn); + + if((conn->send_pipe->size + conn->recv_pipe->size != 0 && !data->set.reuse_forbid && !conn->bits.close)) - /* Stop if Curl_done() has already been called or pipeline - is not empty and we do not have to close connection. */ + /* Stop if pipeline is not empty and we do not have to close + connection. */ return CURLE_OK; conn->bits.done = TRUE; /* called just now! */ - Curl_getoff_all_pipelines(data, conn); - /* Cleanup possible redirect junk */ if(data->req.newurl) { free(data->req.newurl); -- cgit v1.2.1 From f04720afb8e0fd1a5065fb5aa833dbc5e6417698 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 May 2009 11:45:56 +0000 Subject: fix the Curl_connected_proxy function for when libcurl actually connects fine to it in the actual connect call and not asynchronously. --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 402a49151..1395998d0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2825,6 +2825,12 @@ CURLcode Curl_connected_proxy(struct connectdata *conn) CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; + if(conn->bits.tcpconnect) + /* allow this to get called again from the multi interface when TCP is + found connected in the state machine, even though it has already been + called if the connection happened "instantly" */ + return CURLE_OK; + switch(data->set.proxytype) { #ifndef CURL_DISABLE_PROXY case CURLPROXY_SOCKS5: -- cgit v1.2.1 From 611b3584d69c74914eabd1c77f26ac1a82bcbd1f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 12 May 2009 07:38:31 +0000 Subject: make no proxy set return OK from Curl_connected_proxy() since it will be called unconditionally --- lib/url.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1395998d0..ee67578bd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2853,9 +2853,7 @@ CURLcode Curl_connected_proxy(struct connectdata *conn) /* do nothing here. handled later. */ break; default: - failf(data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - break; + break; } /* switch proxytype */ return result; -- cgit v1.2.1 From 3cb06eb2b2e80795d8f97d1fcfdcb8f1d01f02ce Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 May 2009 14:47:50 +0000 Subject: - James Bursa posted a patch to the mailing list that fixed a problem with no_proxy which made it not skip the proxy if the URL entered contained a user name. I added test case 1101 to verify. --- lib/url.c | 77 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 39 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ee67578bd..88f797296 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4316,6 +4316,44 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } + /************************************************************* + * No protocol part in URL was used, add it! + *************************************************************/ + if(conn->protocol&PROT_MISSING) { + /* We're guessing prefixes here and if we're told to use a proxy or if + we're gonna follow a Location: later or... then we need the protocol + part added so that we have a valid URL. */ + char *reurl; + + reurl = aprintf("%s://%s", conn->protostr, data->change.url); + + if(!reurl) { + Curl_safefree(proxy); + return CURLE_OUT_OF_MEMORY; + } + + data->change.url = reurl; + data->change.url_alloc = TRUE; /* free this later */ + conn->protocol &= ~PROT_MISSING; /* switch that one off again */ + } + + /************************************************************* + * Setup internals depending on protocol + *************************************************************/ + result = setup_connection_internals(data, conn); + if(result != CURLE_OK) { + Curl_safefree(proxy); + return result; + } + + /************************************************************* + * Parse a user name and password in the URL and strip it out + * of the host name + *************************************************************/ + result = parse_url_userpass(data, conn, user, passwd); + if(result != CURLE_OK) + return result; + #ifndef CURL_DISABLE_PROXY /************************************************************* * Extract the user and password from the authentication string @@ -4371,37 +4409,6 @@ static CURLcode create_conn(struct SessionHandle *data, } #endif /* CURL_DISABLE_PROXY */ - /************************************************************* - * No protocol part in URL was used, add it! - *************************************************************/ - if(conn->protocol&PROT_MISSING) { - /* We're guessing prefixes here and if we're told to use a proxy or if - we're gonna follow a Location: later or... then we need the protocol - part added so that we have a valid URL. */ - char *reurl; - - reurl = aprintf("%s://%s", conn->protostr, data->change.url); - - if(!reurl) { - Curl_safefree(proxy); - return CURLE_OUT_OF_MEMORY; - } - - data->change.url = reurl; - data->change.url_alloc = TRUE; /* free this later */ - conn->protocol &= ~PROT_MISSING; /* switch that one off again */ - } - - /************************************************************* - * Setup internals depending on protocol - *************************************************************/ - result = setup_connection_internals(data, conn); - if(result != CURLE_OK) { - Curl_safefree(proxy); - return result; - } - - #ifndef CURL_DISABLE_PROXY /*********************************************************************** * If this is supposed to use a proxy, we need to figure out the proxy @@ -4462,14 +4469,6 @@ static CURLcode create_conn(struct SessionHandle *data, if((conn->protocol&PROT_SSL) && conn->bits.httpproxy) conn->bits.tunnel_proxy = TRUE; - /************************************************************* - * Parse a user name and password in the URL and strip it out - * of the host name - *************************************************************/ - result = parse_url_userpass(data, conn, user, passwd); - if(result != CURLE_OK) - return result; - /************************************************************* * Figure out the remote port number and fix it in the URL *************************************************************/ -- cgit v1.2.1 From bf07d37737e179ff2ded90b8303bb65c227a8615 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 27 May 2009 21:45:12 +0000 Subject: - Mike Crowe pointed out that setting CURLOPT_USERPWD to NULL used to clear the auth credentials back in 7.19.0 and earlier while now you have to set "" to get the same effect. His patch brings back the ability to use NULL. --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 88f797296..a97176495 100644 --- a/lib/url.c +++ b/lib/url.c @@ -275,8 +275,14 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, char* separator; CURLcode result = CURLE_OK; - if(!option) - return result; + if(!option) { + /* we treat a NULL passed in as a hint to clear existing info */ + Curl_safefree(*user_storage); + *user_storage = (char *) NULL; + Curl_safefree(*pwd_storage); + *pwd_storage = (char *) NULL; + return CURLE_OK; + } separator = strchr(option, ':'); if (separator != NULL) { -- cgit v1.2.1 From f13cbcf17568fcfdd4160448ceb84e2e0a0704ee Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 28 May 2009 16:18:25 +0000 Subject: fix compiler warning: unused parameter --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a97176495..bba34ff2c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2878,6 +2878,8 @@ static CURLcode ConnectPlease(struct SessionHandle *data, infof(data, "About to connect() to %s%s port %d (#%d)\n", conn->bits.proxy?"proxy ":"", hostname, conn->port, conn->connectindex); +#else + (void)data; #endif /************************************************************* -- cgit v1.2.1 From c9188e22609a453a0b67109328e0aa8fa040ef0b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 29 May 2009 07:43:43 +0000 Subject: corrected comments --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bba34ff2c..c17c226be 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1842,14 +1842,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_SSLKEY: /* - * String that holds file name of the SSL certificate to use + * String that holds file name of the SSL key to use */ result = setstropt(&data->set.str[STRING_KEY], va_arg(param, char *)); break; case CURLOPT_SSLKEYTYPE: /* - * String that holds file type of the SSL certificate to use + * String that holds file type of the SSL key to use */ result = setstropt(&data->set.str[STRING_KEY_TYPE], va_arg(param, char *)); -- cgit v1.2.1 From 2c166812253c28cdfbffdd4de069f5c11db3c7a8 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 10 Jun 2009 02:49:42 +0000 Subject: Adjusted to take in account that... With the curl memory tracking feature decoupled from the debug build feature, CURLDEBUG and DEBUGBUILD preprocessor symbol definitions are used as follows: CURLDEBUG used for curl debug memory tracking specific code (--enable-curldebug) DEBUGBUILD used for debug enabled specific code (--enable-debug) --- lib/url.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c17c226be..0337ea867 100644 --- a/lib/url.c +++ b/lib/url.c @@ -380,7 +380,7 @@ CURLcode Curl_close(struct SessionHandle *data) { struct Curl_multi *m = data->multi; -#ifdef CURLDEBUG +#ifdef DEBUGBUILD /* only for debugging, scan through all connections and see if there's a pipe reference still identifying this handle */ @@ -2310,7 +2310,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) return CURLE_OK; } -#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) +#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, NULL, Curl_scan_cache_used); @@ -2431,7 +2431,7 @@ bool Curl_isPipeliningEnabled(const struct SessionHandle *handle) CURLcode Curl_addHandleToPipeline(struct SessionHandle *data, struct curl_llist *pipeline) { -#ifdef CURLDEBUG +#ifdef DEBUGBUILD if(!IsPipeliningPossible(data)) { /* when not pipelined, there MUST be no handle in the list already */ if(pipeline->head) @@ -2514,7 +2514,7 @@ static void signalPipeClose(struct curl_llist *pipeline) struct curl_llist_element *next = curr->next; struct SessionHandle *data = (struct SessionHandle *) curr->ptr; -#ifdef CURLDEBUG /* debug-only code */ +#ifdef DEBUGBUILD /* debug-only code */ if(data->magic != CURLEASY_MAGIC_NUMBER) { /* MAJOR BADNESS */ infof(data, "signalPipeClose() found BAAD easy handle\n"); @@ -2596,7 +2596,7 @@ ConnectionExists(struct SessionHandle *data, continue; } -#ifdef CURLDEBUG +#ifdef DEBUGBUILD if(pipeLen > MAX_PIPELINE_LENGTH) { infof(data, "BAD! Connection #%ld has too big pipeline!\n", check->connectindex); @@ -2626,7 +2626,7 @@ ConnectionExists(struct SessionHandle *data, get closed. */ infof(data, "Connection #%ld isn't open enough, can't reuse\n", check->connectindex); -#ifdef CURLDEBUG +#ifdef DEBUGBUILD if(check->recv_pipe->size > 0) { infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", check->connectindex); -- cgit v1.2.1 From 352177090f710fd155d22a79d11f621482c09640 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 10 Jun 2009 21:26:11 +0000 Subject: - Fabian Keil ran clang on the (lib)curl code, found a bunch of warnings and contributed a range of patches to fix them. --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0337ea867..1ef52e8ec 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3489,7 +3489,6 @@ static bool check_noproxy(const char* name, const char* no_proxy) else namelen = strlen(name); - tok_start = 0; for (tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { while (tok_start < no_proxy_len && strchr(separator, no_proxy[tok_start]) != NULL) { -- cgit v1.2.1 From 4ea513cc387c0a67c861a87aea01e6d1cac4854c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 12 Jun 2009 02:41:16 +0000 Subject: fix compiler warning --- lib/url.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1ef52e8ec..840eefeb7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -531,22 +531,23 @@ struct conncache *Curl_mk_connc(int type, struct conncache *c; long default_amount; + long max_amount = (long)(((size_t)INT_MAX) / sizeof(struct connectdata *)); if(type == CONNCACHE_PRIVATE) { - default_amount = (amount < 0) ? 5 : amount; + default_amount = (amount < 1L) ? 5L : amount; } else { - default_amount = (amount < 0) ? 10 : amount; + default_amount = (amount < 1L) ? 10L : amount; } - c= calloc(sizeof(struct conncache), 1); + if(default_amount > max_amount) + default_amount = max_amount; + + c = calloc(1, sizeof(struct conncache)); if(!c) return NULL; - if((size_t)(default_amount) > ((size_t)-1) / sizeof(struct connectdata *)) - default_amount = ((size_t)-1) / sizeof(struct connectdata *); - - c->connects = calloc(sizeof(struct connectdata *), (size_t)default_amount); + c->connects = calloc((size_t)default_amount, sizeof(struct connectdata *)); if(!c->connects) { free(c); return NULL; @@ -564,6 +565,7 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, { long i; struct connectdata **newptr; + long max_amount = (long)(((size_t)INT_MAX) / sizeof(struct connectdata *)); if(newamount < 1) newamount = 1; /* we better have at least one entry */ @@ -596,6 +598,8 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, data->state.lastconnect = -1; } if(newamount > 0) { + if(newamount > max_amount) + newamount = max_amount; newptr = realloc(c->connects, sizeof(struct connectdata *) * newamount); if(!newptr) /* we closed a few connections in vain, but so what? */ -- cgit v1.2.1 From 47e403640baebb0df05639628c8aa5dfa77f76f4 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 12 Jun 2009 02:47:35 +0000 Subject: include for INT_MAX definition --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 840eefeb7..cd79866c7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -76,6 +76,10 @@ #endif /* WIN32 */ +#ifdef HAVE_LIMITS_H +#include +#endif + #ifdef USE_LIBIDN #include #include -- cgit v1.2.1 From 0b317b72ae6f23eb4dbd0a22509a20ff5acb2958 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 16 Jun 2009 13:16:28 +0000 Subject: - When doing non-anonymous ftp via http proxies and the password is not provided in the url, add it there (squid needs this). --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cd79866c7..11e336c0f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3831,6 +3831,7 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, * set user/passwd, but doing that first adds more cases here :-( */ + conn->bits.userpwd_in_url = 1; if(data->set.use_netrc != CURL_NETRC_REQUIRED) { /* We could use the one in the URL */ -- cgit v1.2.1 From 47c392e135f17d400acc5d7e99b88d16578cb406 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 22 Jul 2009 22:49:01 +0000 Subject: - Added CURLOPT_SSH_KNOWNHOSTS, CURLOPT_SSH_KEYFUNCTION, CURLOPT_SSH_KEYDATA. They introduce known_host support for SSH keys to libcurl. See docs for details. --- lib/url.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 11e336c0f..5f209fe5e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2169,6 +2169,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ssl.sessionid = (bool)(0 != va_arg(param, long)); break; +#ifdef USE_LIBSSH2 + /* we only include SSH options if explicitly built to support SSH */ case CURLOPT_SSH_AUTH_TYPES: data->set.ssh_auth_types = va_arg(param, long); break; @@ -2196,6 +2198,31 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], va_arg(param, char *)); break; +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + case CURLOPT_SSH_KNOWNHOSTS: + /* + * Store the file name to read known hosts from. + */ + result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], + va_arg(param, char *)); + break; + + case CURLOPT_SSH_KEYFUNCTION: + /* setting to NULL is fine since the ssh.c functions themselves will + then rever to use the internal default */ + data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback); + break; + + case CURLOPT_SSH_KEYDATA: + /* + * Custom client data to pass to the SSH keyfunc callback + */ + data->set.ssh_keyfunc_userp = va_arg(param, void *); + break; +#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ + +#endif /* USE_LIBSSH2 */ + case CURLOPT_HTTP_TRANSFER_DECODING: /* * disable libcurl transfer encoding is used -- cgit v1.2.1 From 2642638fcae2c51a3407f0af6a90b3c6aca895f5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 1 Aug 2009 11:02:10 +0000 Subject: - Alexander Beedie provided the patch for a noproxy problem: If I have set CURLOPT_NOPROXY to "*", or to a host that should not use a proxy, I actually could still end up using a proxy if a proxy environment variable was set. --- lib/url.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5f209fe5e..96db7e481 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4419,14 +4419,17 @@ static CURLcode create_conn(struct SessionHandle *data, } } - if(!proxy) - proxy = detect_proxy(conn); - else if(data->set.str[STRING_NOPROXY]) { - if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) { + + if(data->set.str[STRING_NOPROXY] && + check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) { + if(proxy) { free(proxy); /* proxy is in exception list */ proxy = NULL; } } + else if(!proxy) + proxy = detect_proxy(conn); + if(proxy && !*proxy) { free(proxy); /* Don't bother with an empty proxy string */ proxy = NULL; -- cgit v1.2.1 From 171eef68c3d0e683acc0f422978e28d1d01cf41f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Aug 2009 20:43:12 +0000 Subject: - Benbuck Nason posted the bug report #2835196 (http://curl.haxx.se/bug/view.cgi?id=2835196), fixing a few compiler warnings when mixing ints and bools. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 96db7e481..ae2917548 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3862,7 +3862,7 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, if(data->set.use_netrc != CURL_NETRC_REQUIRED) { /* We could use the one in the URL */ - conn->bits.user_passwd = 1; /* enable user+password */ + conn->bits.user_passwd = TRUE; /* enable user+password */ if(*userpass != ':') { /* the name is given, get user+password */ @@ -4027,7 +4027,7 @@ static void override_userpass(struct SessionHandle *data, different host or similar. */ conn->bits.netrc = TRUE; - conn->bits.user_passwd = 1; /* enable user+password */ + conn->bits.user_passwd = TRUE; /* enable user+password */ } } } -- cgit v1.2.1 From 1048043963d5487ed4d70f426a85aff07c2ee5f1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 21 Aug 2009 07:11:20 +0000 Subject: - Lots of good work by Krister Johansen, mostly related to pipelining: Fix SIGSEGV on free'd easy_conn when pipe unexpectedly breaks Fix data corruption issue with re-connected transfers Fix use after free if we're completed but easy_conn not NULL --- lib/url.c | 88 +++++++++++++++++++++++++++------------------------------------ 1 file changed, 37 insertions(+), 51 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ae2917548..011f6c4d7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -146,7 +146,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by /* Local static prototypes */ static long ConnectionKillOne(struct SessionHandle *data); static void conn_free(struct connectdata *conn); -static void signalPipeClose(struct curl_llist *pipeline); +static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); #ifdef CURL_DISABLE_VERBOSE_STRINGS #define verboseconnect(x) do { } while (0) @@ -420,6 +420,16 @@ CURLcode Curl_close(struct SessionHandle *data) } } } + pipeline = connptr->done_pipe; + if(pipeline) { + for (curr = pipeline->head; curr; curr=curr->next) { + if(data == (struct SessionHandle *) curr->ptr) { + fprintf(stderr, + "MAJOR problem we %p are still in done pipe for %p done %d\n", + data, connptr, (int)connptr->bits.done); + } + } + } pipeline = connptr->pend_pipe; if(pipeline) { for (curr = pipeline->head; curr; curr=curr->next) { @@ -2316,6 +2326,7 @@ static void conn_free(struct connectdata *conn) Curl_llist_destroy(conn->send_pipe, NULL); Curl_llist_destroy(conn->recv_pipe, NULL); Curl_llist_destroy(conn->pend_pipe, NULL); + Curl_llist_destroy(conn->done_pipe, NULL); /* possible left-overs from the async name resolvers */ #if defined(USE_ARES) @@ -2415,9 +2426,10 @@ CURLcode Curl_disconnect(struct connectdata *conn) /* Indicate to all handles on the pipe that we're dead */ if(Curl_isPipeliningEnabled(data)) { - signalPipeClose(conn->send_pipe); - signalPipeClose(conn->recv_pipe); - signalPipeClose(conn->pend_pipe); + signalPipeClose(conn->send_pipe, TRUE); + signalPipeClose(conn->recv_pipe, TRUE); + signalPipeClose(conn->pend_pipe, TRUE); + signalPipeClose(conn->done_pipe, FALSE); } conn_free(conn); @@ -2535,9 +2547,10 @@ void Curl_getoff_all_pipelines(struct SessionHandle *data, if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head) conn->writechannel_inuse = FALSE; Curl_removeHandleFromPipeline(data, conn->pend_pipe); + Curl_removeHandleFromPipeline(data, conn->done_pipe); } -static void signalPipeClose(struct curl_llist *pipeline) +static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke) { struct curl_llist_element *curr; @@ -2556,7 +2569,8 @@ static void signalPipeClose(struct curl_llist *pipeline) } #endif - data->state.pipe_broke = TRUE; + if (pipe_broke) + data->state.pipe_broke = TRUE; Curl_multi_handlePipeBreak(data); Curl_llist_remove(pipeline, curr, NULL); curr = next; @@ -4217,6 +4231,7 @@ static void reuse_conn(struct connectdata *old_conn, Curl_llist_destroy(old_conn->send_pipe, NULL); Curl_llist_destroy(old_conn->recv_pipe, NULL); Curl_llist_destroy(old_conn->pend_pipe, NULL); + Curl_llist_destroy(old_conn->done_pipe, NULL); Curl_safefree(old_conn->master_buffer); } @@ -4319,7 +4334,9 @@ static CURLcode create_conn(struct SessionHandle *data, conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe) + conn->done_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe || + !conn->done_pipe) return CURLE_OUT_OF_MEMORY; /* This initing continues below, see the comment "Continue connectdata @@ -5001,53 +5018,22 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) /* This was formerly done in transfer.c, but we better do it here */ if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { - /* This was a re-use of a connection and we got a write error in the - * DO-phase. Then we DISCONNECT this connection and have another attempt - * to CONNECT and then DO again! The retry cannot possibly find another - * connection to re-use, since we only keep one possible connection for - * each. */ - - infof(data, "Re-used connection seems dead, get a new one\n"); - - conn->bits.close = TRUE; /* enforce close of this connection */ - result = Curl_done(&conn, result, FALSE); /* we are so done with this */ - - /* conn may no longer be a good pointer */ + /* + * If the connection is using an easy handle, call reconnect + * to re-establish the connection. Otherwise, let the multi logic + * figure out how to re-establish the connection. + */ + if(!data->multi) { + result = Curl_reconnect_request(connp); - /* - * According to bug report #1330310. We need to check for - * CURLE_SEND_ERROR here as well. I figure this could happen when the - * request failed on a FTP connection and thus Curl_done() itself tried - * to use the connection (again). Slight Lack of feedback in the report, - * but I don't think this extra check can do much harm. - */ - if((CURLE_OK == result) || (CURLE_SEND_ERROR == result)) { - bool async; - bool protocol_done = TRUE; - - /* Now, redo the connect and get a new connection */ - result = Curl_connect(data, connp, &async, &protocol_done); - if(CURLE_OK == result) { - /* We have connected or sent away a name resolve query fine */ - - conn = *connp; /* setup conn to again point to something nice */ - if(async) { - /* Now, if async is TRUE here, we need to wait for the name - to resolve */ - result = Curl_wait_for_resolv(conn, NULL); - if(result) - return result; - - /* Resolved, continue with the connection */ - result = Curl_async_resolved(conn, &protocol_done); - if(result) - return result; + if(result == CURLE_OK) { + /* ... finally back to actually retry the DO phase */ + result = conn->handler->do_it(conn, done); } - - /* ... finally back to actually retry the DO phase */ - result = conn->handler->do_it(conn, done); } - } + else { + return result; + } } if((result == CURLE_OK) && *done) -- cgit v1.2.1 From 31e106ced2b37e1cb1b54f9f5f5d56df82577ede Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 17 Sep 2009 11:45:27 +0000 Subject: Attempt to silence bogus compiler warning: "Potential null pointer dereference" --- lib/url.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 011f6c4d7..729149c3d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3946,9 +3946,11 @@ static CURLcode parse_remote_port(struct SessionHandle *data, conn->host.name++; /* skip over the starting bracket */ portptr = strchr(conn->host.name, ']'); - *portptr++ = 0; /* zero terminate, killing the bracket */ - if(':' != *portptr) - portptr = NULL; /* no port number available */ + if(portptr) { + *portptr++ = '\0'; /* zero terminate, killing the bracket */ + if(':' != *portptr) + portptr = NULL; /* no port number available */ + } } else portptr = strrchr(conn->host.name, ':'); -- cgit v1.2.1 From 0077a6d51bf9cd9153cdf76cbb14a3cc72ad7e8e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 8 Oct 2009 12:44:25 +0000 Subject: Attempt to silence bogus compiler warning: "Potential null pointer dereference" --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 729149c3d..8f425d4e2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3681,7 +3681,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, char *endofprot; /* We use 'proxyptr' to point to the proxy name from now on... */ - char *proxyptr=proxy; + char *proxyptr; char *portptr; char *atsign; @@ -3691,9 +3691,11 @@ static CURLcode parse_proxy(struct SessionHandle *data, */ /* Skip the protocol part if present */ - endofprot=strstr(proxyptr, "://"); + endofprot = strstr(proxy, "://"); if(endofprot) proxyptr = endofprot+3; + else + proxyptr = proxy; /* Is there a username and password given in this proxy url? */ atsign = strchr(proxyptr, '@'); -- cgit v1.2.1 From 90bc6ee8f38eec0dd6c7c8dbea22b0cba2998ee2 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 14 Nov 2009 02:30:30 +0000 Subject: - Constantine Sapuntzakis provided the fix that ensures that an SSL connection won't be reused unless protection level for peer and host verification match. --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8f425d4e2..d3ec1c074 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2689,6 +2689,12 @@ ConnectionExists(struct SessionHandle *data, /* don't do mixed SSL and non-SSL connections */ continue; + if(needle->protocol&PROT_SSL) { + if((data->set.ssl.verifypeer != check->verifypeer) || + (data->set.ssl.verifyhost != check->verifyhost)) + continue; + } + if(needle->bits.proxy != check->bits.proxy) /* don't do mixed proxy and non-proxy connections */ continue; @@ -4326,6 +4332,9 @@ static CURLcode create_conn(struct SessionHandle *data, conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + conn->verifypeer = data->set.ssl.verifypeer; + conn->verifyhost = data->set.ssl.verifyhost; + if(data->multi && Curl_multi_canPipeline(data->multi) && !conn->master_buffer) { /* Allocate master_buffer to be used for pipelining */ -- cgit v1.2.1 From b32d1a9a1d1d1d3f8c24b9aa439c9ce273c2049e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 17 Nov 2009 22:53:55 +0000 Subject: - Constantine Sapuntzakis provided another fix for the DNS cache that could end up with entries that wouldn't time-out: 1. Set up a first web server that redirects (307) to a http://server:port that's down 2. Have curl connect to the first web server using curl multi After the curl_easy_cleanup call, there will be curl dns entries hanging around with in_use != 0. (http://curl.haxx.se/bug/view.cgi?id=2891591) --- lib/url.c | 76 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 31 insertions(+), 45 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d3ec1c074..6cd1f60da 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2356,6 +2356,11 @@ CURLcode Curl_disconnect(struct connectdata *conn) return CURLE_OK; } + if(conn->dns_entry != NULL) { + Curl_resolv_unlock(data, conn->dns_entry); + conn->dns_entry = NULL; + } + #if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, @@ -2922,7 +2927,6 @@ CURLcode Curl_connected_proxy(struct connectdata *conn) static CURLcode ConnectPlease(struct SessionHandle *data, struct connectdata *conn, - struct Curl_dns_entry *hostaddr, bool *connected) { CURLcode result; @@ -2941,13 +2945,12 @@ static CURLcode ConnectPlease(struct SessionHandle *data, * Connect to server/proxy *************************************************************/ result= Curl_connecthost(conn, - hostaddr, + conn->dns_entry, &conn->sock[FIRSTSOCKET], &addr, connected); if(CURLE_OK == result) { /* All is cool, we store the current information */ - conn->dns_entry = hostaddr; conn->ip_addr = addr; if(*connected) @@ -4086,7 +4089,6 @@ static CURLcode set_userpass(struct connectdata *conn, *************************************************************/ static CURLcode resolve_server(struct SessionHandle *data, struct connectdata *conn, - struct Curl_dns_entry **addr, bool *async) { CURLcode result=CURLE_OK; @@ -4119,9 +4121,8 @@ static CURLcode resolve_server(struct SessionHandle *data, * Resolve the name of the server or proxy *************************************************************/ if(conn->bits.reuse) { - /* re-used connection, no resolving is necessary */ - *addr = NULL; - /* we'll need to clear conn->dns_entry later in Curl_disconnect() */ + /* We're reusing the connection - no need to resolve anything */ + *async = FALSE; if(conn->bits.proxy) fix_hostname(data, conn, &conn->host); @@ -4176,7 +4177,8 @@ static CURLcode resolve_server(struct SessionHandle *data, /* don't return yet, we need to clean up the timeout first */ } } - *addr = hostaddr; + DEBUGASSERT(conn->dns_entry == NULL); + conn->dns_entry = hostaddr; } return result; @@ -4255,10 +4257,7 @@ static void reuse_conn(struct connectdata *old_conn, * * @param data The sessionhandle pointer * @param in_connect is set to the next connection data pointer - * @param addr is set to the new dns entry for this connection. If this - * connection is re-used it will be NULL. - * @param async is set TRUE/FALSE depending on the nature of this lookup - * @return CURLcode + * @param async is set TRUE when an async DNS resolution is pending * @see setup_conn() * * *NOTE* this function assigns the conn->data pointer! @@ -4266,7 +4265,6 @@ static void reuse_conn(struct connectdata *old_conn, static CURLcode create_conn(struct SessionHandle *data, struct connectdata **in_connect, - struct Curl_dns_entry **addr, bool *async) { CURLcode result=CURLE_OK; @@ -4278,9 +4276,8 @@ static CURLcode create_conn(struct SessionHandle *data, bool reuse; char *proxy = NULL; - *addr = NULL; /* nothing yet */ *async = FALSE; - + /************************************************************* * Check input data *************************************************************/ @@ -4646,7 +4643,7 @@ static CURLcode create_conn(struct SessionHandle *data, /************************************************************* * Resolve the address of the server or proxy *************************************************************/ - result = resolve_server(data, conn, addr, async); + result = resolve_server(data, conn, async); return result; } @@ -4654,14 +4651,12 @@ static CURLcode create_conn(struct SessionHandle *data, /* setup_conn() is called after the name resolve initiated in * create_conn() is all done. * - * NOTE: the argument 'hostaddr' is NULL when this function is called for a - * re-used connection. - * + * setup_conn() also handles reused connections + * * conn->data MUST already have been setup fine (in create_conn) */ static CURLcode setup_conn(struct connectdata *conn, - struct Curl_dns_entry *hostaddr, bool *protocol_done) { CURLcode result=CURLE_OK; @@ -4706,15 +4701,10 @@ static CURLcode setup_conn(struct connectdata *conn, /* loop for CURL_SERVER_CLOSED_CONNECTION */ if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { + /* Try to connect only if not already connected */ bool connected = FALSE; - /* Connect only if not already connected! - * - * NOTE: hostaddr can be NULL when passed to this function, but that is - * only for the case where we re-use an existing connection and thus - * this code section will not be reached with hostaddr == NULL. - */ - result = ConnectPlease(data, conn, hostaddr, &connected); + result = ConnectPlease(data, conn, &connected); if(connected) { result = Curl_protocol_connect(conn, protocol_done); @@ -4775,33 +4765,22 @@ CURLcode Curl_connect(struct SessionHandle *data, bool *protocol_done) { CURLcode code; - struct Curl_dns_entry *dns; *asyncp = FALSE; /* assume synchronous resolves by default */ /* call the stuff that needs to be called */ - code = create_conn(data, in_connect, &dns, asyncp); + code = create_conn(data, in_connect, asyncp); if(CURLE_OK == code) { /* no error */ if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size) /* pipelining */ *protocol_done = TRUE; - else { - - if(dns || !*asyncp) - /* If an address is available it means that we already have the name - resolved, OR it isn't async. if this is a re-used connection 'dns' - will be NULL here. Continue connecting from here */ - code = setup_conn(*in_connect, dns, protocol_done); - - if(dns && code) { - /* We have the dns entry info already but failed to connect to the - * host and thus we must make sure to unlock the dns entry again - * before returning failure from here. - */ - Curl_resolv_unlock(data, dns); - } + else if (!*asyncp) { + /* DNS resolution is done: that's either because this is a reused + connection, in which case DNS was unnecessary, or because DNS + really did finish already (synch resolver/fast async resolve) */ + code = setup_conn(*in_connect, protocol_done); } } @@ -4825,7 +4804,14 @@ CURLcode Curl_async_resolved(struct connectdata *conn, { #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ defined(USE_THREADING_GETADDRINFO) - CURLcode code = setup_conn(conn, conn->async.dns, protocol_done); + CURLcode code; + + if(conn->async.dns) { + conn->dns_entry = conn->async.dns; + conn->async.dns = NULL; + } + + code = setup_conn(conn, protocol_done); if(code) /* We're not allowed to return failure with memory left allocated -- cgit v1.2.1 From a41493b3b0eaa83a907b4c3dbbab1297791ead97 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 20 Nov 2009 13:27:21 +0000 Subject: - Jad Chamcham pointed out a bug with connection re-use. If a connection had CURLOPT_HTTPPROXYTUNNEL enabled over a proxy, a subsequent request using the same proxy with the tunnel option disabled would still wrongly re-use that previous connection and the outcome would only be badness. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6cd1f60da..54d2ff929 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2758,6 +2758,7 @@ ConnectionExists(struct SessionHandle *data, is the checked one using the same host, port and type? */ if(check->bits.proxy && (needle->proxytype == check->proxytype) && + (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) && Curl_raw_equal(needle->proxy.name, check->proxy.name) && needle->port == check->port) { /* This is the same proxy connection, use it! */ -- cgit v1.2.1 From 504e6d7ae67a0aa72078fbeab208bf43c81b1f20 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 20 Nov 2009 19:32:49 +0000 Subject: - Constantine Sapuntzakis identified a write after close, as the sockets were closed by libcurl before the SSL lib were shutdown and they may write to its socket. Detected to at least happen with OpenSSL builds. --- lib/url.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 54d2ff929..edfa3edcc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2300,6 +2300,11 @@ static void conn_free(struct connectdata *conn) if(!conn) return; + /* close the SSL stuff before we close any sockets since they will/may + write to the sockets */ + Curl_ssl_close(conn, FIRSTSOCKET); + Curl_ssl_close(conn, SECONDARYSOCKET); + /* close possibly still open sockets */ if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) sclose(conn->sock[SECONDARYSOCKET]); @@ -2336,9 +2341,6 @@ static void conn_free(struct connectdata *conn) Curl_destroy_thread_data(&conn->async); #endif - Curl_ssl_close(conn, FIRSTSOCKET); - Curl_ssl_close(conn, SECONDARYSOCKET); - Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ -- cgit v1.2.1 From ec3bb8f727405642a471b4b1b9eb0118fc003104 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 12 Dec 2009 21:54:01 +0000 Subject: introducing IMAP, POP3 and SMTP support (still lots of polish left to do) --- lib/url.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index edfa3edcc..95ca31632 100644 --- a/lib/url.c +++ b/lib/url.c @@ -130,6 +130,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "file.h" #include "curl_ldap.h" #include "ssh.h" +#include "imap.h" #include "url.h" #include "connect.h" #include "inet_ntop.h" @@ -204,6 +205,27 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_sftp, #endif +#ifndef CURL_DISABLE_IMAP + &Curl_handler_imap, +#ifdef USE_SSL + &Curl_handler_imaps, +#endif +#endif + +#ifndef CURL_DISABLE_POP3 + &Curl_handler_pop3, +#ifdef USE_SSL + &Curl_handler_pop3s, +#endif +#endif + +#ifndef CURL_DISABLE_SMTP + &Curl_handler_smtp, +#ifdef USE_SSL + &Curl_handler_smtps, +#endif +#endif + (struct Curl_handler *) NULL }; @@ -950,12 +972,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.ftp_create_missing_dirs = (int)va_arg(param, long); break; - case CURLOPT_FTP_RESPONSE_TIMEOUT: + case CURLOPT_SERVER_RESPONSE_TIMEOUT: /* - * An FTP option that specifies how quickly an FTP response must be - * obtained before it is considered failure. + * Option that specifies how quickly an server response must be obtained + * before it is considered failure. For pingpong protocols. */ - data->set.ftp_response_timeout = va_arg( param , long ) * 1000; + data->set.server_response_timeout = va_arg( param , long ) * 1000; break; case CURLOPT_TFTP_BLKSIZE: /* @@ -2286,6 +2308,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK; break; + case CURLOPT_MAIL_FROM: + result = setstropt(&data->set.str[STRING_MAIL_FROM], + va_arg(param, char *)); + break; + + case CURLOPT_MAIL_RCPT: + result = setstropt(&data->set.str[STRING_MAIL_RCPT], + va_arg(param, char *)); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -3334,6 +3366,8 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, strcpy(conn->protostr, "DICT"); else if(checkprefix("LDAP.", conn->host.name)) strcpy(conn->protostr, "LDAP"); + else if(checkprefix("IMAP.", conn->host.name)) + strcpy(conn->protostr, "IMAP"); else { strcpy(conn->protostr, "http"); } @@ -4069,7 +4103,7 @@ static CURLcode set_userpass(struct connectdata *conn, const char *user, const char *passwd) { /* If our protocol needs a password and we have none, use the defaults */ - if( (conn->protocol & PROT_FTP) && + if( (conn->protocol & (PROT_FTP|PROT_IMAP)) && !conn->bits.user_passwd) { conn->user = strdup(CURL_DEFAULT_USER); -- cgit v1.2.1 From 3111701c38ee4d15df8e2d76dfcf945dbf2c0bfe Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 14 Dec 2009 23:16:09 +0000 Subject: - Jon Nelson found a regression that turned out to be a flaw in how libcurl detects and uses proxies based on the environment variables. If the proxy was given as an explicit option it worked, but due to the setup order mistake proxies would not be used fine for a few protocols when picked up from '[protocol]_proxy'. Obviously this broke after 7.19.4. I now also added test case 1106 that verifies this functionality. (http://curl.haxx.se/bug/view.cgi?id=2913886) --- lib/url.c | 63 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 30 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 95ca31632..907498db9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3242,6 +3242,7 @@ static struct connectdata *allocate_conn(void) conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->connectindex = -1; /* no index */ + conn->port = -1; /* unknown at this point */ /* Default protocol-independent behavior doesn't support persistent connections, so we set this to force-close. Protocols that support @@ -3498,7 +3499,8 @@ static CURLcode setup_range(struct SessionHandle *data) /*************************************************************** -* Setup connection internals specific to the requested protocol +* Setup connection internals specific to the requested protocol. +* This MUST get called after proxy magic has been figured out. ***************************************************************/ static CURLcode setup_connection_internals(struct SessionHandle *data, struct connectdata *conn) @@ -3537,7 +3539,10 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, p = conn->handler; /* May have changed. */ } - conn->port = p->defport; + if(conn->port < 0) + /* we check for -1 here since if proxy was detected already, this + was very likely already set to the proxy port */ + conn->port = p->defport; conn->remote_port = (unsigned short)p->defport; conn->protocol |= p->protocol; return CURLE_OK; @@ -4314,7 +4319,7 @@ static CURLcode create_conn(struct SessionHandle *data, char *proxy = NULL; *async = FALSE; - + /************************************************************* * Check input data *************************************************************/ @@ -4444,23 +4449,6 @@ static CURLcode create_conn(struct SessionHandle *data, conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } - /************************************************************* - * Setup internals depending on protocol - *************************************************************/ - result = setup_connection_internals(data, conn); - if(result != CURLE_OK) { - Curl_safefree(proxy); - return result; - } - - /************************************************************* - * Parse a user name and password in the URL and strip it out - * of the host name - *************************************************************/ - result = parse_url_userpass(data, conn, user, passwd); - if(result != CURLE_OK) - return result; - #ifndef CURL_DISABLE_PROXY /************************************************************* * Extract the user and password from the authentication string @@ -4483,7 +4471,6 @@ static CURLcode create_conn(struct SessionHandle *data, } } - if(data->set.str[STRING_NOPROXY] && check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) { if(proxy) { @@ -4511,15 +4498,13 @@ static CURLcode create_conn(struct SessionHandle *data, conn->bits.proxy = TRUE; } else { - /* we aren't using the proxy after all... */ - conn->bits.proxy = FALSE; - conn->bits.httpproxy = FALSE; - conn->bits.proxy_user_passwd = FALSE; - conn->bits.tunnel_proxy = FALSE; + /* we aren't using the proxy after all... */ + conn->bits.proxy = FALSE; + conn->bits.httpproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; } -#endif /* CURL_DISABLE_PROXY */ -#ifndef CURL_DISABLE_PROXY /*********************************************************************** * If this is supposed to use a proxy, we need to figure out the proxy * host name, so that we can re-use an existing connection @@ -4534,6 +4519,24 @@ static CURLcode create_conn(struct SessionHandle *data, } #endif /* CURL_DISABLE_PROXY */ + /************************************************************* + * Setup internals depending on protocol. Needs to be done after + * we figured out what/if proxy to use. + *************************************************************/ + result = setup_connection_internals(data, conn); + if(result != CURLE_OK) { + Curl_safefree(proxy); + return result; + } + + /************************************************************* + * Parse a user name and password in the URL and strip it out + * of the host name + *************************************************************/ + result = parse_url_userpass(data, conn, user, passwd); + if(result != CURLE_OK) + return result; + /*********************************************************************** * file: is a special case in that it doesn't need a network connection ***********************************************************************/ @@ -4689,7 +4692,7 @@ static CURLcode create_conn(struct SessionHandle *data, * create_conn() is all done. * * setup_conn() also handles reused connections - * + * * conn->data MUST already have been setup fine (in create_conn) */ @@ -4845,7 +4848,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, if(conn->async.dns) { conn->dns_entry = conn->async.dns; - conn->async.dns = NULL; + conn->async.dns = NULL; } code = setup_conn(conn, protocol_done); -- cgit v1.2.1 From 7603a29fc3db05d354b5adf41d69f781437704ca Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 16 Dec 2009 23:11:47 +0000 Subject: Follow-up fix for the proxy fix I did for Jon Nelson's bug. It turned out I was a bit too quick and broke test case 1101 with that change. The order of some of the setups is sensitive. I now changed it slightly again. --- lib/url.c | 139 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 60 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 907498db9..6e35b666f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3255,11 +3255,53 @@ static struct connectdata *allocate_conn(void) return conn; } +static CURLcode findprotocol(struct SessionHandle *data, + struct connectdata *conn) +{ + const struct Curl_handler * const *pp; + const struct Curl_handler *p; + + /* Scan protocol handler table and match against 'protostr' to set a few + variables based on the URL. Now that the handler may be changed later + when the protocol specific setup function is called. */ + for (pp = protocols; (p = *pp) != NULL; pp++) { + if(Curl_raw_equal(p->scheme, conn->protostr)) { + /* Protocol found in table. Check if allowed */ + if(!(data->set.allowed_protocols & p->protocol)) + /* nope, get out */ + break; + + /* it is allowed for "normal" request, now do an extra check if this is + the result of a redirect */ + if(data->state.this_is_a_follow && + !(data->set.redir_protocols & p->protocol)) + /* nope, get out */ + break; + + /* Perform setup complement if some. */ + conn->handler = p; + conn->protocol |= p->protocol; + + /* 'port' and 'remote_port' are set in setup_connection_internals() */ + return CURLE_OK; + } + } + + + /* The protocol was not found in the table, but we don't have to assign it + to anything since it is already assigned to a dummy-struct in the + create_conn() function when the connectdata struct is allocated. */ + failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME, + conn->protostr); + + return CURLE_UNSUPPORTED_PROTOCOL; +} + /* * Parse URL and fill in the relevant members of the connection struct. */ -static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, - struct connectdata *conn) +static CURLcode parseurlandfillconn(struct SessionHandle *data, + struct connectdata *conn) { char *at; char *tmp; @@ -3455,8 +3497,8 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data, * conn->host.name is B * data->state.path is /C */ - (void)rc; - return CURLE_OK; + + return findprotocol(data, conn); } static void llist_dtor(void *user, void *element) @@ -3502,10 +3544,8 @@ static CURLcode setup_range(struct SessionHandle *data) * Setup connection internals specific to the requested protocol. * This MUST get called after proxy magic has been figured out. ***************************************************************/ -static CURLcode setup_connection_internals(struct SessionHandle *data, - struct connectdata *conn) +static CURLcode setup_connection_internals(struct connectdata *conn) { - const struct Curl_handler * const * pp; const struct Curl_handler * p; CURLcode result; @@ -3513,47 +3553,26 @@ static CURLcode setup_connection_internals(struct SessionHandle *data, /* Scan protocol handler table. */ - for (pp = protocols; (p = *pp) != NULL; pp++) - if(Curl_raw_equal(p->scheme, conn->protostr)) { - /* Protocol found in table. Check if allowed */ - if(!(data->set.allowed_protocols & p->protocol)) - /* nope, get out */ - break; + /* Perform setup complement if some. */ + p = conn->handler; - /* it is allowed for "normal" request, now do an extra check if this is - the result of a redirect */ - if(data->state.this_is_a_follow && - !(data->set.redir_protocols & p->protocol)) - /* nope, get out */ - break; + if(p->setup_connection) { + result = (*p->setup_connection)(conn); - /* Perform setup complement if some. */ - conn->handler = p; - - if(p->setup_connection) { - result = (*p->setup_connection)(conn); - - if(result != CURLE_OK) - return result; + if(result != CURLE_OK) + return result; - p = conn->handler; /* May have changed. */ - } + p = conn->handler; /* May have changed. */ + } - if(conn->port < 0) - /* we check for -1 here since if proxy was detected already, this - was very likely already set to the proxy port */ - conn->port = p->defport; - conn->remote_port = (unsigned short)p->defport; - conn->protocol |= p->protocol; - return CURLE_OK; - } + if(conn->port < 0) + /* we check for -1 here since if proxy was detected already, this + was very likely already set to the proxy port */ + conn->port = p->defport; + conn->remote_port = (unsigned short)p->defport; + conn->protocol |= p->protocol; - /* The protocol was not found in the table, but we don't have to assign it - to anything since it is already assigned to a dummy-struct in the - create_conn() function when the connectdata struct is allocated. */ - failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME, - conn->protostr); - return CURLE_UNSUPPORTED_PROTOCOL; + return CURLE_OK; } #ifndef CURL_DISABLE_PROXY @@ -3989,7 +4008,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, char endbracket; /* Note that at this point, the IPv6 address cannot contain any scope - suffix as that has already been removed in the ParseURLAndFillConnection() + suffix as that has already been removed in the parseurlandfillconn() function */ if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c", &endbracket)) && @@ -4423,7 +4442,7 @@ static CURLcode create_conn(struct SessionHandle *data, conn->host.name = conn->host.rawalloc; conn->host.name[0] = 0; - result = ParseURLAndFillConnection(data, conn); + result = parseurlandfillconn(data, conn); if(result != CURLE_OK) { return result; } @@ -4449,6 +4468,14 @@ static CURLcode create_conn(struct SessionHandle *data, conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } + /************************************************************* + * Parse a user name and password in the URL and strip it out + * of the host name + *************************************************************/ + result = parse_url_userpass(data, conn, user, passwd); + if(result != CURLE_OK) + return result; + #ifndef CURL_DISABLE_PROXY /************************************************************* * Extract the user and password from the authentication string @@ -4523,20 +4550,12 @@ static CURLcode create_conn(struct SessionHandle *data, * Setup internals depending on protocol. Needs to be done after * we figured out what/if proxy to use. *************************************************************/ - result = setup_connection_internals(data, conn); + result = setup_connection_internals(conn); if(result != CURLE_OK) { Curl_safefree(proxy); return result; } - /************************************************************* - * Parse a user name and password in the URL and strip it out - * of the host name - *************************************************************/ - result = parse_url_userpass(data, conn, user, passwd); - if(result != CURLE_OK) - return result; - /*********************************************************************** * file: is a special case in that it doesn't need a network connection ***********************************************************************/ @@ -4598,12 +4617,6 @@ static CURLcode create_conn(struct SessionHandle *data, if(result != CURLE_OK) return result; - /************************************************************* - * Check the current list of connections to see if we can - * re-use an already existing one or if we have to create a - * new one. - *************************************************************/ - /* Get a cloned copy of the SSL config situation stored in the connection struct. But to get this going nicely, we must first make sure that the strings in the master copy are pointing to the correct @@ -4624,6 +4637,12 @@ static CURLcode create_conn(struct SessionHandle *data, if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) return CURLE_OUT_OF_MEMORY; + /************************************************************* + * Check the current list of connections to see if we can + * re-use an already existing one or if we have to create a + * new one. + *************************************************************/ + /* reuse_fresh is TRUE if we are told to use a new connection by force, but we only acknowledge this option if this is not a re-used connection already (which happens due to follow-location or during a HTTP -- cgit v1.2.1 From 91d05903b498ce807b125a7c6a1ac820d21b0ab8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 17 Dec 2009 15:45:04 +0000 Subject: Remove pointless storing of the protocol as a string within the connectdata struct, and instead use the already stored string in the handler struct. --- lib/url.c | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6e35b666f..b85129a62 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2752,7 +2752,7 @@ ConnectionExists(struct SessionHandle *data, it is a non-SSL protocol tunneled over the same http proxy name and port number */ - if(Curl_raw_equal(needle->protostr, check->protostr) && + if(Curl_raw_equal(needle->handler->scheme, check->handler->scheme) && Curl_raw_equal(needle->host.name, check->host.name) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { @@ -3256,7 +3256,8 @@ static struct connectdata *allocate_conn(void) } static CURLcode findprotocol(struct SessionHandle *data, - struct connectdata *conn) + struct connectdata *conn, + const char *protostr) { const struct Curl_handler * const *pp; const struct Curl_handler *p; @@ -3265,7 +3266,7 @@ static CURLcode findprotocol(struct SessionHandle *data, variables based on the URL. Now that the handler may be changed later when the protocol specific setup function is called. */ for (pp = protocols; (p = *pp) != NULL; pp++) { - if(Curl_raw_equal(p->scheme, conn->protostr)) { + if(Curl_raw_equal(p->scheme, protostr)) { /* Protocol found in table. Check if allowed */ if(!(data->set.allowed_protocols & p->protocol)) /* nope, get out */ @@ -3292,7 +3293,7 @@ static CURLcode findprotocol(struct SessionHandle *data, to anything since it is already assigned to a dummy-struct in the create_conn() function when the connectdata struct is allocated. */ failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME, - conn->protostr); + protostr); return CURLE_UNSUPPORTED_PROTOCOL; } @@ -3307,6 +3308,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, char *tmp; char *path = data->state.path; int rc; + char protobuf[16]; + const char *protop; /************************************************************* * Parse the URL. @@ -3317,8 +3320,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, * url ... ************************************************************/ if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", - conn->protostr, - path)) && Curl_raw_equal(conn->protostr, "file")) { + protobuf, path)) && + Curl_raw_equal(protobuf, "file")) { if(path[0] == '/' && path[1] == '/') { /* Allow omitted hostname (e.g. file:/). This is not strictly * speaking a valid file: URL by RFC 1738, but treating file:/ as @@ -3364,7 +3367,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, } } - strcpy(conn->protostr, "file"); /* store protocol string lowercase */ + protop = "file"; /* protocol string */ } else { /* clear path */ @@ -3372,7 +3375,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, if(2 > sscanf(data->change.url, "%15[^\n:]://%[^\n/]%[^\n]", - conn->protostr, + protobuf, conn->host.name, path)) { /* @@ -3404,19 +3407,21 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, * lib/version.c too! */ if(checkprefix("FTP.", conn->host.name)) - strcpy(conn->protostr, "ftp"); + protop = "ftp"; else if(checkprefix("DICT.", conn->host.name)) - strcpy(conn->protostr, "DICT"); + protop = "DICT"; else if(checkprefix("LDAP.", conn->host.name)) - strcpy(conn->protostr, "LDAP"); + protop = "LDAP"; else if(checkprefix("IMAP.", conn->host.name)) - strcpy(conn->protostr, "IMAP"); + protop = "IMAP"; else { - strcpy(conn->protostr, "http"); + protop = "http"; } conn->protocol |= PROT_MISSING; /* not given in URL */ } + else + protop = protobuf; } /* We search for '?' in the host name (but only on the right side of a @@ -3493,12 +3498,12 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, /* * So if the URL was A://B/C, - * conn->protostr is A + * protop is A * conn->host.name is B * data->state.path is /C */ - return findprotocol(data, conn); + return findprotocol(data, conn, protop); } static void llist_dtor(void *user, void *element) @@ -3685,7 +3690,7 @@ static char *detect_proxy(struct connectdata *conn) if(!check_noproxy(conn->host.name, no_proxy)) { /* It was not listed as without proxy */ - char *protop = conn->protostr; + const char *protop = conn->handler->scheme; char *envp = proxy_env; char *prox; @@ -4036,18 +4041,18 @@ static CURLcode parse_remote_port(struct SessionHandle *data, if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; - bool isftp = (bool)(Curl_raw_equal("ftp", conn->protostr) || - Curl_raw_equal("ftps", conn->protostr)); + /* FTPS connections have the FTP bit set too, so they match as well */ + bool isftp = (bool)conn->protocol & PROT_FTP; /* * This synthesized URL isn't always right--suffixes like ;type=A * are stripped off. It would be better to work directly from the * original URL and simply replace the port part of it. */ - url = aprintf("%s://%s%s%s:%d%s%s", conn->protostr, - conn->bits.ipv6_ip?"[":"", conn->host.name, - conn->bits.ipv6_ip?"]":"", conn->remote_port, - isftp?"/":"", data->state.path); + url = aprintf("%s://%s%s%s:%d%s%s", conn->handler->scheme, + conn->bits.ipv6_ip?"[":"", conn->host.name, + conn->bits.ipv6_ip?"]":"", conn->remote_port, + isftp?"/":"", data->state.path); if(!url) return CURLE_OUT_OF_MEMORY; @@ -4456,7 +4461,7 @@ static CURLcode create_conn(struct SessionHandle *data, part added so that we have a valid URL. */ char *reurl; - reurl = aprintf("%s://%s", conn->protostr, data->change.url); + reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url); if(!reurl) { Curl_safefree(proxy); -- cgit v1.2.1 From 54c60d0067b189a7248f5b6e50f235128c1ba89a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 17 Dec 2009 16:03:39 +0000 Subject: Stop overloading the conn->protocol field with the PROT_MISSING bit. It really didn't belong there and had no real point. --- lib/url.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b85129a62..c16c203ba 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3302,7 +3302,8 @@ static CURLcode findprotocol(struct SessionHandle *data, * Parse URL and fill in the relevant members of the connection struct. */ static CURLcode parseurlandfillconn(struct SessionHandle *data, - struct connectdata *conn) + struct connectdata *conn, + bool *prot_missing) { char *at; char *tmp; @@ -3311,6 +3312,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, char protobuf[16]; const char *protop; + prot_missing = FALSE; + /************************************************************* * Parse the URL. * @@ -3418,7 +3421,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, protop = "http"; } - conn->protocol |= PROT_MISSING; /* not given in URL */ + *prot_missing = TRUE; /* not given in URL */ } else protop = protobuf; @@ -4341,6 +4344,7 @@ static CURLcode create_conn(struct SessionHandle *data, char passwd[MAX_CURL_PASSWORD_LENGTH]; bool reuse; char *proxy = NULL; + bool prot_missing = FALSE; *async = FALSE; @@ -4447,7 +4451,7 @@ static CURLcode create_conn(struct SessionHandle *data, conn->host.name = conn->host.rawalloc; conn->host.name[0] = 0; - result = parseurlandfillconn(data, conn); + result = parseurlandfillconn(data, conn, &prot_missing); if(result != CURLE_OK) { return result; } @@ -4455,7 +4459,7 @@ static CURLcode create_conn(struct SessionHandle *data, /************************************************************* * No protocol part in URL was used, add it! *************************************************************/ - if(conn->protocol&PROT_MISSING) { + if(prot_missing) { /* We're guessing prefixes here and if we're told to use a proxy or if we're gonna follow a Location: later or... then we need the protocol part added so that we have a valid URL. */ @@ -4470,7 +4474,6 @@ static CURLcode create_conn(struct SessionHandle *data, data->change.url = reurl; data->change.url_alloc = TRUE; /* free this later */ - conn->protocol &= ~PROT_MISSING; /* switch that one off again */ } /************************************************************* @@ -4519,7 +4522,7 @@ static CURLcode create_conn(struct SessionHandle *data, } /* proxy must be freed later unless NULL */ if(proxy && *proxy) { - long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); + long bits = conn->protocol & (PROT_HTTPS|PROT_SSL); if((conn->proxytype == CURLPROXY_HTTP) || (conn->proxytype == CURLPROXY_HTTP_1_0)) { -- cgit v1.2.1 From a75d9d91691af5ce54dc3fa8b6b249c71ed9cb35 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 17 Dec 2009 16:07:02 +0000 Subject: uh, assign the bool it points to properly --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c16c203ba..ec2c2bf1b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3312,7 +3312,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, char protobuf[16]; const char *protop; - prot_missing = FALSE; + *prot_missing = FALSE; /************************************************************* * Parse the URL. -- cgit v1.2.1 From 3184a91ec86b2f35f16a8e11e2daa03fac8e91b6 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 30 Dec 2009 17:59:56 +0000 Subject: VMS specific preprocessor symbol checking adjustments --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ec2c2bf1b..05055acba 100644 --- a/lib/url.c +++ b/lib/url.c @@ -65,7 +65,7 @@ #include #endif -#ifdef VMS +#ifdef __VMS #include #include #endif -- cgit v1.2.1 From 3f3f6be825da333055a1113c4998691b086f4601 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 31 Dec 2009 21:52:01 +0000 Subject: turned CURLOPT_MAIL_RCPT into a curl_slist list instead to support multiple receivers, and made the command line tool thus support the option specified many times --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 05055acba..3f2f1cd72 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2314,8 +2314,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_MAIL_RCPT: - result = setstropt(&data->set.str[STRING_MAIL_RCPT], - va_arg(param, char *)); + /* get a list of mail recipients */ + data->set.mail_rcpt = va_arg(param, struct curl_slist *); break; default: -- cgit v1.2.1 From 605bbfc4c0fa838f50bf9d18e69e417168f524c0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 1 Jan 2010 14:44:44 +0000 Subject: - Ingmar Runge enhanced libcurl's FTP engine to support the PRET command. This command is a special "hack" used by the drftpd server, but even though it is a custom extension I've deemed it fine to add to libcurl since this server seems to survive and people keep using it and want libcurl to support it. The new libcurl option is named CURLOPT_FTP_USE_PRET, and it is also usable from the curl tool with --ftp-pret. Using this option on a server that doesn't support this command will make libcurl fail. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f2f1cd72..19283c290 100644 --- a/lib/url.c +++ b/lib/url.c @@ -701,6 +701,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->httpreq = HTTPREQ_GET; /* Default HTTP request */ set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ set->ftp_filemethod = FTPFILE_MULTICWD; set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ @@ -1563,6 +1564,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long)); break; + case CURLOPT_FTP_USE_PRET: + data->set.ftp_use_pret = (bool)(0 != va_arg(param, long)); + break; + case CURLOPT_FTP_SSL_CCC: data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long); break; -- cgit v1.2.1 From a62f32d3c2012a4e2e48dac3d9ec780733c4a844 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 1 Jan 2010 14:52:50 +0000 Subject: update copyright year since we are in 2010 now --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 19283c290..13f80987a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From 9bd03483ce6983852d41f5f69cb74827c9defc26 Mon Sep 17 00:00:00 2001 From: Claes Jakobsson Date: Wed, 6 Jan 2010 16:01:48 +0000 Subject: Julien Chaffraix fixed so that the fragment part in an URL is not sent to the server anymore --- lib/url.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 13f80987a..5c7699d88 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3311,8 +3311,9 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, bool *prot_missing) { char *at; - char *tmp; + char *fragment; char *path = data->state.path; + char *query; int rc; char protobuf[16]; const char *protop; @@ -3438,11 +3439,11 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, */ at = strchr(conn->host.name, '@'); if(at) - tmp = strchr(at+1, '?'); + query = strchr(at+1, '?'); else - tmp = strchr(conn->host.name, '?'); + query = strchr(conn->host.name, '?'); - if(tmp) { + if(query) { /* We must insert a slash before the '?'-letter in the URL. If the URL had a slash after the '?', that is where the path currently begins and the '?string' is still part of the host name. @@ -3451,7 +3452,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, the path. And have it all prefixed with a slash. */ - size_t hostlen = strlen(tmp); + size_t hostlen = strlen(query); size_t pathlen = strlen(path); /* move the existing path plus the zero byte forward, to make room for @@ -3459,11 +3460,11 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, memmove(path+hostlen+1, path, pathlen+1); /* now copy the trailing host part in front of the existing path */ - memcpy(path+1, tmp, hostlen); + memcpy(path+1, query, hostlen); path[0]='/'; /* prepend the missing slash */ - *tmp=0; /* now cut off the hostname at the ? */ + *query=0; /* now cut off the hostname at the ? */ } else if(!path[0]) { /* if there's no path set, use a single slash */ @@ -3500,12 +3501,19 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, } } - if (data->set.scope) + if(data->set.scope) /* Override any scope that was set above. */ conn->scope = data->set.scope; + /* Remove the fragment part of the path. Per RFC 2396, this is always the + last part of the URI. We are looking for the first '#' so that we deal gracefully + with non conformant URI such as http://example.com#foo#bar. */ + fragment = strchr(path, '#'); + if(fragment) + *fragment = 0; + /* - * So if the URL was A://B/C, + * So if the URL was A://B/C#D, * protop is A * conn->host.name is B * data->state.path is /C -- cgit v1.2.1 From bc4582b68a673d3b0f5a2e7d971605de2c8b3730 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 21 Jan 2010 13:58:30 +0000 Subject: Chris Conroy brought support for RTSP transfers, and with it comes 8(!) new libcurl options for controlling what to get and how to receive posssibly interleaved RTP data. Initial commit. --- lib/url.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5c7699d88..d9802dba7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -136,6 +136,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "inet_ntop.h" #include "http_ntlm.h" #include "socks.h" +#include "rtsp.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -226,6 +227,10 @@ static const struct Curl_handler * const protocols[] = { #endif #endif +#ifndef CURL_DISABLE_RTSP + &Curl_handler_rtsp, +#endif + (struct Curl_handler *) NULL }; @@ -699,6 +704,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->maxredirs = -1; /* allow any amount by default */ set->httpreq = HTTPREQ_GET; /* Default HTTP request */ + set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ @@ -2323,6 +2329,114 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.mail_rcpt = va_arg(param, struct curl_slist *); break; + case CURLOPT_RTSP_REQUEST: + { + /* + * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) + * Would this be better if the RTSPREQ_* were just moved into here? + */ + long curl_rtspreq = va_arg(param, long); + long rtspreq = RTSPREQ_NONE; + switch(curl_rtspreq) { + case CURL_RTSPREQ_OPTIONS: + rtspreq = RTSPREQ_OPTIONS; + break; + + case CURL_RTSPREQ_DESCRIBE: + rtspreq = RTSPREQ_DESCRIBE; + break; + + case CURL_RTSPREQ_ANNOUNCE: + rtspreq = RTSPREQ_ANNOUNCE; + break; + + case CURL_RTSPREQ_SETUP: + rtspreq = RTSPREQ_SETUP; + break; + + case CURL_RTSPREQ_PLAY: + rtspreq = RTSPREQ_PLAY; + break; + + case CURL_RTSPREQ_PAUSE: + rtspreq = RTSPREQ_PAUSE; + break; + + case CURL_RTSPREQ_TEARDOWN: + rtspreq = RTSPREQ_TEARDOWN; + break; + + case CURL_RTSPREQ_GET_PARAMETER: + rtspreq = RTSPREQ_GET_PARAMETER; + break; + + case CURL_RTSPREQ_SET_PARAMETER: + rtspreq = RTSPREQ_SET_PARAMETER; + break; + + case CURL_RTSPREQ_RECORD: + rtspreq = RTSPREQ_RECORD; + break; + + case CURL_RTSPREQ_RECEIVE: + rtspreq = RTSPREQ_RECEIVE; + break; + default: + rtspreq = RTSPREQ_NONE; + } + + data->set.rtspreq = rtspreq; + break; + } + + + case CURLOPT_RTSP_SESSION_ID: + /* + * Set the RTSP Session ID manually. Useful if the application is + * resuming a previously established RTSP session + */ + result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID], + va_arg(param, char *)); + break; + + case CURLOPT_RTSP_STREAM_URI: + /* + * Set the Stream URI for the RTSP request. Unless the request is + * for generic server options, the application will need to set this. + */ + result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI], + va_arg(param, char *)); + break; + + case CURLOPT_RTSP_TRANSPORT: + /* + * The content of the Transport: header for the RTSP request + */ + result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT], + va_arg(param, char *)); + break; + + case CURLOPT_RTSP_CLIENT_CSEQ: + /* + * Set the CSEQ number to issue for the next RTSP request. Useful if the + * application is resuming a previously broken connection. The CSEQ + * will increment from this new number henceforth. + */ + data->state.rtsp_next_client_CSeq = va_arg(param, long); + break; + + case CURLOPT_RTSP_SERVER_CSEQ: + /* Same as the above, but for server-initiated requests */ + data->state.rtsp_next_client_CSeq = va_arg(param, long); + break; + + case CURLOPT_RTPDATA: + data->set.rtp_out = va_arg(param, void *); + break; + case CURLOPT_RTPFUNCTION: + /* Set the user defined RTP write function */ + data->set.fwrite_rtp = va_arg(param, curl_write_callback); + break; default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -2360,6 +2474,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->allocptr.rtsp_transport); Curl_safefree(conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ @@ -2500,6 +2615,42 @@ static bool SocketIsDead(curl_socket_t sock) return ret_val; } +#ifndef CURL_DISABLE_RTSP +/* + * The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not + * want to block the application forever while receiving a stream. Therefore, + * we cannot assume that an RTSP socket is dead just because it is readable. + * + * Instead, if it is readable, run Curl_getconnectinfo() to peek at the socket + * and distinguish between closed and data. + */ +static bool RTSPConnIsDead(struct connectdata *check) +{ + int sval; + bool ret_val = TRUE; + + sval = Curl_socket_ready(check->sock[FIRSTSOCKET], CURL_SOCKET_BAD, 0); + if(sval == 0) { + /* timeout */ + ret_val = FALSE; + } + else if (sval & CURL_CSELECT_ERR) { + /* socket is in an error state */ + ret_val = TRUE; + } + else if (sval & CURL_CSELECT_IN) { + /* readable with no error. could be closed or could be alive */ + long connectinfo = 0; + Curl_getconnectinfo(check->data, &connectinfo, &check); + if(connectinfo != -1) { + ret_val = FALSE; + } + } + + return ret_val; +} +#endif /* CURL_DISABLE_RTSP */ + static bool IsPipeliningPossible(const struct SessionHandle *handle) { if(handle->multi && Curl_multi_canPipeline(handle->multi) && @@ -2664,7 +2815,15 @@ ConnectionExists(struct SessionHandle *data, /* The check for a dead socket makes sense only if there are no handles in pipeline and the connection isn't already marked in use */ - bool dead = SocketIsDead(check->sock[FIRSTSOCKET]); + bool dead; +#ifndef CURL_DISABLE_RTSP + if(check->protocol & PROT_RTSP) + /* RTSP is a special case due to RTP interleaving */ + dead = RTSPConnIsDead(check); + else +#endif /*CURL_DISABLE_RTSP*/ + dead = SocketIsDead(check->sock[FIRSTSOCKET]); + if(dead) { check->data = data; infof(data, "Connection #%d seems to be dead!\n", i); -- cgit v1.2.1 From bd7430c1eec70f0a0ffd7296a21396ea45d92359 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 21 Jan 2010 19:27:32 +0000 Subject: fix compiler warning --- lib/url.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d9802dba7..5b3ea65cd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3322,7 +3322,7 @@ static bool tld_check_name(struct SessionHandle *data, /* Convert (and downcase) ACE-name back into locale's character set */ rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); if(rc != IDNA_SUCCESS) - return (FALSE); + return FALSE; rc = tld_check_lz(uc_name, &err_pos, NULL); #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -3340,7 +3340,10 @@ static bool tld_check_name(struct SessionHandle *data, #endif /* CURL_DISABLE_VERBOSE_STRINGS */ if(uc_name) idn_free(uc_name); - return (bool)(rc == TLD_SUCCESS); + if(rc != TLD_SUCCESS) + return FALSE; + + return TRUE; } #endif @@ -4217,7 +4220,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, /* we need to create new URL with the new port number */ char *url; /* FTPS connections have the FTP bit set too, so they match as well */ - bool isftp = (bool)conn->protocol & PROT_FTP; + bool isftp = (bool)(conn->protocol & PROT_FTP); /* * This synthesized URL isn't always right--suffixes like ;type=A -- cgit v1.2.1 From 844c19cc5b5a62e572f4fb9e00c5c6a61c2fb581 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Jan 2010 12:17:03 +0000 Subject: s/RTPFUNCTION/INTERLEAVEFUNCTION/ s/RTPDATA/INTERLEAVEDATA/ --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5b3ea65cd..f3ac14d5c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2430,10 +2430,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->state.rtsp_next_client_CSeq = va_arg(param, long); break; - case CURLOPT_RTPDATA: + case CURLOPT_INTERLEAVEDATA: data->set.rtp_out = va_arg(param, void *); break; - case CURLOPT_RTPFUNCTION: + case CURLOPT_INTERLEAVEFUNCTION: /* Set the user defined RTP write function */ data->set.fwrite_rtp = va_arg(param, curl_write_callback); break; -- cgit v1.2.1 From 143586403055b977bfe17b06042ebc3beb5d4d82 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 22 Jan 2010 20:27:48 +0000 Subject: Definitions of resolver specialty compile-time defines CURLRES_* moved from hostip.h to setup.h in order to allow proper inclusion in any file. This represents no functional change at all in which resolver is used, everything still works as usual, internally and externally there is no difference in behavior. --- lib/url.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f3ac14d5c..927e16887 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5044,8 +5044,7 @@ CURLcode Curl_connect(struct SessionHandle *data, CURLcode Curl_async_resolved(struct connectdata *conn, bool *protocol_done) { -#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ - defined(USE_THREADING_GETADDRINFO) +#ifdef CURLRES_ASYNCH CURLcode code; if(conn->async.dns) { -- cgit v1.2.1 From 33ce0ec1f1951bc1a8f4d475381c1b7c95d4a03a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Jan 2010 23:21:39 +0000 Subject: wrap long lines and do some indent policing --- lib/url.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 927e16887..12e7e3639 100644 --- a/lib/url.c +++ b/lib/url.c @@ -432,7 +432,7 @@ CURLcode Curl_close(struct SessionHandle *data) for (curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, - "MAJOR problem we %p are still in send pipe for %p done %d\n", + "problem we %p are still in send pipe for %p done %d\n", data, connptr, (int)connptr->bits.done); } } @@ -442,7 +442,7 @@ CURLcode Curl_close(struct SessionHandle *data) for (curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, - "MAJOR problem we %p are still in recv pipe for %p done %d\n", + "problem we %p are still in recv pipe for %p done %d\n", data, connptr, (int)connptr->bits.done); } } @@ -452,7 +452,7 @@ CURLcode Curl_close(struct SessionHandle *data) for (curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, - "MAJOR problem we %p are still in done pipe for %p done %d\n", + "problem we %p are still in done pipe for %p done %d\n", data, connptr, (int)connptr->bits.done); } } @@ -462,7 +462,7 @@ CURLcode Curl_close(struct SessionHandle *data) for (curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, - "MAJOR problem we %p are still in pend pipe for %p done %d\n", + "problem we %p are still in pend pipe for %p done %d\n", data, connptr, (int)connptr->bits.done); } } @@ -1160,7 +1160,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, to mark that postfields is used rather than read function or form data. */ - p = malloc((size_t)(data->set.postfieldsize?data->set.postfieldsize:1)); + p = malloc((size_t)(data->set.postfieldsize? + data->set.postfieldsize:1)); if(!p) result = CURLE_OUT_OF_MEMORY; @@ -1411,7 +1412,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authhost.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE); + data->state.authhost.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)? + TRUE:FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -1456,7 +1458,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authproxy.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE); + data->state.authproxy.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)? + TRUE:FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -2874,8 +2877,8 @@ ConnectionExists(struct SessionHandle *data, #endif if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { - /* Don't pick a connection that hasn't connected yet or that is going to - get closed. */ + /* Don't pick a connection that hasn't connected yet or that is going + to get closed. */ infof(data, "Connection #%ld isn't open enough, can't reuse\n", check->connectindex); #ifdef DEBUGBUILD @@ -3653,7 +3656,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, char *endp; unsigned long scope = strtoul (percent + 3, &endp, 10); if (*endp == ']') { - /* The address scope was well formed. Knock it out of the hostname. */ + /* The address scope was well formed. Knock it out of the + hostname. */ memmove(percent, endp, strlen(endp)+1); if (!data->state.this_is_a_follow) /* Don't honour a scope given in a Location: header */ @@ -3668,8 +3672,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, conn->scope = data->set.scope; /* Remove the fragment part of the path. Per RFC 2396, this is always the - last part of the URI. We are looking for the first '#' so that we deal gracefully - with non conformant URI such as http://example.com#foo#bar. */ + last part of the URI. We are looking for the first '#' so that we deal + gracefully with non conformant URI such as http://example.com#foo#bar. */ fragment = strchr(path, '#'); if(fragment) *fragment = 0; @@ -3816,7 +3820,8 @@ static bool check_noproxy(const char* name, const char* no_proxy) if((tok_end - tok_start) <= namelen) { /* Match the last part of the name to the domain we are checking. */ const char *checkn = name + namelen - (tok_end - tok_start); - if(Curl_raw_nequal(no_proxy + tok_start, checkn, tok_end - tok_start)) { + if(Curl_raw_nequal(no_proxy + tok_start, checkn, + tok_end - tok_start)) { if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') { /* We either have an exact match, or the previous character is a . * so it is within the same domain, so no proxy for this host. @@ -4005,7 +4010,8 @@ static CURLcode parse_proxy(struct SessionHandle *data, /* detect and extract RFC2732-style IPv6-addresses */ if(*proxyptr == '[') { char *ptr = ++proxyptr; /* advance beyond the initial bracket */ - while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') || (*ptr == '.'))) + while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') || + (*ptr == '.'))) ptr++; if(*ptr == ']') { /* yeps, it ended nicely with a bracket as well */ -- cgit v1.2.1 From 597ad5a2ce99b8e74c32f7ead13581d2e9b23155 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 23 Jan 2010 13:53:33 +0000 Subject: adjust preprocessor symbol definition check relative to resolver specialty --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 12e7e3639..9f7cd0ac5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2489,11 +2489,12 @@ static void conn_free(struct connectdata *conn) Curl_llist_destroy(conn->done_pipe, NULL); /* possible left-overs from the async name resolvers */ -#if defined(USE_ARES) +#if defined(CURLRES_ASYNCH) Curl_safefree(conn->async.hostname); Curl_safefree(conn->async.os_specific); -#elif defined(CURLRES_THREADED) +#if defined(CURLRES_THREADED) Curl_destroy_thread_data(&conn->async); +#endif #endif Curl_free_ssl_config(&conn->ssl_config); -- cgit v1.2.1 From bbefdf88fdd9c0a2c36966960b360a5a7e9bf764 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 27 Jan 2010 03:43:34 +0000 Subject: fix compiler warning --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9f7cd0ac5..26ad8b78c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2339,7 +2339,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Would this be better if the RTSPREQ_* were just moved into here? */ long curl_rtspreq = va_arg(param, long); - long rtspreq = RTSPREQ_NONE; + Curl_RtspReq rtspreq = RTSPREQ_NONE; switch(curl_rtspreq) { case CURL_RTSPREQ_OPTIONS: rtspreq = RTSPREQ_OPTIONS; @@ -3557,8 +3557,8 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ - if(1 > (rc = sscanf(data->change.url, "%[^\n/]%[^\n]", - conn->host.name, path)) ) { + rc = sscanf(data->change.url, "%[^\n/]%[^\n]", conn->host.name, path); + if(1 > rc) { /* * We couldn't even get this format. * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is -- cgit v1.2.1 From d65cf7889b4ce669876f9e05442fd09f6fe40e37 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 28 Jan 2010 15:34:18 +0000 Subject: fix printf-style format strings --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 26ad8b78c..34626e69a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2830,7 +2830,7 @@ ConnectionExists(struct SessionHandle *data, if(dead) { check->data = data; - infof(data, "Connection #%d seems to be dead!\n", i); + infof(data, "Connection #%ld seems to be dead!\n", i); Curl_disconnect(check); /* disconnect resources */ data->state.connc->connects[i]=NULL; /* nothing here */ @@ -3056,7 +3056,7 @@ ConnectionStore(struct SessionHandle *data, /* there was no room available, kill one */ i = ConnectionKillOne(data); if(-1 != i) - infof(data, "Connection (#%d) was killed to make room (holds %d)\n", + infof(data, "Connection (#%ld) was killed to make room (holds %ld)\n", i, data->state.connc->num); else infof(data, "This connection did not fit in the connection cache\n"); @@ -3137,7 +3137,7 @@ static CURLcode ConnectPlease(struct SessionHandle *data, #ifndef CURL_DISABLE_VERBOSE_STRINGS char *hostname = conn->bits.proxy?conn->proxy.name:conn->host.name; - infof(data, "About to connect() to %s%s port %d (#%d)\n", + infof(data, "About to connect() to %s%s port %ld (#%ld)\n", conn->bits.proxy?"proxy ":"", hostname, conn->port, conn->connectindex); #else @@ -3172,7 +3172,7 @@ static CURLcode ConnectPlease(struct SessionHandle *data, #ifndef CURL_DISABLE_VERBOSE_STRINGS static void verboseconnect(struct connectdata *conn) { - infof(conn->data, "Connected to %s (%s) port %d (#%d)\n", + infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, conn->ip_addr_str, conn->port, conn->connectindex); } -- cgit v1.2.1 From 7aef172a347a0422a0968fde9c487639ff673383 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 4 Feb 2010 19:44:31 +0000 Subject: fix printf-style format strings --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 34626e69a..8340e52c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4234,7 +4234,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, * are stripped off. It would be better to work directly from the * original URL and simply replace the port part of it. */ - url = aprintf("%s://%s%s%s:%d%s%s", conn->handler->scheme, + url = aprintf("%s://%s%s%s:%hu%s%s", conn->handler->scheme, conn->bits.ipv6_ip?"[":"", conn->host.name, conn->bits.ipv6_ip?"]":"", conn->remote_port, isftp?"/":"", data->state.path); -- cgit v1.2.1 From 71593dfe57e2b364fb794b1dc993e029e16d57f7 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Feb 2010 17:30:06 +0000 Subject: OOM handling fix --- lib/url.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8340e52c0..0b1446c17 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4321,13 +4321,19 @@ static CURLcode set_userpass(struct connectdata *conn, !conn->bits.user_passwd) { conn->user = strdup(CURL_DEFAULT_USER); - conn->passwd = strdup(CURL_DEFAULT_PASSWORD); + if(conn->user) + conn->passwd = strdup(CURL_DEFAULT_PASSWORD); + else + conn->passwd = NULL; /* This is the default password, so DON'T set conn->bits.user_passwd */ } else { /* store user + password, zero-length if not set */ conn->user = strdup(user); - conn->passwd = strdup(passwd); + if(conn->user) + conn->passwd = strdup(passwd); + else + conn->passwd = NULL; } if(!conn->user || !conn->passwd) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 4186b5b41f08479b84caeca4c0e0f2dd57ae5c12 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 23 Feb 2010 16:07:54 +0000 Subject: fix compiler warning --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0b1446c17..c67e8a6a7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4227,7 +4227,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, /* we need to create new URL with the new port number */ char *url; /* FTPS connections have the FTP bit set too, so they match as well */ - bool isftp = (bool)(conn->protocol & PROT_FTP); + bool isftp = (bool)(0 != (conn->protocol & PROT_FTP)); /* * This synthesized URL isn't always right--suffixes like ;type=A -- cgit v1.2.1 From 5695c4db861e3c3f200005ae428c89cd3ad6ccdb Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 24 Feb 2010 00:03:06 +0000 Subject: fix compiler warning --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c67e8a6a7..887c06a84 100644 --- a/lib/url.c +++ b/lib/url.c @@ -120,6 +120,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "easyif.h" #include "speedcheck.h" #include "rawstr.h" +#include "warnless.h" /* And now for the protocols */ #include "ftp.h" @@ -4267,7 +4268,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, } *portptr = '\0'; /* cut off the name there */ - conn->remote_port = (unsigned short)port; + conn->remote_port = curlx_ultous(port); } } return CURLE_OK; -- cgit v1.2.1 From f4551a967820ab2be76fd5d600fbce32cd290e62 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 5 Mar 2010 03:15:19 +0000 Subject: Constantine Sapuntzakis detected and fixed a double free in builds done with threaded resolver enabled (Windows default configuration) that would get triggered when a curl handle is closed while doing DNS resolution. --- lib/url.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 887c06a84..fe9c322bf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2490,12 +2490,11 @@ static void conn_free(struct connectdata *conn) Curl_llist_destroy(conn->done_pipe, NULL); /* possible left-overs from the async name resolvers */ -#if defined(CURLRES_ASYNCH) - Curl_safefree(conn->async.hostname); - Curl_safefree(conn->async.os_specific); #if defined(CURLRES_THREADED) Curl_destroy_thread_data(&conn->async); -#endif +#elif defined(CURLRES_ASYNCH) + Curl_safefree(conn->async.hostname); + Curl_safefree(conn->async.os_specific); #endif Curl_free_ssl_config(&conn->ssl_config); -- cgit v1.2.1 From 2309b4e330b96bc2e1f8e36b6184015e59544037 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Mar 2010 11:02:54 +0100 Subject: remove the CVSish $Id$ lines --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fe9c322bf..e32e8da16 100644 --- a/lib/url.c +++ b/lib/url.c @@ -18,7 +18,6 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id$ ***************************************************************************/ /* -- WIN32 approved -- */ -- cgit v1.2.1 From 0eda142e90afc33177d050249fcc4371ba01d039 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sat, 27 Mar 2010 23:00:51 +0100 Subject: allow user+password in the URL for all protocols Ben Greear brought a patch that from now on allows all protocols to specify name and user within the URL, in the same manner HTTP and FTP have been allowed to in the past - although far from all of the libcurl supported protocols actually have that feature in their URL definition spec. --- lib/url.c | 101 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 50 insertions(+), 51 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e32e8da16..357f213c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4113,63 +4113,62 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, * We need somewhere to put the embedded details, so do that first. */ + char *ptr=strchr(conn->host.name, '@'); + char *userpass = conn->host.name; + user[0] =0; /* to make everything well-defined */ passwd[0]=0; - if(conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) { - /* This is a FTP, HTTP, SCP or SFTP 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->host.name, '@'); - char *userpass = conn->host.name; - if(ptr != NULL) { - /* there's a user+password given here, to the left of the @ */ - - conn->host.name = ++ptr; - - /* So the hostname is sane. Only bother interpreting the - * results if we could care. It could still be wasted - * work because it might be overtaken by the programmatically - * set user/passwd, but doing that first adds more cases here :-( - */ + /* We will now try to extract the + * possible user+password pair in a string like: + * ftp://user:password@ftp.my.site:8021/README */ + if(ptr != NULL) { + /* there's a user+password given here, to the left of the @ */ - conn->bits.userpwd_in_url = 1; - if(data->set.use_netrc != CURL_NETRC_REQUIRED) { - /* We could use the one in the URL */ + conn->host.name = ++ptr; - conn->bits.user_passwd = TRUE; /* enable user+password */ + /* So the hostname is sane. Only bother interpreting the + * results if we could care. It could still be wasted + * work because it might be overtaken by the programmatically + * set user/passwd, but doing that first adds more cases here :-( + */ - if(*userpass != ':') { - /* the name is given, get user+password */ - sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:" - "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", - user, passwd); - } - else - /* no name given, get the password only */ - sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); - - if(user[0]) { - char *newname=curl_easy_unescape(data, user, 0, NULL); - if(!newname) - return CURLE_OUT_OF_MEMORY; - if(strlen(newname) < MAX_CURL_USER_LENGTH) - strcpy(user, newname); - - /* if the new name is longer than accepted, then just use - the unconverted name, it'll be wrong but what the heck */ - free(newname); - } - if(passwd[0]) { - /* we have a password found in the URL, decode it! */ - char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); - if(!newpasswd) - return CURLE_OUT_OF_MEMORY; - if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) - strcpy(passwd, newpasswd); - - free(newpasswd); - } + conn->bits.userpwd_in_url = 1; + if(data->set.use_netrc != CURL_NETRC_REQUIRED) { + /* We could use the one in the URL */ + + conn->bits.user_passwd = TRUE; /* enable user+password */ + + if(*userpass != ':') { + /* the name is given, get user+password */ + sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:" + "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", + user, passwd); + } + else + /* no name given, get the password only */ + sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); + + if(user[0]) { + char *newname=curl_easy_unescape(data, user, 0, NULL); + if(!newname) + return CURLE_OUT_OF_MEMORY; + if(strlen(newname) < MAX_CURL_USER_LENGTH) + strcpy(user, newname); + + /* if the new name is longer than accepted, then just use + the unconverted name, it'll be wrong but what the heck */ + free(newname); + } + if(passwd[0]) { + /* we have a password found in the URL, decode it! */ + char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); + if(!newpasswd) + return CURLE_OUT_OF_MEMORY; + if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) + strcpy(passwd, newpasswd); + + free(newpasswd); } } } -- cgit v1.2.1 From 44f1bef6683ddc3fb268b0bca2e5eae314d69d23 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Tue, 6 Apr 2010 22:57:20 -0700 Subject: Remove redundant conditional --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 357f213c0..6dc267204 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4707,7 +4707,7 @@ static CURLcode create_conn(struct SessionHandle *data, proxy = NULL; } /* proxy must be freed later unless NULL */ - if(proxy && *proxy) { + if(proxy) { long bits = conn->protocol & (PROT_HTTPS|PROT_SSL); if((conn->proxytype == CURLPROXY_HTTP) || -- cgit v1.2.1 From c0111460b0689d74731cc56ff019cc869a0d16a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 16 Apr 2010 23:43:04 +0200 Subject: Curl_setup_transfer: no longer returns anything This function could only return CURLE_OK and by changing it to a void instead, we can simplify code all over. --- lib/url.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6dc267204..a84e69d35 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4779,9 +4779,8 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } - result = Curl_setup_transfer(conn, -1, -1, FALSE, - NULL, /* no download */ - -1, NULL); /* no upload */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ + -1, NULL); /* no upload */ } return result; -- cgit v1.2.1 From 38d2afcefb3519f7e6a3b7c3afda4f5bfb67bde9 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 29 Apr 2010 00:49:04 +0200 Subject: telnet: Allow programatic use of telnet. The main change is to allow input from user-specified methods, when they are specified with CURLOPT_READFUNCTION. All calls to fflush(stdout) in telnet.c were removed, which makes using 'curl telnet://foo.com' painful since prompts and other data are not always returned to the user promptly. Use 'curl --no-buffer telnet://foo.com' instead. In general, the user should have their CURLOPT_WRITEFUNCTION do a fflush for interactive use. Also fix assumption that reading from stdin never returns < 0. Old code could crash in that case. Call progress functions in telnet main loop. Signed-off-by: Ben Greear --- lib/url.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a84e69d35..56dd5dc9e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -690,6 +690,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) /* use fread as default function to read input */ set->fread_func = (curl_read_callback)fread; + set->is_fread_set = 0; + set->is_fwrite_set = 0; set->seek_func = ZERO_NULL; set->seek_client = ZERO_NULL; @@ -1825,18 +1827,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set data write callback */ data->set.fwrite_func = va_arg(param, curl_write_callback); - if(!data->set.fwrite_func) + if(!data->set.fwrite_func) { + data->set.is_fwrite_set = 0; /* When set to NULL, reset to our internal default function */ data->set.fwrite_func = (curl_write_callback)fwrite; + } + else + data->set.is_fwrite_set = 0; break; case CURLOPT_READFUNCTION: /* * Read data callback */ data->set.fread_func = va_arg(param, curl_read_callback); - if(!data->set.fread_func) + if(!data->set.fread_func) { + data->set.is_fread_set = 0; /* When set to NULL, reset to our internal default function */ data->set.fread_func = (curl_read_callback)fread; + } + else + data->set.is_fread_set = 1; break; case CURLOPT_SEEKFUNCTION: /* -- cgit v1.2.1 From d64bd82bdcb169d0647a80f00068cedd761f8163 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 7 May 2010 15:05:34 +0200 Subject: sendrecv: split the I/O handling into private handler Howard Chu brought the bulk work of this patch that properly moves out the sending and recving of data to the parts of the code that are properly responsible for the various ways of doing so. Daniel Stenberg assisted with polishing a few bits and fixed some minor flaws in the original patch. Another upside of this patch is that we now abuse CURLcodes less with the "magic" -1 return codes and instead use CURLE_AGAIN more consistently. --- lib/url.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 56dd5dc9e..0f5ac2d14 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4760,6 +4760,9 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } + conn->recv = Curl_recv_plain; + conn->send = Curl_send_plain; + /*********************************************************************** * file: is a special case in that it doesn't need a network connection ***********************************************************************/ -- cgit v1.2.1 From 8914857092f1c7ceb3342b9c4f5e03587e634f5d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 May 2010 23:24:47 +0200 Subject: verboseconnect: so the verbose checking within the function As the function is used more than once and libcurl can be built without it, do the conditional check within the verboseconnect() function itself. --- lib/url.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0f5ac2d14..9c9e09fbc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -154,7 +154,6 @@ static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); #define verboseconnect(x) do { } while (0) #endif - /* * Protocol table. */ @@ -3181,9 +3180,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data, #ifndef CURL_DISABLE_VERBOSE_STRINGS static void verboseconnect(struct connectdata *conn) { - infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", - conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, - conn->ip_addr_str, conn->port, conn->connectindex); + if(conn->data->set.verbose) + infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", + conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, + conn->ip_addr_str, conn->port, conn->connectindex); } #endif @@ -3275,8 +3275,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ - if(data->set.verbose) - verboseconnect(conn); + verboseconnect(conn); } if(!conn->bits.protoconnstart) { @@ -4998,8 +4997,7 @@ static CURLcode setup_conn(struct connectdata *conn, Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */ conn->bits.tcpconnect = TRUE; *protocol_done = TRUE; - if(data->set.verbose) - verboseconnect(conn); + verboseconnect(conn); } /* Stop the loop now */ break; -- cgit v1.2.1 From adaf87530dc561314a2261fa6d26c38ce999876f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 May 2010 23:49:29 +0200 Subject: multi interface: missed storing connection time Dirk Manske reported a regression. When connecting with the multi interface, there were situations where libcurl wouldn't store connect time correctly as it used to (and is documented to) do. Using his fine sample program we could repeat it, and I wrote up test case 573 using that code. The problem does not easily show itself using the local test suite though. The fix, also as suggested by Dirk, is a bit on the ugly side as it adds yet another call to Curl_verboseconnect() and setting the TIMER_CONNECT time. That situation is subject for some closer inspection in the future. --- lib/url.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9c9e09fbc..c41db0a7c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -150,10 +150,6 @@ static long ConnectionKillOne(struct SessionHandle *data); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); -#ifdef CURL_DISABLE_VERBOSE_STRINGS -#define verboseconnect(x) do { } while (0) -#endif - /* * Protocol table. */ @@ -3178,7 +3174,7 @@ static CURLcode ConnectPlease(struct SessionHandle *data, * verboseconnect() displays verbose information after a connect */ #ifndef CURL_DISABLE_VERBOSE_STRINGS -static void verboseconnect(struct connectdata *conn) +void Curl_verboseconnect(struct connectdata *conn) { if(conn->data->set.verbose) infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", @@ -3274,8 +3270,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, if(!conn->bits.tcpconnect) { Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ - - verboseconnect(conn); + Curl_verboseconnect(conn); } if(!conn->bits.protoconnstart) { @@ -4997,7 +4992,7 @@ static CURLcode setup_conn(struct connectdata *conn, Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */ conn->bits.tcpconnect = TRUE; *protocol_done = TRUE; - verboseconnect(conn); + Curl_verboseconnect(conn); } /* Stop the loop now */ break; -- cgit v1.2.1 From bc8fc9803fbd0fa9daf0dba796d42d03faf49120 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 11 May 2010 22:48:38 +0200 Subject: sendrecv: make them two pairs of send/recv to properly deal with FTPS FTP(S) use two connections that can be set to different recv and send functions independently, so by introducing recv+send pairs in the same manner we already have sockets/connections we can work with FTPS fine. This commit fixes the FTPS regression introduced in change d64bd82. --- lib/url.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c41db0a7c..ec7f46a3e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4754,8 +4754,10 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } - conn->recv = Curl_recv_plain; - conn->send = Curl_send_plain; + conn->recv[FIRSTSOCKET] = Curl_recv_plain; + conn->send[FIRSTSOCKET] = Curl_send_plain; + conn->recv[SECONDARYSOCKET] = Curl_recv_plain; + conn->send[SECONDARYSOCKET] = Curl_send_plain; /*********************************************************************** * file: is a special case in that it doesn't need a network connection -- cgit v1.2.1 From 04cb15ae9dc0e863487ee55de2226cf5033311c0 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 12 May 2010 23:07:20 +0200 Subject: RTMP: initial support added, powered by librtmp librtmp is found at http://rtmpdump.mplayerhq.hu/ --- lib/url.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ec7f46a3e..1db65cab7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -137,6 +137,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "http_ntlm.h" #include "socks.h" #include "rtsp.h" +#include "curl_rtmp.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -226,6 +227,15 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_rtsp, #endif +#ifdef USE_LIBRTMP + &Curl_handler_rtmp, + &Curl_handler_rtmpt, + &Curl_handler_rtmpe, + &Curl_handler_rtmpte, + &Curl_handler_rtmps, + &Curl_handler_rtmpts, +#endif + (struct Curl_handler *) NULL }; -- cgit v1.2.1 From 0825cd80a62c21725fb3615f1fdd3aa6cc5f0f34 Mon Sep 17 00:00:00 2001 From: Pavel Raiskup Date: Wed, 12 May 2010 15:33:22 +0200 Subject: FTP: WILDCARDMATCH/CHUNKING/FNMATCH added --- lib/url.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1db65cab7..cc73750e0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -770,6 +770,10 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH); #endif + set->wildcardmatch = 0L; + set->chunk_bgn = ZERO_NULL; + set->chunk_end = ZERO_NULL; + return res; } @@ -838,6 +842,9 @@ CURLcode Curl_open(struct SessionHandle **curl) data->progress.flags |= PGRS_HIDE; data->state.current_speed = -1; /* init to negative == impossible */ + data->wildcard.state = CURLWC_INIT; + data->wildcard.filelist = NULL; + data->set.fnmatch = ZERO_NULL; /* This no longer creates a connection cache here. It is instead made on the first call to curl_easy_perform() or when the handle is added to a multi stack. */ @@ -2455,6 +2462,23 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* Set the user defined RTP write function */ data->set.fwrite_rtp = va_arg(param, curl_write_callback); break; + + case CURLOPT_WILDCARDMATCH: + data->set.wildcardmatch = va_arg(param, long); + break; + case CURLOPT_CHUNK_BGN_FUNCTION: + data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); + break; + case CURLOPT_CHUNK_END_FUNCTION: + data->set.chunk_end = va_arg(param, curl_chunk_end_callback); + break; + case CURLOPT_FNMATCH_FUNCTION: + data->set.fnmatch = va_arg(param, curl_fnmatch_callback); + break; + case CURLOPT_CHUNK_DATA: + data->wildcard.customptr = va_arg(param, void *); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 2ffe834bffa893efcd8942736ab14e311a0087b3 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Sun, 16 May 2010 02:49:08 +0200 Subject: ftp wildcard: a new option CURLOPT_FNMATCH_DATA --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cc73750e0..31976300c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2478,7 +2478,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_CHUNK_DATA: data->wildcard.customptr = va_arg(param, void *); break; - + case CURLOPT_FNMATCH_DATA: + data->set.fnmatch_data = va_arg(param, void *); + break; default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ -- cgit v1.2.1 From 368fd5d27bf89a294d10b63bdacb9ecd7cf8c30d Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 20 May 2010 20:15:51 +0200 Subject: setopt: Fix setting of set.is_fwrite_set Signed-off-by: Ben Greear --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 31976300c..4fe2173dc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1845,7 +1845,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.fwrite_func = (curl_write_callback)fwrite; } else - data->set.is_fwrite_set = 0; + data->set.is_fwrite_set = 1; break; case CURLOPT_READFUNCTION: /* -- cgit v1.2.1 From 2e056353b00d0944bdb2f8e948cc40a4dc0f3dfb Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 25 May 2010 00:44:42 +0200 Subject: LDAP: properly implemented as a curl_handler makes the LDAP code much cleaner, nicer and in general being a better libcurl citizen. If a new enough OpenLDAP version is detect, the new and shiny lib/openldap.c code is then used instead of the old cruft Code by Howard, minor cleanups by Daniel. --- lib/url.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4fe2173dc..c59535a9c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -181,13 +181,12 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_dict, #endif -#ifndef CURL_DISABLE_LDAP +#if !defined(CURL_DISABLE_LDAP) || defined(USE_OPENLDAP) &Curl_handler_ldap, -#endif - -#if !defined(CURL_DISABLE_LDAP) && defined(HAVE_LDAP_SSL) +#if defined(HAVE_LDAP_SSL) || defined(USE_OPENLDAP) &Curl_handler_ldaps, #endif +#endif #ifndef CURL_DISABLE_FILE &Curl_handler_file, -- cgit v1.2.1 From dd8568739c2b67ad069d59a8afcce9e6d3305d5f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 26 May 2010 11:12:26 +0200 Subject: url.c: avoid implied cast to bool --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c59535a9c..8f95c8a66 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2463,7 +2463,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_WILDCARDMATCH: - data->set.wildcardmatch = va_arg(param, long); + data->set.wildcardmatch = !! va_arg(param, long); break; case CURLOPT_CHUNK_BGN_FUNCTION: data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); -- cgit v1.2.1 From b1c1b9bb76e01900de6ffd7e173eec3d2c65a310 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 28 May 2010 12:23:28 +0200 Subject: LDAPS: list availability depending on SSL's presence --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8f95c8a66..4d1632b66 100644 --- a/lib/url.c +++ b/lib/url.c @@ -183,7 +183,7 @@ static const struct Curl_handler * const protocols[] = { #if !defined(CURL_DISABLE_LDAP) || defined(USE_OPENLDAP) &Curl_handler_ldap, -#if defined(HAVE_LDAP_SSL) || defined(USE_OPENLDAP) +#if defined(HAVE_LDAP_SSL) || (defined(USE_OPENLDAP) && defined(USE_SSL)) &Curl_handler_ldaps, #endif #endif -- cgit v1.2.1 From b4fa27ae4b5e01f2b7494edb0ba37efb349cf6ae Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 31 May 2010 17:11:51 +0200 Subject: fix compiler warning: enumerated type mixed with another type --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4d1632b66..3b15f3c3b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -769,7 +769,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH); #endif - set->wildcardmatch = 0L; + set->wildcardmatch = FALSE; set->chunk_bgn = ZERO_NULL; set->chunk_end = ZERO_NULL; -- cgit v1.2.1 From 0546d448ced64975a6b71ef4ee23650f5fc1e362 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 31 May 2010 17:22:43 +0200 Subject: fix compiler warning: enumerated type mixed with another type --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3b15f3c3b..6c48dcb2e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4172,7 +4172,7 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, * set user/passwd, but doing that first adds more cases here :-( */ - conn->bits.userpwd_in_url = 1; + conn->bits.userpwd_in_url = TRUE; if(data->set.use_netrc != CURL_NETRC_REQUIRED) { /* We could use the one in the URL */ -- cgit v1.2.1 From b38189c7b41cc2a327ab690a523441bcb3e6f9fe Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 1 Jun 2010 12:25:14 +0200 Subject: fix compiler warning: enumerated type mixed with another type --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6c48dcb2e..3f55f7bda 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2463,7 +2463,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_WILDCARDMATCH: - data->set.wildcardmatch = !! va_arg(param, long); + data->set.wildcardmatch = (bool)(0 != va_arg(param, long)); break; case CURLOPT_CHUNK_BGN_FUNCTION: data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); -- cgit v1.2.1 From 89da5324457070cb4a7391c48c6c4f84ed7fe964 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 1 Jun 2010 17:25:03 +0200 Subject: fix ldap related compilation issues --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f55f7bda..6ec844a65 100644 --- a/lib/url.c +++ b/lib/url.c @@ -181,9 +181,10 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_dict, #endif -#if !defined(CURL_DISABLE_LDAP) || defined(USE_OPENLDAP) +#ifndef CURL_DISABLE_LDAP &Curl_handler_ldap, -#if defined(HAVE_LDAP_SSL) || (defined(USE_OPENLDAP) && defined(USE_SSL)) +#if (defined(USE_OPENLDAP) && defined(USE_SSL)) || \ + (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)) &Curl_handler_ldaps, #endif #endif -- cgit v1.2.1 From 8098d9417c649272b9d6d2ad76abbde7dfbfcad1 Mon Sep 17 00:00:00 2001 From: Frank Meier Date: Sat, 5 Jun 2010 00:29:09 +0200 Subject: getinfo: added *_PRIMARY_PORT, *_LOCAL_IP and *_LOCAL_PORT --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6ec844a65..8a59be2d4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5031,6 +5031,7 @@ static CURLcode setup_conn(struct connectdata *conn, conn->bits.tcpconnect = TRUE; *protocol_done = TRUE; Curl_verboseconnect(conn); + Curl_updateconninfo(conn->sock[FIRSTSOCKET], &data->info); } /* Stop the loop now */ break; -- cgit v1.2.1 From f737e94164fd33cbb03a559ff51d4b4db59902ea Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 7 Jun 2010 16:53:31 +0200 Subject: Curl_updateconninfo() error handling fix --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8a59be2d4..897ff2c12 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5031,7 +5031,7 @@ static CURLcode setup_conn(struct connectdata *conn, conn->bits.tcpconnect = TRUE; *protocol_done = TRUE; Curl_verboseconnect(conn); - Curl_updateconninfo(conn->sock[FIRSTSOCKET], &data->info); + Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]); } /* Stop the loop now */ break; -- cgit v1.2.1 From 181b08babb0fd74fca60bac1265be631cfb35d50 Mon Sep 17 00:00:00 2001 From: Jan Van Boghout Date: Sun, 18 Jul 2010 20:23:08 +0200 Subject: CUSTOMREQUEST: shouldn't be disabled when HTTP is disabled ... since FTP is using it as well, and potentially other protocols! Also, an #endif CURL_DISABLE_HTTP was incorrectly marked, as it seems to end the proxy block instead. --- lib/url.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 897ff2c12..4ed330e96 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1404,19 +1404,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.httpversion = va_arg(param, long); break; - case CURLOPT_CUSTOMREQUEST: - /* - * Set a custom string to use as request - */ - result = setstropt(&data->set.str[STRING_CUSTOMREQUEST], - va_arg(param, char *)); - - /* we don't set - data->set.httpreq = HTTPREQ_CUSTOM; - here, we continue as if we were using the already set type - and this just changes the actual request keyword */ - break; - case CURLOPT_HTTPAUTH: /* * Set HTTP Authentication type BITMASK. @@ -1448,6 +1435,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } break; +#endif /* CURL_DISABLE_HTTP */ + + case CURLOPT_CUSTOMREQUEST: + /* + * Set a custom string to use as request + */ + result = setstropt(&data->set.str[STRING_CUSTOMREQUEST], + va_arg(param, char *)); + + /* we don't set + data->set.httpreq = HTTPREQ_CUSTOM; + here, we continue as if we were using the already set type + and this just changes the actual request keyword */ + break; + #ifndef CURL_DISABLE_PROXY case CURLOPT_HTTPPROXYTUNNEL: /* @@ -1492,7 +1494,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.proxyauth = auth; } break; -#endif /* CURL_DISABLE_HTTP */ case CURLOPT_PROXY: /* @@ -1532,7 +1533,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; } break; -#endif +#endif /* CURL_DISABLE_PROXY */ #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) case CURLOPT_SOCKS5_GSSAPI_SERVICE: -- cgit v1.2.1 From a1a5ba3d0adad64c4c028d5d3f2903abd0efb510 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Aug 2010 23:17:30 +0200 Subject: Curl_connected_proxy: skip the bits.tcpconnect check Simply because the TCP might be connected already we cannot skip the proxy connect procedure. We need to be careful to not overload more meaning to the bits.tcpconnect field like this. With this fix, SOCKS proxies work again when the multi interface is used. I believe this regression was added with commit 4b351d018e, released as 7.20.1. Left todo: add a test case that verifies this functionality that prevents us from breaking it again in the future! Reported by: Robin Cornelius Bug: http://curl.haxx.se/bug/view.cgi?id=3033966 --- lib/url.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4ed330e96..228e35386 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3127,7 +3127,7 @@ ConnectionStore(struct SessionHandle *data, /* after a TCP connection to the proxy has been verified, this function does the next magic step. - Note: this function (and its sub-functions) calls failf() + Note: this function's sub-functions call failf() */ CURLcode Curl_connected_proxy(struct connectdata *conn) @@ -3135,12 +3135,6 @@ CURLcode Curl_connected_proxy(struct connectdata *conn) CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; - if(conn->bits.tcpconnect) - /* allow this to get called again from the multi interface when TCP is - found connected in the state machine, even though it has already been - called if the connection happened "instantly" */ - return CURLE_OK; - switch(data->set.proxytype) { #ifndef CURL_DISABLE_PROXY case CURLPROXY_SOCKS5: -- cgit v1.2.1 From dc2157a0878f3a140fac07b97687b3c3da42616b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Aug 2010 00:56:45 +0200 Subject: parse_remote_port: fix ;type= URL suffix over HTTP proxy Test 563 is enabled now and verifies that the combo FTP type=A URL, CURLOPT_PORT set and proxy work fine. As a bonus I managed to remove the somewhat odd FTP check in parse_remote_port() and instead converted it to a better and more generic 'slash_removed' struct field. Checking the ->protocol field isn't right since when an FTP:// URL is sent over a HTTP proxy, the protocol is HTTP but the URL was handled by the FTP code and thus slash_removed is set TRUE for this case. --- lib/url.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 228e35386..fd6443a59 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4259,18 +4259,23 @@ static CURLcode parse_remote_port(struct SessionHandle *data, if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; - /* FTPS connections have the FTP bit set too, so they match as well */ - bool isftp = (bool)(0 != (conn->protocol & PROT_FTP)); + char type[12]=""; + + if(conn->bits.type_set) + snprintf(type, sizeof(type), ";type=%c", + data->set.prefer_ascii?'A': + (data->set.ftp_list_only?'D':'I')); /* - * This synthesized URL isn't always right--suffixes like ;type=A - * are stripped off. It would be better to work directly from the - * original URL and simply replace the port part of it. + * This synthesized URL isn't always right--suffixes like ;type=A are + * stripped off. It would be better to work directly from the original + * URL and simply replace the port part of it. */ - url = aprintf("%s://%s%s%s:%hu%s%s", conn->handler->scheme, + url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->handler->scheme, conn->bits.ipv6_ip?"[":"", conn->host.name, conn->bits.ipv6_ip?"]":"", conn->remote_port, - isftp?"/":"", data->state.path); + data->state.slash_removed?"/":"", data->state.path, + type); if(!url) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 232ad6549a684505efcbb6ed9d7a78943cc5f817 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 10 Aug 2010 11:02:07 +0200 Subject: multi: support timeouts Curl_expire() is now expanded to hold a list of timeouts for each easy handle. Only the closest in time will be the one used as the primary timeout for the handle and will be used for the splay tree (which sorts and lists all handles within the multi handle). When the main timeout has triggered/expired, the next timeout in time that is kept in the list will be moved to the main timeout position and used as the key to splay with. This way, all timeouts that are set with Curl_expire() internally will end up as a proper timeout. Previously any Curl_expire() that set a _later_ timeout than what was already set was just silently ignored and thus missed. Setting Curl_expire() with timeout 0 (zero) will cancel all previously added timeouts. Corrects known bug #62. --- lib/url.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fd6443a59..ac621f220 100644 --- a/lib/url.c +++ b/lib/url.c @@ -479,7 +479,15 @@ CURLcode Curl_close(struct SessionHandle *data) if(m) /* This handle is still part of a multi handle, take care of this first and detach this handle from there. */ - Curl_multi_rmeasy(data->multi, data); + curl_multi_remove_handle(data->multi, data); + + /* Destroy the timeout list that is held in the easy handle. It is + /normally/ done by curl_multi_remove_handle() but this is "just in + case" */ + if(data->state.timeoutlist) { + Curl_llist_destroy(data->state.timeoutlist, NULL); + data->state.timeoutlist = NULL; + } data->magic = 0; /* force a clear AFTER the possibly enforced removal from the multi handle, since that function uses the magic -- cgit v1.2.1 From 6b6a3bcb61f2d8f4e80a1e2a5bc62e78904256ed Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 25 Aug 2010 13:42:14 +0200 Subject: http: handle trailer headers in all chunked responses HTTP allows that a server sends trailing headers after all the chunks have been sent WITHOUT signalling their presence in the first response headers. The "Trailer:" header is only a SHOULD there and as we need to handle the situation even without that header I made libcurl ignore Trailer: completely. Test case 1116 was added to verify this and to make sure we handle more than one trailer header properly. Reported by: Patrick McManus Bug: http://curl.haxx.se/bug/view.cgi?id=3052450 --- lib/url.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ac621f220..3ae797532 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5300,10 +5300,8 @@ static CURLcode do_init(struct connectdata *conn) static void do_complete(struct connectdata *conn) { conn->data->req.chunk=FALSE; - conn->data->req.trailerhdrpresent=FALSE; - conn->data->req.maxfd = (conn->sockfd>conn->writesockfd? - conn->sockfd:conn->writesockfd)+1; + conn->sockfd:conn->writesockfd)+1; } CURLcode Curl_do(struct connectdata **connp, bool *done) -- cgit v1.2.1 From 201637d4682973bcc4a1fd0f4e8d4159300bd0b8 Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Thu, 12 Aug 2010 07:55:48 -0700 Subject: Gopher protocol support (initial release) --- lib/url.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3ae797532..6b312eb11 100644 --- a/lib/url.c +++ b/lib/url.c @@ -138,6 +138,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "socks.h" #include "rtsp.h" #include "curl_rtmp.h" +#include "gopher.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -227,6 +228,10 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_rtsp, #endif +#ifndef CURL_DISABLE_GOPHER + &Curl_handler_gopher, +#endif + #ifdef USE_LIBRTMP &Curl_handler_rtmp, &Curl_handler_rtmpt, @@ -3482,8 +3487,11 @@ static CURLcode findprotocol(struct SessionHandle *data, if(Curl_raw_equal(p->scheme, protostr)) { /* Protocol found in table. Check if allowed */ if(!(data->set.allowed_protocols & p->protocol)) +{ /* nope, get out */ + fprintf(stderr, "well, shit\n"); break; +} /* it is allowed for "normal" request, now do an extra check if this is the result of a redirect */ -- cgit v1.2.1 From 65629f2915d1b23193fbe4fb3697702ce2fc7e87 Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Thu, 12 Aug 2010 09:25:43 -0700 Subject: Remove url.c test --- lib/url.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6b312eb11..99f1e7d12 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3487,11 +3487,8 @@ static CURLcode findprotocol(struct SessionHandle *data, if(Curl_raw_equal(p->scheme, protostr)) { /* Protocol found in table. Check if allowed */ if(!(data->set.allowed_protocols & p->protocol)) -{ /* nope, get out */ - fprintf(stderr, "well, shit\n"); break; -} /* it is allowed for "normal" request, now do an extra check if this is the result of a redirect */ -- cgit v1.2.1 From ce00c2ef5d5b25b045ed630c72628e8a05f51943 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 1 Sep 2010 16:04:39 +0200 Subject: resolve_server: simplify code Make use of the helper function Curl_timeleft() instead of duplicating code. --- lib/url.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 99f1e7d12..8abf6e9bc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4400,30 +4400,7 @@ static CURLcode resolve_server(struct SessionHandle *data, bool *async) { CURLcode result=CURLE_OK; - long shortest = 0; /* default to no timeout */ - - /************************************************************* - * Set timeout if that is being used - *************************************************************/ - if(data->set.timeout || data->set.connecttimeout) { - - /* We set the timeout on the name resolving phase first, separately from - * the download/upload part to allow a maximum time on everything. This is - * a signal-based timeout, why it won't work and shouldn't be used in - * multi-threaded environments. */ - - shortest = data->set.timeout; /* default to this timeout value */ - if(shortest && data->set.connecttimeout && - (data->set.connecttimeout < shortest)) - /* if both are set, pick the shortest */ - shortest = data->set.connecttimeout; - else if(!shortest) - /* if timeout is not set, use the connect timeout */ - shortest = data->set.connecttimeout; - /* We can expect the conn->created time to be "now", as that was just - recently set in the beginning of this function and nothing slow - has been done since then until now. */ - } + long timeout_ms = Curl_timeleft(conn, NULL, TRUE); /************************************************************* * Resolve the name of the server or proxy @@ -4450,7 +4427,7 @@ static CURLcode resolve_server(struct SessionHandle *data, /* Resolve target host right on */ rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port, - &hostaddr, shortest); + &hostaddr, timeout_ms); if(rc == CURLRESOLV_PENDING) *async = TRUE; @@ -4471,7 +4448,7 @@ static CURLcode resolve_server(struct SessionHandle *data, /* resolve proxy */ rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port, - &hostaddr, shortest); + &hostaddr, timeout_ms); if(rc == CURLRESOLV_PENDING) *async = TRUE; -- cgit v1.2.1 From c6fa1952a14ba2fa14f4a3483f1f573560ef3133 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Sep 2010 00:02:54 +0200 Subject: portabilty: use proper variable type to hold sockets Curl_getconnectinfo() is changed to return a proper curl_socket_t for the last socket so that it'll work more portably (and cause less compiler warnings). --- lib/url.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8abf6e9bc..133418681 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2698,11 +2698,10 @@ static bool RTSPConnIsDead(struct connectdata *check) } else if (sval & CURL_CSELECT_IN) { /* readable with no error. could be closed or could be alive */ - long connectinfo = 0; - Curl_getconnectinfo(check->data, &connectinfo, &check); - if(connectinfo != -1) { + curl_socket_t connectinfo = + Curl_getconnectinfo(check->data, &check); + if(connectinfo != CURL_SOCKET_BAD) ret_val = FALSE; - } } return ret_val; -- cgit v1.2.1 From 8665d4e593c853dbcc83a0c6ba92b77d9e5bcd7e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 21 Sep 2010 19:51:30 +0200 Subject: parse_remote_port: ignore colons without port number Obviously, browsers ignore a colon without a following port number. Both Firefox and Chrome just removes the colon for such URLs. This change does not remove the colon for URLs sent over a HTTP proxy, so we should consider doing that change as well. Reported by: github user 'kreshano' --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 133418681..7fe713d3e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4319,6 +4319,11 @@ static CURLcode parse_remote_port(struct SessionHandle *data, *portptr = '\0'; /* cut off the name there */ conn->remote_port = curlx_ultous(port); } + else if(!port) + /* Browser behavior adaptation. If there's a colon with no digits after, + just cut off the name there which makes us ignore the colon and just + use the default port. Firefox and Chrome both do that. */ + *portptr = '\0'; } return CURLE_OK; } -- cgit v1.2.1 From ed4eecc05e0cce36d8ce4ac9466376ca5fcfcba2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 28 Sep 2010 23:17:34 +0200 Subject: multi: don't expire timeouts at disonnect or done The functions Curl_disconnect() and Curl_done() are both used within the scope of a single request so they cannot be allowed to use Curl_expire(... 0) to kill all timeouts as there are some timeouts that are set before a request that are supposed to remain until the request is done. The timeouts are now instead cleared at curl_easy_cleanup() and when the multi state machine changes a handle to the complete state. --- lib/url.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7fe713d3e..1b65a923f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -481,6 +481,8 @@ CURLcode Curl_close(struct SessionHandle *data) } #endif + Curl_expire(data, 0); /* shut off timers */ + if(m) /* This handle is still part of a multi handle, take care of this first and detach this handle from there. */ @@ -2579,7 +2581,6 @@ CURLcode Curl_disconnect(struct connectdata *conn) NULL, Curl_scan_cache_used); #endif - Curl_expire(data, 0); /* shut off timers */ Curl_hostcache_prune(data); /* kill old DNS cache entries */ { @@ -5131,8 +5132,6 @@ CURLcode Curl_done(struct connectdata **connp, conn = *connp; data = conn->data; - Curl_expire(data, 0); /* stop timer */ - if(conn->bits.done) /* Stop if Curl_done() has already been called */ return CURLE_OK; -- cgit v1.2.1 From b0ccd24a729294da5f5b58ad595593068415d6df Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Oct 2010 22:33:20 +0200 Subject: Curl_setopt: disallow CURLOPT_USE_SSL without SSL support In order to avoid for example the pingpong protocols to issue STARTTLS (or equivalent) even though there's no SSL support built-in. Reported by: Sune Ahlgren Bug: http://curl.haxx.se/mail/archive-2010-10/0045.html --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1b65a923f..b0a348b88 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2166,13 +2166,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.max_filesize = va_arg(param, long); break; +#ifdef USE_SSL case CURLOPT_USE_SSL: /* * Make transfers attempt to use SSL/TLS. */ data->set.ftp_ssl = (curl_usessl)va_arg(param, long); break; - +#endif case CURLOPT_FTPSSLAUTH: /* * Set a specific auth for FTP-SSL transfers. -- cgit v1.2.1 From 98d9dc78407eff15ebf566fe08df2e1b4fd18baf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 19 Oct 2010 20:20:06 +0200 Subject: URL-parsing: consider ? a divider The URL parser got a little stricter as it now considers a ? to be a host name divider so that the slightly sloppier URLs work too. The problem that made me do this change was the reported problem with an URL like: www.example.com?email=name@example.com This form of URL is not really a legal URL (due to the missing slash after the host name) but is widely accepted by all major browsers and libcurl also already accepted it, it was just the '@' letter that triggered the problem now. The side-effect of this change is that now libcurl no longer accepts the ? letter as part of user-name or password when given in the URL, which it used to accept (and is tested in test 191). That letter is however mentioned in RFC3986 to be required to be percent encoded since it is used as a divider. Bug: http://curl.haxx.se/bug/view.cgi?id=3090268 --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b0a348b88..b715e998f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3597,7 +3597,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, path[0]=0; if(2 > sscanf(data->change.url, - "%15[^\n:]://%[^\n/]%[^\n]", + "%15[^\n:]://%[^\n/?]%[^\n]", protobuf, conn->host.name, path)) { @@ -3605,7 +3605,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ - rc = sscanf(data->change.url, "%[^\n/]%[^\n]", conn->host.name, path); + rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path); if(1 > rc) { /* * We couldn't even get this format. -- cgit v1.2.1 From afecd1aa13b4f40c54d195514af113715b0e0f9f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 4 Nov 2010 14:58:15 +0100 Subject: host: get the custom Host: name more genericly When given a custom host name in a Host: header, we can use it for several different purposes other than just cookies, so we rename it and use it for SSL SNI etc. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b715e998f..ef02b4f31 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2534,7 +2534,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.rangeline); Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); - Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->allocptr.customhost); Curl_safefree(conn->allocptr.rtsp_transport); Curl_safefree(conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ -- cgit v1.2.1 From 87374a47c9d22521c8d31f1c4952db5fdb479903 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Nov 2010 10:24:22 +0100 Subject: Revert: use Host: name for SNI and cert name checks This reverts commit b0fd03f5b8d4520dd232a9d13567d16bd0ad8951, 4b2fbe1e97891f, afecd1aa13b4f, 68cde058f66b3 --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ef02b4f31..b715e998f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2534,7 +2534,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.rangeline); Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); - Curl_safefree(conn->allocptr.customhost); + Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->allocptr.rtsp_transport); Curl_safefree(conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ -- cgit v1.2.1 From 1b24b89cca3c06e36b69969af8edeeaca659515b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Nov 2010 22:31:40 +0100 Subject: CURLOPT_RESOLVE: added CURLOPT_RESOLVE is a new option that sends along a curl_slist with name:port:address sets that will populate the DNS cache with entries so that request can be "fooled" to use another host than what otherwise would've been used. Previously we've encouraged the use of Host: for that when dealing with HTTP, but this new feature has the added bonus that it allows the name from the URL to be used for TLS SNI and server certificate name checks as well. This is a first change. Surely more will follow to make it decent. --- lib/url.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b715e998f..4a45256d4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1750,6 +1750,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.quote = va_arg(param, struct curl_slist *); break; + case CURLOPT_RESOLVE: + /* + * List of NAME:[address] names to populate the DNS cache with + * Prefix the NAME with dash (-) to _remove_ the name from the cache. + * + * Names added with this API will remain in the cache until explicitly + * removed or the handle is cleaned up. + * + * This API can remove any name from the DNS cache, but only entries + * that aren't actually in use right now will be pruned immediately. + */ + data->set.resolve = va_arg(param, struct curl_slist *); + data->change.resolve = data->set.resolve; + break; case CURLOPT_PROGRESSFUNCTION: /* * Progress callback function -- cgit v1.2.1 From a1f32ffee540bcef046dc499938585c5da9d0aa8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 11 Nov 2010 14:51:39 +0100 Subject: ip_version: moved to connection struct The IP version choice was previously only in the UserDefined struct within the SessionHandle, but since we sometimes alter that option during a request we need to have it on a per-connection basis. I also moved more "init conn" code into the allocate_conn() function which is designed for that purpose more or less. --- lib/url.c | 137 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 72 insertions(+), 65 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4a45256d4..fb5122d65 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2196,7 +2196,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_IPRESOLVE: - data->set.ip_version = va_arg(param, long); + data->set.ipver = va_arg(param, long); break; case CURLOPT_MAXFILESIZE_LARGE: @@ -3455,14 +3455,19 @@ static void fix_hostname(struct SessionHandle *data, #endif } +static void llist_dtor(void *user, void *element) +{ + (void)user; + (void)element; + /* Do nothing */ +} + /* * Allocate and initialize a new connectdata object. */ -static struct connectdata *allocate_conn(void) +static struct connectdata *allocate_conn(struct SessionHandle *data) { - struct connectdata *conn; - - conn = calloc(1, sizeof(struct connectdata)); + struct connectdata *conn = calloc(1, sizeof(struct connectdata)); if(!conn) return NULL; @@ -3485,7 +3490,66 @@ static struct connectdata *allocate_conn(void) /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); + conn->data = data; /* Setup the association between this connection + and the SessionHandle */ + + conn->proxytype = data->set.proxytype; /* type */ + +#ifdef CURL_DISABLE_PROXY + + conn->bits.proxy = FALSE; + conn->bits.httpproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; + +#else /* CURL_DISABLE_PROXY */ + + conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && + *data->set.str[STRING_PROXY]); + conn->bits.httpproxy = (bool)(conn->bits.proxy && + (conn->proxytype == CURLPROXY_HTTP || + conn->proxytype == CURLPROXY_HTTP_1_0)); + conn->bits.proxy_user_passwd = + (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; + +#endif /* CURL_DISABLE_PROXY */ + + conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); + conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; + conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + + conn->verifypeer = data->set.ssl.verifypeer; + conn->verifyhost = data->set.ssl.verifyhost; + + conn->ip_version = data->set.ipver; + + if(data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ + conn->master_buffer = calloc(BUFSIZE, sizeof (char)); + if(!conn->master_buffer) + goto error; + } + + /* Initialize the pipeline lists */ + conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->done_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe || + !conn->done_pipe) + goto error; + return conn; + error: + Curl_llist_destroy(conn->send_pipe, NULL); + Curl_llist_destroy(conn->recv_pipe, NULL); + Curl_llist_destroy(conn->pend_pipe, NULL); + Curl_llist_destroy(conn->done_pipe, NULL); + Curl_safefree(conn->master_buffer); + Curl_safefree(conn); + return NULL; } static CURLcode findprotocol(struct SessionHandle *data, @@ -3751,13 +3815,6 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, return findprotocol(data, conn, protop); } -static void llist_dtor(void *user, void *element) -{ - (void)user; - (void)element; - /* Do nothing */ -} - /* * If we're doing a resumed transfer, we need to setup our stuff * properly. @@ -4595,66 +4652,16 @@ static CURLcode create_conn(struct SessionHandle *data, parts for checking against the already present connections. In order to not have to modify everything at once, we allocate a temporary connection data struct and fill in for comparison purposes. */ + conn = allocate_conn(data); - conn = allocate_conn(); + if(!conn) + return CURLE_OUT_OF_MEMORY; /* We must set the return variable as soon as possible, so that our parent can cleanup any possible allocs we may have done before any failure */ *in_connect = conn; - if(!conn) - return CURLE_OUT_OF_MEMORY; - - conn->data = data; /* Setup the association between this connection - and the SessionHandle */ - - conn->proxytype = data->set.proxytype; /* type */ - -#ifdef CURL_DISABLE_PROXY - - conn->bits.proxy = FALSE; - conn->bits.httpproxy = FALSE; - conn->bits.proxy_user_passwd = FALSE; - conn->bits.tunnel_proxy = FALSE; - -#else /* CURL_DISABLE_PROXY */ - - conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && - *data->set.str[STRING_PROXY]); - conn->bits.httpproxy = (bool)(conn->bits.proxy && - (conn->proxytype == CURLPROXY_HTTP || - conn->proxytype == CURLPROXY_HTTP_1_0)); - conn->bits.proxy_user_passwd = - (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; - -#endif /* CURL_DISABLE_PROXY */ - - conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); - conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; - conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; - - conn->verifypeer = data->set.ssl.verifypeer; - conn->verifyhost = data->set.ssl.verifyhost; - - if(data->multi && Curl_multi_canPipeline(data->multi) && - !conn->master_buffer) { - /* Allocate master_buffer to be used for pipelining */ - conn->master_buffer = calloc(BUFSIZE, sizeof (char)); - if(!conn->master_buffer) - return CURLE_OUT_OF_MEMORY; - } - - /* Initialize the pipeline lists */ - conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->done_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe || - !conn->done_pipe) - return CURLE_OUT_OF_MEMORY; - /* This initing continues below, see the comment "Continue connectdata * initialization here" */ -- cgit v1.2.1 From 8d59d69449c2a86c478699a50d920541aa106201 Mon Sep 17 00:00:00 2001 From: Julien Chaffraix Date: Sat, 13 Nov 2010 12:01:33 -0800 Subject: security: tighten enum protection_level usage. While changing Curl_sec_read_msg to accept an enum protection_level instead of an int, I went ahead and fixed the usage of the associated fields. Some code was assuming that prot_clear == 0. Fixed those to use the proper value. Added assertions prior to any code that would set the protection level. --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fb5122d65..3f9bfa877 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3541,6 +3541,10 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) !conn->done_pipe) goto error; +#if defined(HAVE_KRB4) || defined(HAVE_GSSAPI) + conn->data_prot = prot_clear; +#endif + return conn; error: Curl_llist_destroy(conn->send_pipe, NULL); -- cgit v1.2.1 From add5766dd4d8a15f3f96254fc65e9ab5c9ff3d48 Mon Sep 17 00:00:00 2001 From: Julien Chaffraix Date: Sat, 13 Nov 2010 14:42:34 -0800 Subject: urldata: Capitalize enum protect_level values. This makes it easier to spot the enum values from the variables. Removed some unneeded DEBUGASSERT added in the previous commit. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3f9bfa877..e915c7947 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3542,7 +3542,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) goto error; #if defined(HAVE_KRB4) || defined(HAVE_GSSAPI) - conn->data_prot = prot_clear; + conn->data_prot = PROT_CLEAR; #endif return conn; -- cgit v1.2.1 From 5db0a412ff6972e51ccddaf1e8d6a27c8de4990f Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 28 Nov 2010 23:11:14 +0100 Subject: atoi: remove atoi usage --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e915c7947..0aed7b44b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4155,7 +4155,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, *prox_portno = 0x0; /* cut off number from host name */ prox_portno ++; /* now set the local port number */ - conn->port = atoi(prox_portno); + conn->port = strtol(prox_portno, NULL, 10); } else { /* without a port number after the host name, some people seem to use -- cgit v1.2.1 From c328214a2dc145bd5671c6dcb88865d195c5dea1 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 30 Nov 2010 13:31:25 +0100 Subject: fix getinfo CURLINFO_LOCAL* for reused connections Failed to commit this file changes along with the others. --- lib/url.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0aed7b44b..e3d89ebe6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4599,6 +4599,8 @@ static void reuse_conn(struct connectdata *old_conn, else free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ + strcpy(conn->ip_addr_str, old_conn->ip_addr_str); + /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ @@ -4925,12 +4927,6 @@ static CURLcode create_conn(struct SessionHandle *data, infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->proxy.name?conn->proxy.dispname:conn->host.dispname); - /* copy this IP address to the common buffer for the easy handle so that - the address can actually survice the removal of this connection. strcpy - is safe since the target buffer is big enough to hold the largest - possible IP address */ - strcpy(data->info.ip, conn->ip_addr_str); - } else { /* -- cgit v1.2.1 From 11cddb68e0ff73c8297b85e51bebaf6f968a8d62 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 30 Nov 2010 22:14:37 +0100 Subject: fix getinfo CURLINFO_LOCAL* for reused connections (take 2) --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e3d89ebe6..858d72927 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4599,7 +4599,8 @@ static void reuse_conn(struct connectdata *old_conn, else free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ - strcpy(conn->ip_addr_str, old_conn->ip_addr_str); + /* persist connection info in session handle */ + Curl_persistconninfo(conn); /* re-use init */ conn->bits.reuse = TRUE; /* yes, we're re-using here */ -- cgit v1.2.1 From 7e3f0bffe5d930489db80e1d65c27fe44a51f6f4 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 1 Dec 2010 23:33:43 +0100 Subject: fix compiler warning: conversion may lose significant bits --- lib/url.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 858d72927..f1ab21c2d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1006,7 +1006,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * An FTP option that modifies an upload to create missing directories on * the server. */ - data->set.ftp_create_missing_dirs = (int)va_arg(param, long); + switch(va_arg(param, long)) { + case 0: + data->set.ftp_create_missing_dirs = 0; + break; + case 1: + data->set.ftp_create_missing_dirs = 1; + break; + case 2: + data->set.ftp_create_missing_dirs = 2; + break; + default: + /* reserve other values for future use */ + result = CURLE_FAILED_INIT; + break; + } break; case CURLOPT_SERVER_RESPONSE_TIMEOUT: /* @@ -2001,13 +2015,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Set what local port to bind the socket to when performing an operation. */ - data->set.localport = (unsigned short) va_arg(param, long); + data->set.localport = curlx_sltous(va_arg(param, long)); break; case CURLOPT_LOCALPORTRANGE: /* * Set number of local ports to try, starting with CURLOPT_LOCALPORT. */ - data->set.localportrange = (int) va_arg(param, long); + data->set.localportrange = curlx_sltosi(va_arg(param, long)); break; case CURLOPT_KRBLEVEL: /* @@ -2356,7 +2370,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * know that an unsigned int will always hold the value so we blindly * typecast to this type */ - data->set.scope = (unsigned int) va_arg(param, long); + data->set.scope = curlx_sltoui(va_arg(param, long)); break; case CURLOPT_PROTOCOLS: -- cgit v1.2.1 From 5c7c9a768d009319520142fcaee1dea33625060f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 19 Nov 2010 13:43:20 +0100 Subject: url: provide dead_connection flag in Curl_handler::disconnect It helps to prevent a hangup with some FTP servers in case idle session timeout has exceeded. But it may be useful also for other protocols that send any quit message on disconnect. Currently used by FTP, POP3, IMAP and SMTP. --- lib/url.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f1ab21c2d..93a56002d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -651,7 +651,7 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, close handles not in use. */ for(i=newamount; i< c->num; i++) - Curl_disconnect(c->connects[i]); + Curl_disconnect(c->connects[i], /* dead_connection */ FALSE); /* If the most recent connection is no longer valid, mark it invalid. */ @@ -2587,7 +2587,7 @@ static void conn_free(struct connectdata *conn) free(conn); /* free all the connection oriented data */ } -CURLcode Curl_disconnect(struct connectdata *conn) +CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) { struct SessionHandle *data; if(!conn) @@ -2647,7 +2647,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ - conn->handler->disconnect(conn); + conn->handler->disconnect(conn, dead_connection); if(-1 != conn->connectindex) { /* unlink ourselves! */ @@ -2915,7 +2915,8 @@ ConnectionExists(struct SessionHandle *data, check->data = data; infof(data, "Connection #%ld seems to be dead!\n", i); - Curl_disconnect(check); /* disconnect resources */ + /* disconnect resources */ + Curl_disconnect(check, /* dead_connection */ TRUE); data->state.connc->connects[i]=NULL; /* nothing here */ continue; @@ -3102,7 +3103,7 @@ ConnectionKillOne(struct SessionHandle *data) conn->data = data; /* the winner gets the honour of being disconnected */ - (void)Curl_disconnect(conn); + (void)Curl_disconnect(conn, /* dead_connection */ FALSE); /* clean the array entry */ data->state.connc->connects[connindex] = NULL; @@ -5116,7 +5117,7 @@ CURLcode Curl_connect(struct SessionHandle *data, if(code && *in_connect) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ - Curl_disconnect(*in_connect); /* close the connection */ + Curl_disconnect(*in_connect, FALSE); /* close the connection */ *in_connect = NULL; /* return a NULL */ } @@ -5236,7 +5237,7 @@ CURLcode Curl_done(struct connectdata **connp, */ if(data->set.reuse_forbid || conn->bits.close || premature || (-1 == conn->connectindex)) { - CURLcode res2 = Curl_disconnect(conn); /* close the connection */ + CURLcode res2 = Curl_disconnect(conn, FALSE); /* close the connection */ /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ -- cgit v1.2.1 From 5965d4554da93cba5a866f9961c9b8f7bf163215 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Dec 2010 15:33:38 +0100 Subject: disconnect: pass on the dead_connection argument Cleanup fix after Kamil's commit 5c7c9a768d0093 --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 93a56002d..7ba262ae2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5145,7 +5145,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, if(code) /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ - Curl_disconnect(conn); /* close the connection */ + Curl_disconnect(conn, FALSE); /* close the connection */ return code; #else -- cgit v1.2.1 From a865bd9fbaaa43e5cbccb9f14d62fc346053c701 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Dec 2010 13:44:50 +0100 Subject: IsPipeliningPossible: only for HTTP The function that checks if pipelining is possible now requires the HTTP bit to be set so that it doesn't mistakenly tries to do it for other protocols. Bug: http://curl.haxx.se/mail/lib-2010-12/0152.html Reported by: Dmitri Shubin --- lib/url.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7ba262ae2..8511ffe4c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2738,12 +2738,14 @@ static bool RTSPConnIsDead(struct connectdata *check) } #endif /* CURL_DISABLE_RTSP */ -static bool IsPipeliningPossible(const struct SessionHandle *handle) +static bool IsPipeliningPossible(const struct SessionHandle *handle, + const struct connectdata *conn) { - if(handle->multi && Curl_multi_canPipeline(handle->multi) && - (handle->set.httpreq == HTTPREQ_GET || - handle->set.httpreq == HTTPREQ_HEAD) && - handle->set.httpversion != CURL_HTTP_VERSION_1_0) + if((conn->handler->protocol & PROT_HTTP) && + handle->multi && Curl_multi_canPipeline(handle->multi) && + (handle->set.httpreq == HTTPREQ_GET || + handle->set.httpreq == HTTPREQ_HEAD) && + handle->set.httpversion != CURL_HTTP_VERSION_1_0) return TRUE; return FALSE; @@ -2760,13 +2762,6 @@ bool Curl_isPipeliningEnabled(const struct SessionHandle *handle) CURLcode Curl_addHandleToPipeline(struct SessionHandle *data, struct curl_llist *pipeline) { -#ifdef DEBUGBUILD - if(!IsPipeliningPossible(data)) { - /* when not pipelined, there MUST be no handle in the list already */ - if(pipeline->head) - infof(data, "PIPE when no PIPE supposed!\n"); - } -#endif if(!Curl_llist_insert_next(pipeline, pipeline->tail, data)) return CURLE_OUT_OF_MEMORY; return CURLE_OK; @@ -2876,7 +2871,7 @@ ConnectionExists(struct SessionHandle *data, { long i; struct connectdata *check; - bool canPipeline = IsPipeliningPossible(data); + bool canPipeline = IsPipeliningPossible(data, needle); for(i=0; i< data->state.connc->num; i++) { bool match = FALSE; @@ -2928,11 +2923,11 @@ ConnectionExists(struct SessionHandle *data, struct SessionHandle* sh = gethandleathead(check->send_pipe); struct SessionHandle* rh = gethandleathead(check->recv_pipe); if(sh) { - if(!IsPipeliningPossible(sh)) + if(!IsPipeliningPossible(sh, check)) continue; } else if(rh) { - if(!IsPipeliningPossible(rh)) + if(!IsPipeliningPossible(rh, check)) continue; } -- cgit v1.2.1 From 6b5dc725756984da68da5c3866c6bb8ef10527cb Mon Sep 17 00:00:00 2001 From: Pasha Kuznetsov Date: Sat, 18 Dec 2010 22:35:37 +0100 Subject: Curl_do: avoid using stale conn pointer Since the original `conn' pointer was used after the `connectdata' it points to has been closed/cleaned up by Curl_reconnect_request it caused a crash. We must make sure to use the newly created connection instead! URL: http://curl.haxx.se/mail/lib-2010-12/0202.html --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8511ffe4c..95d024d52 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5347,12 +5347,13 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) if(result == CURLE_OK) { /* ... finally back to actually retry the DO phase */ + conn = *connp; /* re-assign conn since Curl_reconnect_request + creates a new connection */ result = conn->handler->do_it(conn, done); } } - else { + else return result; - } } if((result == CURLE_OK) && *done) -- cgit v1.2.1 From b6a3e2be8e1bbb183597399c0dcdaa67022b958e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 27 Dec 2010 09:55:13 +0100 Subject: c-ares: fix cancelled resolves When built IPv6-enabled, we could do Curl_done() with one of the two resolves having returned already, so when ares_cancel() is called the resolve callback ends up doing funny things (sometimes resulting in a segfault) since it would try to actually store the previous resolve even though we're shutting down the resolve. This bug was introduced in commit 8ab137b2bc9630ce so it hasn't been included in any public release. Bug: http://curl.haxx.se/bug/view.cgi?id=3145445 Reported by: Pedro Larroy --- lib/url.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 95d024d52..470b4c94c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5210,10 +5210,6 @@ CURLcode Curl_done(struct connectdata **connp, data->state.tempwrite = NULL; } - /* for ares-using, make sure all possible outstanding requests are properly - cancelled before we proceed */ - ares_cancel(data->state.areschannel); - /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this no matter what we think. -- cgit v1.2.1 From 420eac5542ebf41a1812ae2250a0bc09517b999d Mon Sep 17 00:00:00 2001 From: Pierre Joye Date: Tue, 28 Dec 2010 19:55:00 +0100 Subject: IDN: use win32 API if told to The functionality is provided in a new source file: lib/idn_win32.c --- lib/url.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 470b4c94c..ed310b38b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2658,7 +2658,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) data->state.connc->connects[conn->connectindex] = NULL; } -#ifdef USE_LIBIDN +#if defined(USE_LIBIDN) if(conn->host.encalloc) idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed with idn_free() since this was allocated @@ -2667,6 +2667,14 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed with idn_free() since this was allocated by libidn */ +#elif defined(USE_WIN32_IDN) + free(conn->host.encalloc); /* encoded host name buffer, must be freed with + idn_free() since this was allocated by + curl_win32_idn_to_ascii */ + if(conn->proxy.encalloc) + free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed + with idn_free() since this was allocated by + curl_win32_idn_to_ascii */ #endif Curl_ssl_close(conn, FIRSTSOCKET); @@ -3368,7 +3376,6 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, /* * Helpers for IDNA convertions. */ -#ifdef USE_LIBIDN static bool is_ASCII_name(const char *hostname) { const unsigned char *ch = (const unsigned char*)hostname; @@ -3380,6 +3387,7 @@ static bool is_ASCII_name(const char *hostname) return TRUE; } +#ifdef USE_LIBIDN /* * Check if characters in hostname is allowed in Top Level Domain. */ @@ -3438,13 +3446,12 @@ static void fix_hostname(struct SessionHandle *data, /* set the name we use to display the host name */ host->dispname = host->name; - + if(!is_ASCII_name(host->name)) { #ifdef USE_LIBIDN /************************************************************* * Check name for non-ASCII and convert hostname to ACE form. *************************************************************/ - if(!is_ASCII_name(host->name) && - stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { + if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { char *ace_hostname = NULL; int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); infof (data, "Input domain encoded as `%s'\n", @@ -3462,7 +3469,24 @@ static void fix_hostname(struct SessionHandle *data, host->name = host->encalloc; } } +#elif defined(USE_WIN32_IDN) + /************************************************************* + * Check name for non-ASCII and convert hostname to ACE form. + *************************************************************/ + char *ace_hostname = NULL; + int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname, 0); + if(rc == 0) + infof(data, "Failed to convert %s to ACE;\n", + host->name); + else { + host->encalloc = ace_hostname; + /* change the name pointer to point to the encoded hostname */ + host->name = host->encalloc; + } +#else + infof (data, "IDN support not present, can't parse Unicode (UTF-8) domains"); #endif + } } static void llist_dtor(void *user, void *element) -- cgit v1.2.1 From adb49ad8bb280b586b387ba930c0681afee03923 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 Jan 2011 23:07:58 +0100 Subject: Curl_timeleft: s/conn/data in first argument As the function doesn't really use the connectdata struct but only the SessionHanadle struct I modified what argument it wants. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ed310b38b..6741f18bb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -4515,7 +4515,7 @@ static CURLcode resolve_server(struct SessionHandle *data, bool *async) { CURLcode result=CURLE_OK; - long timeout_ms = Curl_timeleft(conn, NULL, TRUE); + long timeout_ms = Curl_timeleft(data, NULL, TRUE); /************************************************************* * Resolve the name of the server or proxy -- cgit v1.2.1 From 1d28efb9d1759bcbc81d28e462c2e3a5d60a17e4 Mon Sep 17 00:00:00 2001 From: Marcel Roelofs Date: Wed, 5 Jan 2011 17:01:07 +0100 Subject: HTTP: HTTP Negotiate authentication using SSPI Only under Windows --- lib/url.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6741f18bb..f8bd07aad 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1454,8 +1454,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef HAVE_GSSAPI - auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ +#ifndef USE_HTTP_NEGOTIATE + auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ #endif if(!auth) return CURLE_FAILED_INIT; /* no supported types left! */ @@ -1514,8 +1514,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef HAVE_GSSAPI - auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */ +#ifndef USE_HTTP_NEGOTIATE + auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ #endif if(!auth) return CURLE_FAILED_INIT; /* no supported types left! */ -- cgit v1.2.1 From 59cf93ccdbaa5e866f9de6b2d9b1ae5cee84863f Mon Sep 17 00:00:00 2001 From: Quinn Slack Date: Wed, 19 Jan 2011 20:35:02 +0100 Subject: TLS-SRP: support added when using GnuTLS --- lib/url.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f8bd07aad..cd89e1f89 100644 --- a/lib/url.c +++ b/lib/url.c @@ -751,6 +751,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) */ set->ssl.verifypeer = TRUE; set->ssl.verifyhost = 2; +#ifdef USE_TLS_SRP + set->ssl.authtype = CURL_TLSAUTH_NONE; +#endif set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth type */ set->ssl.sessionid = TRUE; /* session ID caching enabled by default */ @@ -2526,6 +2529,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_FNMATCH_DATA: data->set.fnmatch_data = va_arg(param, void *); break; +#ifdef USE_TLS_SRP + case CURLOPT_TLSAUTH_USERNAME: + result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], + va_arg(param, char *)); + if (data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_PASSWORD: + result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], + va_arg(param, char *)); + if (data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_TYPE: + if (strncmp((char *)va_arg(param, char *), "SRP", strlen("SRP")) == 0) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; + else + data->set.ssl.authtype = CURL_TLSAUTH_NONE; + break; +#endif default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -4929,6 +4952,10 @@ static CURLcode create_conn(struct SessionHandle *data, data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; +#ifdef USE_TLS_SRP + data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; + data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; +#endif if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From ef19e30985fabbe6f5abecf623f371450488653c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 27 Jan 2011 14:37:25 +0100 Subject: ares: memory leak fix The double name resolve trick used with c-ares could leave allocated memory in 'temp_ai' if the operation was aborted in the middle. --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cd89e1f89..c07554182 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5241,6 +5241,8 @@ CURLcode Curl_done(struct connectdata **connp, data->req.location = NULL; } + Curl_async_cancel(conn); + if(conn->dns_entry) { Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ conn->dns_entry = NULL; -- cgit v1.2.1 From d85cae922575d8966529fee364e6d611e3062a99 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 17 Feb 2011 23:51:43 +0100 Subject: multi: better failed connect treatment When failing to connect the protocol during the CURLM_STATE_PROTOCONNECT state, Curl_done() has to be called with the premature flag set TRUE as for the pingpong protocols this can be important. When Curl_done() is called with premature == TRUE, it needs to call Curl_disconnect() with its 'dead_connection' argument set to TRUE as well so that any protocol handler's disconnect function won't attempt to use the (control) connection for anything. This problem caused the pingpong protocols to fail to disconnect when STARTTLS failed. Reported by: Alona Rossen Bug: http://curl.haxx.se/mail/lib-2011-02/0195.html --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c07554182..c1dab8254 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5281,7 +5281,7 @@ CURLcode Curl_done(struct connectdata **connp, */ if(data->set.reuse_forbid || conn->bits.close || premature || (-1 == conn->connectindex)) { - CURLcode res2 = Curl_disconnect(conn, FALSE); /* close the connection */ + CURLcode res2 = Curl_disconnect(conn, premature); /* close the connection */ /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ -- cgit v1.2.1 From 29f0898525bf48292606f098bee33ce8f1f58781 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 7 Mar 2011 17:45:33 -0800 Subject: Fixed libcurl to honour the --disable-ldaps configure option --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c1dab8254..5af007172 100644 --- a/lib/url.c +++ b/lib/url.c @@ -184,8 +184,9 @@ static const struct Curl_handler * const protocols[] = { #ifndef CURL_DISABLE_LDAP &Curl_handler_ldap, -#if (defined(USE_OPENLDAP) && defined(USE_SSL)) || \ - (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)) +#if !defined(CURL_DISABLE_LDAPS) && \ + ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ + (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) &Curl_handler_ldaps, #endif #endif -- cgit v1.2.1 From 8831000bc07de463d277975a3ddfb6a31dcf14b4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 14 Mar 2011 22:22:22 +0100 Subject: protocol handler: added flags field The protocol handler struct got a 'flags' field for special information and characteristics of the given protocol. This now enables us to move away central protocol information such as CLOSEACTION and DUALCHANNEL from single defines in a central place, out to each protocol's definition. It also made us stop abusing the protocol field for other info than the protocol, and we could start cleaning up other protocol-specific things by adding flags bits to set in the handler struct. The "protocol" field connectdata struct was removed as well and the code now refers directly to the conn->handler->protocol field instead. To make things work properly, the code now always store a conn->given pointer that points out the original handler struct so that the code can learn details from the original protocol even if conn->handler is modified along the way - for example when switching to go over a HTTP proxy. --- lib/url.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5af007172..e9a7f4a17 100644 --- a/lib/url.c +++ b/lib/url.c @@ -263,7 +263,8 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* disconnect */ 0, /* defport */ - 0 /* protocol */ + 0, /* protocol */ + 0 /* flags */ }; void Curl_safefree(void *ptr) @@ -765,9 +766,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) /* for the *protocols fields we don't use the CURLPROTO_ALL convenience define since we internally only use the lower 16 bits for the passed in bitmask to not conflict with the private bits */ - set->allowed_protocols = PROT_EXTMASK; + set->allowed_protocols = PROT_ALL; set->redir_protocols = - PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */ + PROT_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */ #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) /* @@ -2382,7 +2383,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, transfer, which thus helps the app which takes URLs from users or other external inputs and want to restrict what protocol(s) to deal with. Defaults to CURLPROTO_ALL. */ - data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK; + data->set.allowed_protocols = va_arg(param, long); break; case CURLOPT_REDIR_PROTOCOLS: @@ -2390,7 +2391,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs to be set in both bitmasks to be allowed to get redirected to. Defaults to all protocols except FILE and SCP. */ - data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK; + data->set.redir_protocols = va_arg(param, long); break; case CURLOPT_MAIL_FROM: @@ -2931,7 +2932,7 @@ ConnectionExists(struct SessionHandle *data, use */ bool dead; #ifndef CURL_DISABLE_RTSP - if(check->protocol & PROT_RTSP) + if(check->handler->protocol & PROT_RTSP) /* RTSP is a special case due to RTP interleaving */ dead = RTSPConnIsDead(check); else @@ -3003,11 +3004,12 @@ ConnectionExists(struct SessionHandle *data, } } - if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL)) + if((needle->handler->flags&PROTOPT_SSL) != + (check->handler->flags&PROTOPT_SSL)) /* don't do mixed SSL and non-SSL connections */ continue; - if(needle->protocol&PROT_SSL) { + if(needle->handler->flags&PROTOPT_SSL) { if((data->set.ssl.verifypeer != check->verifypeer) || (data->set.ssl.verifyhost != check->verifyhost)) continue; @@ -3022,7 +3024,7 @@ ConnectionExists(struct SessionHandle *data, in use so we skip it */ continue; - if(!needle->bits.httpproxy || needle->protocol&PROT_SSL || + if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL || (needle->bits.httpproxy && check->bits.httpproxy && needle->bits.tunnel_proxy && check->bits.tunnel_proxy && Curl_raw_equal(needle->proxy.name, check->proxy.name) && @@ -3034,7 +3036,7 @@ ConnectionExists(struct SessionHandle *data, if(Curl_raw_equal(needle->handler->scheme, check->handler->scheme) && Curl_raw_equal(needle->host.name, check->host.name) && (needle->remote_port == check->remote_port) ) { - if(needle->protocol & PROT_SSL) { + if(needle->handler->flags & PROTOPT_SSL) { /* This is SSL, verify that we're using the same ssl options as well */ if(!Curl_ssl_config_matches(&needle->ssl_config, @@ -3053,8 +3055,8 @@ ConnectionExists(struct SessionHandle *data, continue; } } - if((needle->protocol & PROT_FTP) || - ((needle->protocol & PROT_HTTP) && + if((needle->handler->protocol & PROT_FTP) || + ((needle->handler->protocol & PROT_HTTP) && (data->state.authhost.want==CURLAUTH_NTLM))) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ @@ -3639,8 +3641,7 @@ static CURLcode findprotocol(struct SessionHandle *data, break; /* Perform setup complement if some. */ - conn->handler = p; - conn->protocol |= p->protocol; + conn->handler = conn->given = p; /* 'port' and 'remote_port' are set in setup_connection_internals() */ return CURLE_OK; @@ -3938,8 +3939,7 @@ static CURLcode setup_connection_internals(struct connectdata *conn) /* we check for -1 here since if proxy was detected already, this was very likely already set to the proxy port */ conn->port = p->defport; - conn->remote_port = (unsigned short)p->defport; - conn->protocol |= p->protocol; + conn->remote_port = (unsigned short)conn->given->defport; return CURLE_OK; } @@ -4418,7 +4418,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data, * stripped off. It would be better to work directly from the original * URL and simply replace the port part of it. */ - url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->handler->scheme, + url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme, conn->bits.ipv6_ip?"[":"", conn->host.name, conn->bits.ipv6_ip?"]":"", conn->remote_port, data->state.slash_removed?"/":"", data->state.path, @@ -4507,7 +4507,7 @@ static CURLcode set_userpass(struct connectdata *conn, const char *user, const char *passwd) { /* If our protocol needs a password and we have none, use the defaults */ - if( (conn->protocol & (PROT_FTP|PROT_IMAP)) && + if( (conn->handler->protocol & (PROT_FTP|PROT_IMAP)) && !conn->bits.user_passwd) { conn->user = strdup(CURL_DEFAULT_USER); @@ -4829,13 +4829,11 @@ static CURLcode create_conn(struct SessionHandle *data, proxy = NULL; } /* proxy must be freed later unless NULL */ - if(proxy) { - long bits = conn->protocol & (PROT_HTTPS|PROT_SSL); - + if(proxy && !(conn->handler->flags & PROTOPT_BANPROXY)) { if((conn->proxytype == CURLPROXY_HTTP) || (conn->proxytype == CURLPROXY_HTTP_1_0)) { /* force this connection's protocol to become HTTP */ - conn->protocol = PROT_HTTP | bits; + conn->handler = &Curl_handler_http; conn->bits.httpproxy = TRUE; } conn->bits.proxy = TRUE; @@ -4881,7 +4879,7 @@ static CURLcode create_conn(struct SessionHandle *data, * file: is a special case in that it doesn't need a network connection ***********************************************************************/ #ifndef CURL_DISABLE_FILE - if(conn->protocol & PROT_FILE) { + if(conn->handler->protocol & PROT_FILE) { bool done; /* this is supposed to be the connect function so we better at least check that the file is present here! */ @@ -4918,7 +4916,7 @@ static CURLcode create_conn(struct SessionHandle *data, * If the protocol is using SSL and HTTP proxy is used, we set * the tunnel_proxy bit. *************************************************************/ - if((conn->protocol&PROT_SSL) && conn->bits.httpproxy) + if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy) conn->bits.tunnel_proxy = TRUE; /************************************************************* @@ -5041,7 +5039,7 @@ static CURLcode setup_conn(struct connectdata *conn, Curl_pgrsTime(data, TIMER_NAMELOOKUP); - if(conn->protocol & PROT_FILE) { + if(conn->handler->protocol & PROT_FILE) { /* There's nothing in this function to setup if we're only doing a file:// transfer */ *protocol_done = TRUE; -- cgit v1.2.1 From 13b64d75589647f8d151e035bd2c5d340a1c37ee Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 14 Mar 2011 22:52:14 +0100 Subject: protocols: use CURLPROTO_ internally The PROT_* set of internal defines for the protocols is no longer used. We now use the same bits internally as we have defined in the public header using the CURLPROTO_ prefix. This is for simplicity and because the PROT_* prefix was already used duplicated internally for a set of KRB4 values. The PROTOPT_* defines were moved up to just below the struct definition within which they are used. --- lib/url.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e9a7f4a17..5faefd931 100644 --- a/lib/url.c +++ b/lib/url.c @@ -766,9 +766,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) /* for the *protocols fields we don't use the CURLPROTO_ALL convenience define since we internally only use the lower 16 bits for the passed in bitmask to not conflict with the private bits */ - set->allowed_protocols = PROT_ALL; + set->allowed_protocols = CURLPROTO_ALL; set->redir_protocols = - PROT_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */ + CURLPROTO_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */ #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) /* @@ -2774,7 +2774,7 @@ static bool RTSPConnIsDead(struct connectdata *check) static bool IsPipeliningPossible(const struct SessionHandle *handle, const struct connectdata *conn) { - if((conn->handler->protocol & PROT_HTTP) && + if((conn->handler->protocol & CURLPROTO_HTTP) && handle->multi && Curl_multi_canPipeline(handle->multi) && (handle->set.httpreq == HTTPREQ_GET || handle->set.httpreq == HTTPREQ_HEAD) && @@ -2932,7 +2932,7 @@ ConnectionExists(struct SessionHandle *data, use */ bool dead; #ifndef CURL_DISABLE_RTSP - if(check->handler->protocol & PROT_RTSP) + if(check->handler->protocol & CURLPROTO_RTSP) /* RTSP is a special case due to RTP interleaving */ dead = RTSPConnIsDead(check); else @@ -3055,8 +3055,8 @@ ConnectionExists(struct SessionHandle *data, continue; } } - if((needle->handler->protocol & PROT_FTP) || - ((needle->handler->protocol & PROT_HTTP) && + if((needle->handler->protocol & CURLPROTO_FTP) || + ((needle->handler->protocol & CURLPROTO_HTTP) && (data->state.authhost.want==CURLAUTH_NTLM))) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ @@ -4507,7 +4507,7 @@ static CURLcode set_userpass(struct connectdata *conn, const char *user, const char *passwd) { /* If our protocol needs a password and we have none, use the defaults */ - if( (conn->handler->protocol & (PROT_FTP|PROT_IMAP)) && + if( (conn->handler->protocol & (CURLPROTO_FTP|CURLPROTO_IMAP)) && !conn->bits.user_passwd) { conn->user = strdup(CURL_DEFAULT_USER); @@ -4879,7 +4879,7 @@ static CURLcode create_conn(struct SessionHandle *data, * file: is a special case in that it doesn't need a network connection ***********************************************************************/ #ifndef CURL_DISABLE_FILE - if(conn->handler->protocol & PROT_FILE) { + if(conn->handler->protocol & CURLPROTO_FILE) { bool done; /* this is supposed to be the connect function so we better at least check that the file is present here! */ @@ -5039,7 +5039,7 @@ static CURLcode setup_conn(struct connectdata *conn, Curl_pgrsTime(data, TIMER_NAMELOOKUP); - if(conn->handler->protocol & PROT_FILE) { + if(conn->handler->protocol & CURLPROTO_FILE) { /* There's nothing in this function to setup if we're only doing a file:// transfer */ *protocol_done = TRUE; -- cgit v1.2.1 From 93290f69d0258ddc7da7d034937f17334fe943b1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 17 Mar 2011 11:45:58 +0100 Subject: connection setup: if HTTP is disabled asking for HTTP proxy is bad --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5faefd931..ecb3d33bb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4832,9 +4832,14 @@ static CURLcode create_conn(struct SessionHandle *data, if(proxy && !(conn->handler->flags & PROTOPT_BANPROXY)) { if((conn->proxytype == CURLPROXY_HTTP) || (conn->proxytype == CURLPROXY_HTTP_1_0)) { +#ifdef CURL_DISABLE_HTTP + /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */ + return CURLE_UNSUPPORTED_PROTOCOL; +#else /* force this connection's protocol to become HTTP */ conn->handler = &Curl_handler_http; conn->bits.httpproxy = TRUE; +#endif } conn->bits.proxy = TRUE; } -- cgit v1.2.1 From 0f07142509d756f127cfba03d9a603d5184eb209 Mon Sep 17 00:00:00 2001 From: Julien Chaffraix Date: Sat, 19 Mar 2011 09:44:31 -0700 Subject: url: 0 is PROTOPT_NONE. Tiny tweak after Daniel's refactoring of the protocol handlers. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ecb3d33bb..47ac725f3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -264,7 +264,7 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* disconnect */ 0, /* defport */ 0, /* protocol */ - 0 /* flags */ + PROTOPT_NONE /* flags */ }; void Curl_safefree(void *ptr) -- cgit v1.2.1 From cc9e4321d38f26fec59789a7b3a3bf6a0bf27ce4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 23 Mar 2011 17:27:58 +0100 Subject: rtsp: move protocol code to dedicated file The RTSP-specific function for checking for "dead" connection is better located in rtsp.c. The code using this is now written without #ifdefs as the function call is instead turned into a macro (in rtsp.h) when RTSP is disabled. --- lib/url.c | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 47ac725f3..106d4e7ec 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2736,41 +2736,6 @@ static bool SocketIsDead(curl_socket_t sock) return ret_val; } -#ifndef CURL_DISABLE_RTSP -/* - * The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not - * want to block the application forever while receiving a stream. Therefore, - * we cannot assume that an RTSP socket is dead just because it is readable. - * - * Instead, if it is readable, run Curl_getconnectinfo() to peek at the socket - * and distinguish between closed and data. - */ -static bool RTSPConnIsDead(struct connectdata *check) -{ - int sval; - bool ret_val = TRUE; - - sval = Curl_socket_ready(check->sock[FIRSTSOCKET], CURL_SOCKET_BAD, 0); - if(sval == 0) { - /* timeout */ - ret_val = FALSE; - } - else if (sval & CURL_CSELECT_ERR) { - /* socket is in an error state */ - ret_val = TRUE; - } - else if (sval & CURL_CSELECT_IN) { - /* readable with no error. could be closed or could be alive */ - curl_socket_t connectinfo = - Curl_getconnectinfo(check->data, &check); - if(connectinfo != CURL_SOCKET_BAD) - ret_val = FALSE; - } - - return ret_val; -} -#endif /* CURL_DISABLE_RTSP */ - static bool IsPipeliningPossible(const struct SessionHandle *handle, const struct connectdata *conn) { @@ -2931,12 +2896,10 @@ ConnectionExists(struct SessionHandle *data, handles in pipeline and the connection isn't already marked in use */ bool dead; -#ifndef CURL_DISABLE_RTSP if(check->handler->protocol & CURLPROTO_RTSP) /* RTSP is a special case due to RTP interleaving */ - dead = RTSPConnIsDead(check); + dead = Curl_rtsp_connisdead(check); else -#endif /*CURL_DISABLE_RTSP*/ dead = SocketIsDead(check->sock[FIRSTSOCKET]); if(dead) { -- cgit v1.2.1 From 11c2db2aa2a8ce5f3c151d6075066283e65bfd85 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 25 Mar 2011 16:00:41 +0100 Subject: fix: re-use of bound connections When asked to bind the local end of a connection when doing a request, the code will now disqualify other existing connections from re-use even if they are connected to the correct remote host. This will also affect which connections that can be used for pipelining, so that only connections that aren't bound or bound to the same device/port you're asking for will be considered. --- lib/url.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 106d4e7ec..25f03b7e2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2606,7 +2606,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->async.hostname); Curl_safefree(conn->async.os_specific); #endif - + Curl_safefree(conn->localdev); Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ @@ -2987,6 +2987,25 @@ ConnectionExists(struct SessionHandle *data, in use so we skip it */ continue; + if(needle->localdev || needle->localport) { + /* If we are bound to a specific local end (IP+port), we must not re-use + a random other one, although if we didn't ask for a particular one we + can reuse one that was bound. + + This comparison is a bit rough and too strict. Since the input + parameters can be specified in numerous ways and still end up the + same it would take a lot of processing to make it really accurate. + Instead, this matching will assume that re-uses of bound connections + will most likely also re-use the exact same binding parameters and + missing out a few edge cases shouldn't hurt anyone very much. + */ + if((check->localport != needle->localport) || + (check->localportrange != needle->localportrange) || + !check->localdev || + strcmp(check->localdev, needle->localdev)) + continue; + } + if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL || (needle->bits.httpproxy && check->bits.httpproxy && needle->bits.tunnel_proxy && check->bits.tunnel_proxy && @@ -3568,13 +3587,24 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) conn->data_prot = PROT_CLEAR; #endif + /* Store the local bind parameters that will be used for this connection */ + if(data->set.str[STRING_DEVICE]) { + conn->localdev = strdup(data->set.str[STRING_DEVICE]); + if(!conn->localdev) + goto error; + } + conn->localportrange = data->set.localportrange; + conn->localport = data->set.localport; + return conn; error: + Curl_llist_destroy(conn->send_pipe, NULL); Curl_llist_destroy(conn->recv_pipe, NULL); Curl_llist_destroy(conn->pend_pipe, NULL); Curl_llist_destroy(conn->done_pipe, NULL); Curl_safefree(conn->master_buffer); + Curl_safefree(conn->localdev); Curl_safefree(conn); return NULL; } -- cgit v1.2.1 From 9d1e914a56e8a4030d8917875eaedaddf5cff97c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 4 Apr 2011 15:46:42 +0200 Subject: disable cookies: remove ifdefs, move code 1 - make sure to #define macros for cookie functions in the cookie header when cookies are disabled to avoid having to use #ifdefs in code using those functions. 2 - move cookie-specific code to cookie.c and use the functio conditionally as mentioned in (1). net result: 6 #if lines removed, and 9 lines of code less --- lib/url.c | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 25f03b7e2..5ece35ed2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -377,39 +377,6 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) return r; } -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) -static void flush_cookies(struct SessionHandle *data, int cleanup) -{ - if(data->set.str[STRING_COOKIEJAR]) { - if(data->change.cookielist) { - /* If there is a list of cookie files to read, do it first so that - we have all the told files read before we write the new jar. - Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */ - Curl_cookie_loadfiles(data); - } - - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - - /* if we have a destination file for all the cookies to get dumped to */ - if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) - infof(data, "WARNING: failed to save cookies in %s\n", - data->set.str[STRING_COOKIEJAR]); - } - else { - if(cleanup && data->change.cookielist) - /* since nothing is written, we can just free the list of cookie file - names */ - curl_slist_free_all(data->change.cookielist); /* clean up list */ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - } - - if(cleanup && (!data->share || (data->cookies != data->share->cookies))) { - Curl_cookie_cleanup(data->cookies); - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); -} -#endif - /* * This is the internal function curl_easy_cleanup() calls. This should * cleanup and free all resources associated with this sessionhandle. @@ -548,9 +515,7 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.headerbuff); -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - flush_cookies(data, 1); -#endif + Curl_flush_cookies(data, 1); Curl_digest_cleanup(data); @@ -1393,7 +1358,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } else if(Curl_raw_equal(argptr, "FLUSH")) { /* flush cookies to file */ - flush_cookies(data, 0); + Curl_flush_cookies(data, 0); break; } -- cgit v1.2.1 From 01f05d0c758795e5bb02c6245fc73b8458eb397a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Apr 2011 15:14:02 +0200 Subject: return code cleanup: build, init and run-time errors Stop the abuse of CURLE_FAILED_INIT as return code for things not being init related by introducing two new return codes: CURLE_NOT_BUILT_IN and CURLE_UNKNOWN_OPTION CURLE_NOT_BUILT_IN replaces return code 4 that has been obsoleted for several years. It is used for returning error when something is attempted to be used but the feature/option was not enabled or explictitly disabled at build-time. Getting this error mostly means that libcurl needs to be rebuilt. CURLE_FAILED_INIT is now saved and used strictly for init failures. Getting this problem means something went seriously wrong, like a resource shortage or similar. CURLE_UNKNOWN_OPTION is the option formerly known as CURLE_UNKNOWN_TELNET_OPTION (and the old name is still present, separately defined to be removed in a very distant future). This error code is meant to be used to return when an option is given to libcurl that isn't known. This problem would mostly indicate a problem in the program that uses libcurl. --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5ece35ed2..c7fcdfe96 100644 --- a/lib/url.c +++ b/lib/url.c @@ -988,7 +988,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; default: /* reserve other values for future use */ - result = CURLE_FAILED_INIT; + result = CURLE_UNKNOWN_OPTION; break; } break; @@ -1428,7 +1428,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ #endif if(!auth) - return CURLE_FAILED_INIT; /* no supported types left! */ + return CURLE_NOT_BUILT_IN; /* no supported types left! */ data->set.httpauth = auth; } @@ -1488,7 +1488,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ #endif if(!auth) - return CURLE_FAILED_INIT; /* no supported types left! */ + return CURLE_NOT_BUILT_IN; /* no supported types left! */ data->set.proxyauth = auth; } @@ -1528,7 +1528,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; default: /* reserve other values for future use */ - result = CURLE_FAILED_INIT; + result = CURLE_UNKNOWN_OPTION; break; } break; @@ -2518,7 +2518,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #endif default: /* unknown tag and its companion, just ignore: */ - result = CURLE_FAILED_INIT; /* correct this */ + result = CURLE_UNKNOWN_OPTION; break; } -- cgit v1.2.1 From 0790b2791091ca46bed3813dc7d04cd3f30e5dac Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Apr 2011 23:24:52 +0200 Subject: HTTP: add support for gzip and deflate Transfer-Encoding Transfer-Encoding differs from Content-Encoding in a few subtle ways, but primarily it concerns the transfer only and not the content so when discovered to be compressed we know we have to uncompress it. There will only arrive compressed transfers in a response after we have requested them with the appropriate TE: header. Test case 1122 and 1123 verify. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c7fcdfe96..a31c28033 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2549,6 +2549,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->allocptr.uagent); Curl_safefree(conn->allocptr.userpwd); Curl_safefree(conn->allocptr.accept_encoding); + Curl_safefree(conn->allocptr.te); Curl_safefree(conn->allocptr.rangeline); Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); -- cgit v1.2.1 From 8e4fb01e64bee1893452f25873758cb856898d84 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Apr 2011 22:45:42 +0200 Subject: transfer-encoding: added new option and cmdline Added CURLOPT_TRANSFER_ENCODING as the option to set to request Transfer Encoding in HTTP requests (if built zlib enabled). I also renamed CURLOPT_ENCODING to CURLOPT_ACCEPT_ENCODING (while keeping the old name around) to reduce the confusion when we have to encoding options for HTTP. --tr-encoding is now the new command line option for curl to request this, and thus I updated the test cases accordingly. --- lib/url.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a31c28033..019f9a24b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1076,7 +1076,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.http_auto_referer = (bool)(0 != va_arg(param, long)); break; - case CURLOPT_ENCODING: + case CURLOPT_ACCEPT_ENCODING: /* * String to use at the value of Accept-Encoding header. * @@ -1092,6 +1092,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, (char *) ALL_CONTENT_ENCODINGS: argptr); break; + case CURLOPT_TRANSFER_ENCODING: + data->set.http_transfer_encoding = (bool)(0 != va_arg(param, long)); + break; + case CURLOPT_FOLLOWLOCATION: /* * Follow Location: header hints on a HTTP-server. -- cgit v1.2.1 From 24e5a40156b0dda012d3ff940a49d9fef4524bdc Mon Sep 17 00:00:00 2001 From: Guenter Knauf Date: Tue, 19 Apr 2011 16:45:54 +0200 Subject: Windows native IDN fixes. Provide prototype for curl_win32_idn_to_ascii(); remove wrong 3rd parameter from curl_win32_idn_to_ascii() call. --- lib/url.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 019f9a24b..cf576ad8a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -86,14 +86,16 @@ #ifdef HAVE_IDN_FREE_H #include #else -void idn_free (void *ptr); /* prototype from idn-free.h, not provided by - libidn 0.4.5's make install! */ +/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */ +void idn_free (void *ptr); #endif #ifndef HAVE_IDN_FREE -/* if idn_free() was not found in this version of libidn, use plain free() - instead */ +/* if idn_free() was not found in this version of libidn use free() instead */ #define idn_free(x) (free)(x) #endif +#elif defined(USE_WIN32_IDN) +/* prototype for curl_win32_idn_to_ascii() */ +int curl_win32_idn_to_ascii(const char *in, char **out); #endif /* USE_LIBIDN */ #include "urldata.h" @@ -3452,7 +3454,7 @@ static void fix_hostname(struct SessionHandle *data, * Check name for non-ASCII and convert hostname to ACE form. *************************************************************/ char *ace_hostname = NULL; - int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname, 0); + int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname); if(rc == 0) infof(data, "Failed to convert %s to ACE;\n", host->name); -- cgit v1.2.1 From c828646f60b5bffb2bfcf924eba36da767bf08bf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Apr 2011 00:48:20 +0200 Subject: CURL_DOES_CONVERSIONS: cleanup Massively reduce #ifdefs all over (23 #ifdef lines less so far) Moved conversion-specific code to non-ascii.c --- lib/url.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index cf576ad8a..3bc8db06d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -122,6 +122,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "speedcheck.h" #include "rawstr.h" #include "warnless.h" +#include "non-ascii.h" /* And now for the protocols */ #include "ftp.h" @@ -527,18 +528,7 @@ CURLcode Curl_close(struct SessionHandle *data) /* this destroys the channel and we cannot use it anymore after this */ ares_destroy(data->state.areschannel); -#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) - /* close iconv conversion descriptors */ - if(data->inbound_cd != (iconv_t)-1) { - iconv_close(data->inbound_cd); - } - if(data->outbound_cd != (iconv_t)-1) { - iconv_close(data->outbound_cd); - } - if(data->utf8_cd != (iconv_t)-1) { - iconv_close(data->utf8_cd); - } -#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + Curl_convert_close(data); /* No longer a dirty share, if it exists */ if(data->share) { @@ -816,12 +806,7 @@ CURLcode Curl_open(struct SessionHandle **curl) data->state.headersize=HEADERSIZE; -#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) - /* conversion descriptors for iconv calls */ - data->outbound_cd = (iconv_t)-1; - data->inbound_cd = (iconv_t)-1; - data->utf8_cd = (iconv_t)-1; -#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + Curl_convert_init(data); /* most recent connection is not yet defined */ data->state.lastconnect = -1; -- cgit v1.2.1 From ca015f1a45c68aa1d641678cfc13ce0df0c58fe0 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Sat, 29 Jan 2011 20:12:10 +0100 Subject: asynch resolvers: unified Introducing an internal API for handling of different async resolver backends. --- lib/url.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 3bc8db06d..12c70975d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -526,7 +526,7 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->info.wouldredirect); /* this destroys the channel and we cannot use it anymore after this */ - ares_destroy(data->state.areschannel); + Curl_resolver_cleanup(data->state.resolver); Curl_convert_close(data); @@ -766,9 +766,7 @@ CURLcode Curl_open(struct SessionHandle **curl) { CURLcode res = CURLE_OK; struct SessionHandle *data; -#ifdef USE_ARES int status; -#endif /* Very simple start-up: alloc the struct, init it with zeroes and return */ data = calloc(1, sizeof(struct SessionHandle)); @@ -780,18 +778,11 @@ CURLcode Curl_open(struct SessionHandle **curl) data->magic = CURLEASY_MAGIC_NUMBER; -#ifdef USE_ARES - if((status = ares_init(&data->state.areschannel)) != ARES_SUCCESS) { - DEBUGF(fprintf(stderr, "Error: ares_init failed\n")); + if( (status=Curl_resolver_init(&data->state.resolver)) != CURLE_OK ) { + DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); free(data); - if(status == ARES_ENOMEM) - return CURLE_OUT_OF_MEMORY; - else - return CURLE_FAILED_INIT; + return status; } - /* make sure that all other returns from this function should destroy the - ares channel before returning error! */ -#endif /* We do some initial setup here, all those fields that can't be just 0 */ @@ -823,7 +814,7 @@ CURLcode Curl_open(struct SessionHandle **curl) } if(res) { - ares_destroy(data->state.areschannel); + Curl_resolver_cleanup(data->state.resolver); if(data->state.headerbuff) free(data->state.headerbuff); Curl_freeset(data); @@ -2521,6 +2512,11 @@ static void conn_free(struct connectdata *conn) if(!conn) return; + /* possible left-overs from the async name resolvers */ +#if defined(CURLRES_ASYNCH) + Curl_async_cancel(conn); +#endif + /* close the SSL stuff before we close any sockets since they will/may write to the sockets */ Curl_ssl_close(conn, FIRSTSOCKET); @@ -2564,6 +2560,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->async.os_specific); #endif Curl_safefree(conn->localdev); + Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ @@ -5195,7 +5192,9 @@ CURLcode Curl_done(struct connectdata **connp, data->req.location = NULL; } +#if defined(CURLRES_ASYNCH) Curl_async_cancel(conn); +#endif if(conn->dns_entry) { Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ -- cgit v1.2.1 From 24d84da0731f680a9b19653a450d4843f190d6b8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 30 Jan 2011 01:00:52 +0100 Subject: asynch resolvers: cleanup Fixed indents, coding conventions and white space edits. Modified the c-ares completion callback function to again NOT read the conn data when the ares handle is being taken down as then it may have been freed already. --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 12c70975d..592763f89 100644 --- a/lib/url.c +++ b/lib/url.c @@ -778,7 +778,8 @@ CURLcode Curl_open(struct SessionHandle **curl) data->magic = CURLEASY_MAGIC_NUMBER; - if( (status=Curl_resolver_init(&data->state.resolver)) != CURLE_OK ) { + status = Curl_resolver_init(&data->state.resolver); + if(status) { DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); free(data); return status; -- cgit v1.2.1 From 7de2f9271c68c10ee7057c10741b0406bca6c156 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Jan 2011 00:10:35 +0100 Subject: async resolvers: further cleanups asyn-ares.c and asyn-thread.c are two separate backends that implement the same (internal) async resolver API for libcurl to use. Backend is specified at build time. The internal resolver API is defined in asyn.h for asynch resolvers. --- lib/url.c | 78 ++++++++++++++------------------------------------------------- 1 file changed, 17 insertions(+), 61 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 592763f89..054b866ae 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2514,9 +2514,7 @@ static void conn_free(struct connectdata *conn) return; /* possible left-overs from the async name resolvers */ -#if defined(CURLRES_ASYNCH) - Curl_async_cancel(conn); -#endif + Curl_resolver_cancel(conn); /* close the SSL stuff before we close any sockets since they will/may write to the sockets */ @@ -2553,15 +2551,7 @@ static void conn_free(struct connectdata *conn) Curl_llist_destroy(conn->pend_pipe, NULL); Curl_llist_destroy(conn->done_pipe, NULL); - /* possible left-overs from the async name resolvers */ -#if defined(CURLRES_THREADED) - Curl_destroy_thread_data(&conn->async); -#elif defined(CURLRES_ASYNCH) - Curl_safefree(conn->async.hostname); - Curl_safefree(conn->async.os_specific); -#endif Curl_safefree(conn->localdev); - Curl_free_ssl_config(&conn->ssl_config); free(conn); /* free all the connection oriented data */ @@ -2896,16 +2886,16 @@ ConnectionExists(struct SessionHandle *data, continue; } -#ifdef CURLRES_ASYNCH - /* ip_addr_str[0] is NUL only if the resolving of the name hasn't - completed yet and until then we don't re-use this connection */ - if(!check->ip_addr_str[0]) { - infof(data, - "Connection #%ld hasn't finished name resolve, can't reuse\n", - check->connectindex); - continue; + if(Curl_resolver_asynch()) { + /* ip_addr_str[0] is NUL only if the resolving of the name hasn't + completed yet and until then we don't re-use this connection */ + if(!check->ip_addr_str[0]) { + infof(data, + "Connection #%ld hasn't finished name resolve, can't reuse\n", + check->connectindex); + continue; + } } -#endif if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { /* Don't pick a connection that hasn't connected yet or that is going @@ -4633,7 +4623,7 @@ static void reuse_conn(struct connectdata *old_conn, * @param data The sessionhandle pointer * @param in_connect is set to the next connection data pointer * @param async is set TRUE when an async DNS resolution is pending - * @see setup_conn() + * @see Curl_setup_conn() * * *NOTE* this function assigns the conn->data pointer! */ @@ -4976,16 +4966,16 @@ static CURLcode create_conn(struct SessionHandle *data, return result; } -/* setup_conn() is called after the name resolve initiated in +/* Curl_setup_conn() is called after the name resolve initiated in * create_conn() is all done. * - * setup_conn() also handles reused connections + * Curl_setup_conn() also handles reused connections * * conn->data MUST already have been setup fine (in create_conn) */ -static CURLcode setup_conn(struct connectdata *conn, - bool *protocol_done) +CURLcode Curl_setup_conn(struct connectdata *conn, + bool *protocol_done) { CURLcode result=CURLE_OK; struct SessionHandle *data = conn->data; @@ -5108,7 +5098,7 @@ CURLcode Curl_connect(struct SessionHandle *data, /* DNS resolution is done: that's either because this is a reused connection, in which case DNS was unnecessary, or because DNS really did finish already (synch resolver/fast async resolve) */ - code = setup_conn(*in_connect, protocol_done); + code = Curl_setup_conn(*in_connect, protocol_done); } } @@ -5122,38 +5112,6 @@ CURLcode Curl_connect(struct SessionHandle *data, return code; } -/* Call this function after Curl_connect() has returned async=TRUE and - then a successful name resolve has been received. - - Note: this function disconnects and frees the conn data in case of - resolve failure */ -CURLcode Curl_async_resolved(struct connectdata *conn, - bool *protocol_done) -{ -#ifdef CURLRES_ASYNCH - CURLcode code; - - if(conn->async.dns) { - conn->dns_entry = conn->async.dns; - conn->async.dns = NULL; - } - - code = setup_conn(conn, protocol_done); - - if(code) - /* We're not allowed to return failure with memory left allocated - in the connectdata struct, free those here */ - Curl_disconnect(conn, FALSE); /* close the connection */ - - return code; -#else - (void)conn; - (void)protocol_done; - return CURLE_OK; -#endif -} - - CURLcode Curl_done(struct connectdata **connp, CURLcode status, /* an error if this is called after an error was detected */ @@ -5193,9 +5151,7 @@ CURLcode Curl_done(struct connectdata **connp, data->req.location = NULL; } -#if defined(CURLRES_ASYNCH) - Curl_async_cancel(conn); -#endif + Curl_resolver_cancel(conn); if(conn->dns_entry) { Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ -- cgit v1.2.1 From b903186fa0189ff241d756d25d07fdfe9885ae49 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Apr 2011 15:17:42 +0200 Subject: source cleanup: unify look, style and indent levels By the use of a the new lib/checksrc.pl script that checks that our basic source style rules are followed. --- lib/url.c | 117 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 59 insertions(+), 58 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 054b866ae..d8642e31b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -331,7 +331,7 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, } separator = strchr(option, ':'); - if (separator != NULL) { + if(separator != NULL) { /* store username part of option */ char * p; @@ -347,9 +347,8 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, } /* store password part of option */ - if (result == CURLE_OK) { + if(result == CURLE_OK) result = setstropt(pwd_storage, separator+1); - } } else { result = setstropt(user_storage, option); @@ -411,7 +410,7 @@ CURLcode Curl_close(struct SessionHandle *data) pipeline = connptr->send_pipe; if(pipeline) { - for (curr = pipeline->head; curr; curr=curr->next) { + for(curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "problem we %p are still in send pipe for %p done %d\n", @@ -421,7 +420,7 @@ CURLcode Curl_close(struct SessionHandle *data) } pipeline = connptr->recv_pipe; if(pipeline) { - for (curr = pipeline->head; curr; curr=curr->next) { + for(curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "problem we %p are still in recv pipe for %p done %d\n", @@ -431,7 +430,7 @@ CURLcode Curl_close(struct SessionHandle *data) } pipeline = connptr->done_pipe; if(pipeline) { - for (curr = pipeline->head; curr; curr=curr->next) { + for(curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "problem we %p are still in done pipe for %p done %d\n", @@ -441,7 +440,7 @@ CURLcode Curl_close(struct SessionHandle *data) } pipeline = connptr->pend_pipe; if(pipeline) { - for (curr = pipeline->head; curr; curr=curr->next) { + for(curr = pipeline->head; curr; curr=curr->next) { if(data == (struct SessionHandle *) curr->ptr) { fprintf(stderr, "problem we %p are still in pend pipe for %p done %d\n", @@ -736,7 +735,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) /* set default gssapi service name */ res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE], (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE); - if (res != CURLE_OK) + if(res != CURLE_OK) return res; #endif @@ -1408,7 +1407,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef USE_HTTP_NEGOTIATE - auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ + auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or + WINDOWS_SSPI */ #endif if(!auth) return CURLE_NOT_BUILT_IN; /* no supported types left! */ @@ -1468,7 +1468,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef USE_HTTP_NEGOTIATE - auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ + auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or + WINDOWS_SSPI */ #endif if(!auth) return CURLE_NOT_BUILT_IN; /* no supported types left! */ @@ -2483,17 +2484,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_TLSAUTH_USERNAME: result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], va_arg(param, char *)); - if (data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ break; case CURLOPT_TLSAUTH_PASSWORD: result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], va_arg(param, char *)); - if (data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ break; case CURLOPT_TLSAUTH_TYPE: - if (strncmp((char *)va_arg(param, char *), "SRP", strlen("SRP")) == 0) + if(strncmp((char *)va_arg(param, char *), "SRP", strlen("SRP")) == 0) data->set.ssl.authtype = CURL_TLSAUTH_SRP; else data->set.ssl.authtype = CURL_TLSAUTH_NONE; @@ -2590,19 +2591,19 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) related stuff. NTLM is connection-related so when we close the shop we shall forget. */ - if (has_host_ntlm) { + if(has_host_ntlm) { data->state.authhost.done = FALSE; data->state.authhost.picked = data->state.authhost.want; } - if (has_proxy_ntlm) { + if(has_proxy_ntlm) { data->state.authproxy.done = FALSE; data->state.authproxy.picked = data->state.authproxy.want; } - if (has_host_ntlm || has_proxy_ntlm) { + if(has_host_ntlm || has_proxy_ntlm) { data->state.authproblem = FALSE; Curl_ntlm_cleanup(conn); @@ -2789,8 +2790,8 @@ static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke) } #endif - if (pipe_broke) - data->state.pipe_broke = TRUE; + if(pipe_broke) + data->state.pipe_broke = TRUE; Curl_multi_handlePipeBreak(data); Curl_llist_remove(pipeline, curr, NULL); curr = next; @@ -3437,7 +3438,7 @@ static void fix_hostname(struct SessionHandle *data, host->name = host->encalloc; } #else - infof (data, "IDN support not present, can't parse Unicode (UTF-8) domains"); + infof (data, "IDN support not present, can't parse Unicode domains"); #endif } } @@ -3564,7 +3565,7 @@ static CURLcode findprotocol(struct SessionHandle *data, /* Scan protocol handler table and match against 'protostr' to set a few variables based on the URL. Now that the handler may be changed later when the protocol specific setup function is called. */ - for (pp = protocols; (p = *pp) != NULL; pp++) { + for(pp = protocols; (p = *pp) != NULL; pp++) { if(Curl_raw_equal(p->scheme, protostr)) { /* Protocol found in table. Check if allowed */ if(!(data->set.allowed_protocols & p->protocol)) @@ -3692,7 +3693,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, * assigned, but the return value is EOF! */ #if defined(__DJGPP__) && (DJGPP_MINOR == 4) - if (!(rc == -1 && *conn->host.name)) + if(!(rc == -1 && *conn->host.name)) #endif { failf(data, " malformed"); @@ -3776,21 +3777,22 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, path[0] = '/'; } - if (conn->host.name[0] == '[') { + if(conn->host.name[0] == '[') { /* This looks like an IPv6 address literal. See if there is an address scope. */ char *percent = strstr (conn->host.name, "%25"); - if (percent) { + if(percent) { char *endp; unsigned long scope = strtoul (percent + 3, &endp, 10); - if (*endp == ']') { + if(*endp == ']') { /* The address scope was well formed. Knock it out of the hostname. */ memmove(percent, endp, strlen(endp)+1); - if (!data->state.this_is_a_follow) + if(!data->state.this_is_a_follow) /* Don't honour a scope given in a Location: header */ conn->scope = (unsigned int)scope; - } else + } + else infof(data, "Invalid IPv6 address format\n"); } } @@ -3915,9 +3917,9 @@ static bool check_noproxy(const char* name, const char* no_proxy) else namelen = strlen(name); - for (tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { - while (tok_start < no_proxy_len && - strchr(separator, no_proxy[tok_start]) != NULL) { + for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { + while(tok_start < no_proxy_len && + strchr(separator, no_proxy[tok_start]) != NULL) { /* Look for the beginning of the token. */ ++tok_start; } @@ -3925,10 +3927,10 @@ static bool check_noproxy(const char* name, const char* no_proxy) if(tok_start == no_proxy_len) break; /* It was all trailing separator chars, no more tokens. */ - for (tok_end = tok_start; tok_end < no_proxy_len && - strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) { + for(tok_end = tok_start; tok_end < no_proxy_len && + strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) /* Look for the end of the token. */ - } + ; /* To match previous behaviour, where it was necessary to specify * ".local.com" to prevent matching "notlocal.com", we will leave @@ -3950,7 +3952,7 @@ static bool check_noproxy(const char* name, const char* no_proxy) } } } /* if((tok_end - tok_start) <= namelen) */ - } /* for (tok_start = 0; tok_start < no_proxy_len; + } /* for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) */ } /* NO_PROXY was specified and it wasn't just an asterisk */ @@ -4133,10 +4135,10 @@ static CURLcode parse_proxy(struct SessionHandle *data, while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') || (*ptr == '.'))) ptr++; - if(*ptr == ']') { + if(*ptr == ']') /* yeps, it ended nicely with a bracket as well */ *ptr++ = 0; - } else + else infof(data, "Invalid IPv6 address format\n"); portptr = ptr; /* Note that if this didn't end with a bracket, we still advanced the @@ -4508,7 +4510,7 @@ static CURLcode resolve_server(struct SessionHandle *data, if(rc == CURLRESOLV_PENDING) *async = TRUE; - else if (rc == CURLRESOLV_TIMEDOUT) + else if(rc == CURLRESOLV_TIMEDOUT) result = CURLE_OPERATION_TIMEDOUT; else if(!hostaddr) { @@ -4530,7 +4532,7 @@ static CURLcode resolve_server(struct SessionHandle *data, if(rc == CURLRESOLV_PENDING) *async = TRUE; - else if (rc == CURLRESOLV_TIMEDOUT) + else if(rc == CURLRESOLV_TIMEDOUT) result = CURLE_OPERATION_TIMEDOUT; else if(!hostaddr) { @@ -4698,9 +4700,8 @@ static CURLcode create_conn(struct SessionHandle *data, conn->host.name[0] = 0; result = parseurlandfillconn(data, conn, &prot_missing); - if(result != CURLE_OK) { - return result; - } + if(result != CURLE_OK) + return result; /************************************************************* * No protocol part in URL was used, add it! @@ -5094,7 +5095,7 @@ CURLcode Curl_connect(struct SessionHandle *data, if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size) /* pipelining */ *protocol_done = TRUE; - else if (!*asyncp) { + else if(!*asyncp) { /* DNS resolution is done: that's either because this is a reused connection, in which case DNS was unnecessary, or because DNS really did finish already (synch resolver/fast async resolve) */ @@ -5191,7 +5192,7 @@ CURLcode Curl_done(struct connectdata **connp, */ if(data->set.reuse_forbid || conn->bits.close || premature || (-1 == conn->connectindex)) { - CURLcode res2 = Curl_disconnect(conn, premature); /* close the connection */ + CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */ /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ @@ -5296,23 +5297,23 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) /* This was formerly done in transfer.c, but we better do it here */ if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { - /* - * If the connection is using an easy handle, call reconnect - * to re-establish the connection. Otherwise, let the multi logic - * figure out how to re-establish the connection. - */ - if(!data->multi) { - result = Curl_reconnect_request(connp); - - if(result == CURLE_OK) { - /* ... finally back to actually retry the DO phase */ - conn = *connp; /* re-assign conn since Curl_reconnect_request - creates a new connection */ - result = conn->handler->do_it(conn, done); - } + /* + * If the connection is using an easy handle, call reconnect + * to re-establish the connection. Otherwise, let the multi logic + * figure out how to re-establish the connection. + */ + if(!data->multi) { + result = Curl_reconnect_request(connp); + + if(result == CURLE_OK) { + /* ... finally back to actually retry the DO phase */ + conn = *connp; /* re-assign conn since Curl_reconnect_request + creates a new connection */ + result = conn->handler->do_it(conn, done); } - else - return result; + } + else + return result; } if((result == CURLE_OK) && *done) -- cgit v1.2.1 From 889d1e973fb718a77c5000141d724ce03863af23 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Apr 2011 23:01:30 +0200 Subject: whitespace cleanup: no space first in conditionals "if(a)" is our style, not "if( a )" --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d8642e31b..16c871df3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4447,8 +4447,8 @@ static CURLcode set_userpass(struct connectdata *conn, const char *user, const char *passwd) { /* If our protocol needs a password and we have none, use the defaults */ - if( (conn->handler->protocol & (CURLPROTO_FTP|CURLPROTO_IMAP)) && - !conn->bits.user_passwd) { + if((conn->handler->protocol & (CURLPROTO_FTP|CURLPROTO_IMAP)) && + !conn->bits.user_passwd) { conn->user = strdup(CURL_DEFAULT_USER); if(conn->user) -- cgit v1.2.1 From 3b1b26578f7b21e2bfca1d1738aa77a44e11e111 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 27 Apr 2011 14:44:00 +0200 Subject: proxy: allow socks:// prefix in proxy string Inspired by a patch from OB.Conseil. Added test case 708 to verify. --- lib/url.c | 76 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 40 insertions(+), 36 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 16c871df3..7c70be818 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3132,25 +3132,22 @@ ConnectionStore(struct SessionHandle *data, */ CURLcode Curl_connected_proxy(struct connectdata *conn) { - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - switch(data->set.proxytype) { + switch(conn->proxytype) { #ifndef CURL_DISABLE_PROXY case CURLPROXY_SOCKS5: case CURLPROXY_SOCKS5_HOSTNAME: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, - conn->host.name, conn->remote_port, - FIRSTSOCKET, conn); - break; + return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, + conn->host.name, conn->remote_port, + FIRSTSOCKET, conn); + case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, FALSE); - break; + return Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, FALSE); + case CURLPROXY_SOCKS4A: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, - conn->remote_port, FIRSTSOCKET, conn, TRUE); - break; + return Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, TRUE); + #endif /* CURL_DISABLE_PROXY */ case CURLPROXY_HTTP: case CURLPROXY_HTTP_1_0: @@ -3160,7 +3157,7 @@ CURLcode Curl_connected_proxy(struct connectdata *conn) break; } /* switch proxytype */ - return result; + return CURLE_OK; } static CURLcode ConnectPlease(struct SessionHandle *data, @@ -4066,16 +4063,23 @@ static CURLcode parse_proxy(struct SessionHandle *data, char *atsign; /* We do the proxy host string parsing here. We want the host name and the - * port name. Accept a protocol:// prefix, even though it should just be - * ignored. + * port name. Accept a protocol:// prefix */ - /* Skip the protocol part if present */ + /* Parse the protocol part if present */ endofprot = strstr(proxy, "://"); - if(endofprot) + if(endofprot) { proxyptr = endofprot+3; + if(checkprefix("socks5", proxy)) + conn->proxytype = CURLPROXY_SOCKS5; + else if(checkprefix("socks4a", proxy)) + conn->proxytype = CURLPROXY_SOCKS4A; + else if(checkprefix("socks4", proxy)) + conn->proxytype = CURLPROXY_SOCKS4; + /* Any other xxx:// : change to http proxy */ + } else - proxyptr = proxy; + proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */ /* Is there a username and password given in this proxy url? */ atsign = strchr(proxyptr, '@'); @@ -4763,12 +4767,24 @@ static CURLcode create_conn(struct SessionHandle *data, else if(!proxy) proxy = detect_proxy(conn); - if(proxy && !*proxy) { - free(proxy); /* Don't bother with an empty proxy string */ + if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_BANPROXY))) { + free(proxy); /* Don't bother with an empty proxy string or if the + protocol doesn't work with proxy */ proxy = NULL; } - /* proxy must be freed later unless NULL */ - if(proxy && !(conn->handler->flags & PROTOPT_BANPROXY)) { + + /*********************************************************************** + * If this is supposed to use a proxy, we need to figure out the proxy host + * name, proxy type and port number, so that we can re-use an existing + * connection that may exist registered to the same proxy host. + ***********************************************************************/ + if(proxy) { + result = parse_proxy(data, conn, proxy); + + /* parse_proxy has freed the proxy string, so don't try to use it again */ + if(result != CURLE_OK) + return result; + if((conn->proxytype == CURLPROXY_HTTP) || (conn->proxytype == CURLPROXY_HTTP_1_0)) { #ifdef CURL_DISABLE_HTTP @@ -4790,18 +4806,6 @@ static CURLcode create_conn(struct SessionHandle *data, conn->bits.tunnel_proxy = FALSE; } - /*********************************************************************** - * If this is supposed to use a proxy, we need to figure out the proxy - * host name, so that we can re-use an existing connection - * that may exist registered to the same proxy host. - ***********************************************************************/ - if(proxy) { - result = parse_proxy(data, conn, proxy); - /* parse_proxy has freed the proxy string, so don't try to use it again */ - proxy = NULL; - if(result != CURLE_OK) - return result; - } #endif /* CURL_DISABLE_PROXY */ /************************************************************* -- cgit v1.2.1 From 821301de15520d51f4cbdba30372bc062f8a955a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 29 Apr 2011 16:46:49 +0200 Subject: ConnectionExists: avoid NULL dereference When checking for connections that are bound to a particular device we must make sure we don't compare with a NULL pointer. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7c70be818..fa0557711 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2948,6 +2948,7 @@ ConnectionExists(struct SessionHandle *data, if((check->localport != needle->localport) || (check->localportrange != needle->localportrange) || !check->localdev || + !needle->localdev || strcmp(check->localdev, needle->localdev)) continue; } -- cgit v1.2.1 From dc15a88076c82aabfd0340bc2eb4ef4086b38cb4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 4 May 2011 23:56:18 +0200 Subject: ConnectionStore: remove unused return code --- lib/url.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fa0557711..1a605c52a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3085,9 +3085,8 @@ ConnectionDone(struct connectdata *conn) * The given connection should be unique. That must've been checked prior to * this call. */ -static long -ConnectionStore(struct SessionHandle *data, - struct connectdata *conn) +static void ConnectionStore(struct SessionHandle *data, + struct connectdata *conn) { long i; for(i=0; i< data->state.connc->num; i++) { @@ -3121,8 +3120,6 @@ ConnectionStore(struct SessionHandle *data, data->state.connc->connects[i] = conn; /* fill in this */ conn->data = data; } - - return i; } /* after a TCP connection to the proxy has been verified, this function does -- cgit v1.2.1 From 61877b569f29ec735e35cf0b52bc1b00ce03078b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 May 2011 00:02:39 +0200 Subject: Corrected comments closepolicy has been deprecated and unused for years --- lib/url.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 1a605c52a..edbb16429 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3025,9 +3025,10 @@ ConnectionExists(struct SessionHandle *data, /* - * This function frees/closes a connection in the connection cache. This - * should take the previously set policy into account when deciding which - * of the connections to kill. + * This function kills and removes an existing connection in the connection + * cache. The connection that has been unused for the longest time. + * + * Returns -1 if it can't find any unused connection to kill. */ static long ConnectionKillOne(struct SessionHandle *data) @@ -3078,9 +3079,9 @@ ConnectionDone(struct connectdata *conn) } /* - * The given input connection struct pointer is to be stored. If the "cache" - * is already full, we must clean out the most suitable using the previously - * set policy. + * The given input connection struct pointer is to be stored in the connection + * cache. If the cache is already full, least interesting existing connection + * (if any) gets closed. * * The given connection should be unique. That must've been checked prior to * this call. -- cgit v1.2.1 From 558f997e99c4c8e4f6ed888a85d748b33920cdf2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 May 2011 11:47:55 +0200 Subject: socks proxy: allow socks5h:// prefix too Using 'socks5h' as proxy protocol will make it a CURLPROXY_SOCKS5_HOSTNAME proxy which is SOCKS5 and asking the proxy to resolve host names. I found no "standard" protocol name for this. --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index edbb16429..22f8b3391 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4069,7 +4069,9 @@ static CURLcode parse_proxy(struct SessionHandle *data, endofprot = strstr(proxy, "://"); if(endofprot) { proxyptr = endofprot+3; - if(checkprefix("socks5", proxy)) + if(checkprefix("socks5h", proxy)) + conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME; + else if(checkprefix("socks5", proxy)) conn->proxytype = CURLPROXY_SOCKS5; else if(checkprefix("socks4a", proxy)) conn->proxytype = CURLPROXY_SOCKS4A; -- cgit v1.2.1 From 51075a6777576a0676a77a49c250a8aba7ea3097 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 May 2011 15:14:19 +0200 Subject: remove FILE protocol-specific checks Also, convert the BANPROXY flag into NONETWORK for the protocols (file:// only atm) that don't work over networks. --- lib/url.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 22f8b3391..30c9d7c02 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4768,9 +4768,9 @@ static CURLcode create_conn(struct SessionHandle *data, else if(!proxy) proxy = detect_proxy(conn); - if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_BANPROXY))) { + if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) { free(proxy); /* Don't bother with an empty proxy string or if the - protocol doesn't work with proxy */ + protocol doesn't work with network */ proxy = NULL; } @@ -4828,7 +4828,7 @@ static CURLcode create_conn(struct SessionHandle *data, * file: is a special case in that it doesn't need a network connection ***********************************************************************/ #ifndef CURL_DISABLE_FILE - if(conn->handler->protocol & CURLPROTO_FILE) { + if(conn->handler->flags & PROTOPT_NONETWORK) { bool done; /* this is supposed to be the connect function so we better at least check that the file is present here! */ @@ -4988,9 +4988,8 @@ CURLcode Curl_setup_conn(struct connectdata *conn, Curl_pgrsTime(data, TIMER_NAMELOOKUP); - if(conn->handler->protocol & CURLPROTO_FILE) { - /* There's nothing in this function to setup if we're only doing - a file:// transfer */ + if(conn->handler->flags & PROTOPT_NONETWORK) { + /* nothing to setup when not using a network */ *protocol_done = TRUE; return result; } -- cgit v1.2.1 From f0612f166a5fa51d09498baa19a327c5cf36941f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 May 2011 16:27:03 +0200 Subject: RTSP: convert protocol-specific checks to generic Add a 'readwrite' function to the protocol handler struct and use that for the extra readwrite functionality RTSP needs. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 30c9d7c02..6a3d81aaf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -265,6 +265,7 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* doing_getsock */ ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ 0, /* defport */ 0, /* protocol */ PROTOPT_NONE /* flags */ -- cgit v1.2.1 From 9c629e534866169b1445bd6614233ded73ff0460 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 May 2011 16:53:05 +0200 Subject: RTSP: cleanups Made several functions static Made one function defined to nothing when RTSP is disabled to avoid the #ifdefs in code. Removed explicit rtsp.h includes --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6a3d81aaf..4771b3b97 100644 --- a/lib/url.c +++ b/lib/url.c @@ -139,7 +139,6 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "inet_ntop.h" #include "http_ntlm.h" #include "socks.h" -#include "rtsp.h" #include "curl_rtmp.h" #include "gopher.h" -- cgit v1.2.1 From 32001ac4149b2062402b5914d756d405ab45c212 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 5 May 2011 17:07:21 +0200 Subject: set_userpass: convert from protocol-specific to generic The protocol handler's flags field now can set that the protocol requires a password, so that the set_userpass function doesn't have to have the specific knowledge of which protocols that do. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4771b3b97..038a02d43 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4452,7 +4452,7 @@ static CURLcode set_userpass(struct connectdata *conn, const char *user, const char *passwd) { /* If our protocol needs a password and we have none, use the defaults */ - if((conn->handler->protocol & (CURLPROTO_FTP|CURLPROTO_IMAP)) && + if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) { conn->user = strdup(CURL_DEFAULT_USER); -- cgit v1.2.1 From b5d170b55110bacc61a4aa8bf99df1afc303c5dc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 16 May 2011 23:46:43 +0200 Subject: CLOSESOCKETFUNCTION: added Introduced the initial setup to allow closesocket callbacks by making sure sclose() is only ever called from one place in the libcurl source and still run all test cases fine. --- lib/url.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 038a02d43..b0b2d8f13 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2232,6 +2232,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.opensocket_client = va_arg(param, void *); break; + case CURLOPT_CLOSESOCKETFUNCTION: + /* + * close socket callback function: called instead of close() + * when shutting down a connection + */ + data->set.fclosesocket = va_arg(param, curl_closesocket_callback); + break; + + case CURLOPT_CLOSESOCKETDATA: + /* + * socket callback data pointer. Might be NULL. + */ + data->set.closesocket_client = va_arg(param, void *); + break; + case CURLOPT_SSL_SESSIONID_CACHE: data->set.ssl.sessionid = (bool)(0 != va_arg(param, long)); break; @@ -2524,9 +2539,9 @@ static void conn_free(struct connectdata *conn) /* close possibly still open sockets */ if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) - sclose(conn->sock[SECONDARYSOCKET]); + Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) - sclose(conn->sock[FIRSTSOCKET]); + Curl_closesocket(conn, conn->sock[FIRSTSOCKET]); Curl_safefree(conn->user); Curl_safefree(conn->passwd); @@ -3538,6 +3553,11 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) conn->localportrange = data->set.localportrange; conn->localport = data->set.localport; + /* the close socket stuff needs to be copied to the connection struct as + it may live on without (this specific) SessionHandle */ + conn->fclosesocket = data->set.fclosesocket; + conn->closesocket_client = data->set.closesocket_client; + return conn; error: -- cgit v1.2.1 From fce7276f5446e7fc1003b98a9a752a3a42a0a247 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 21 May 2011 14:10:17 +0200 Subject: compiler warning: fix Fix compiler warning: enumerated type mixed with another type --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b0b2d8f13..ac3399b9e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -765,7 +765,7 @@ CURLcode Curl_open(struct SessionHandle **curl) { CURLcode res = CURLE_OK; struct SessionHandle *data; - int status; + CURLcode status; /* Very simple start-up: alloc the struct, init it with zeroes and return */ data = calloc(1, sizeof(struct SessionHandle)); -- cgit v1.2.1 From 017ee34bbad9885e524f735401be7ad859cdbd84 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 25 May 2011 15:57:38 +0200 Subject: create_conn: only switch protocol handler if necessary When switching to HTTP because a HTTP proxy is being used, the existing handler is now checked if it already is "compatible". This allows the https handler remain while other non-http handlers will be redirected. Bug: http://curl.haxx.se/mail/lib-2011-05/0214.html Reported by: Jerome Robert --- lib/url.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ac3399b9e..d37fe6dfc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4812,8 +4812,11 @@ static CURLcode create_conn(struct SessionHandle *data, /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */ return CURLE_UNSUPPORTED_PROTOCOL; #else - /* force this connection's protocol to become HTTP */ - conn->handler = &Curl_handler_http; + /* force this connection's protocol to become HTTP if not already + compatible */ + if(!(conn->handler->protocol & CURLPROTO_HTTP)) + conn->handler = &Curl_handler_http; + conn->bits.httpproxy = TRUE; #endif } -- cgit v1.2.1 From f551aa5c1676a8a7d9b0683f047cd6f3fa1b4676 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 7 Jun 2011 15:57:13 +0200 Subject: disconnect: wipe out the keeps_speed time stamp When closing a connection, the speedchecker's timestamp is now deleted so that it cannot accidentally be used by a fresh connection on the same handle when examining the transfer speed. Bug: https://bugzilla.redhat.com/679709 --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d37fe6dfc..c5b642fde 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2675,6 +2675,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) conn_free(conn); data->state.current_conn = NULL; + Curl_speedinit(data); return CURLE_OK; } -- cgit v1.2.1 From a6d4807d028eb82f4a99587b0a8851727ca88566 Mon Sep 17 00:00:00 2001 From: Mandy Wu Date: Mon, 18 Jul 2011 23:36:36 +0200 Subject: NTLM single-sign on supported With the use of the 'ntlm_auth' tool from the Samba project --- lib/url.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c5b642fde..adb96c4cc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1406,6 +1406,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif +#ifndef USE_NTLM_SSO + auth &= ~CURLAUTH_NTLM_SSO; /* no NTLM single-sign-on without SSL + and ntlm_auth */ +#endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ @@ -1467,6 +1471,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif +#ifndef USE_NTLM_SSO + auth &= ~CURLAUTH_NTLM_SSO; /* no NTLM single-sign-on without SSL + and ntlm_auth */ +#endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ @@ -3002,7 +3010,8 @@ ConnectionExists(struct SessionHandle *data, } if((needle->handler->protocol & CURLPROTO_FTP) || ((needle->handler->protocol & CURLPROTO_HTTP) && - (data->state.authhost.want==CURLAUTH_NTLM))) { + ((data->state.authhost.want==CURLAUTH_NTLM) || + (data->state.authhost.want==CURLAUTH_NTLM_SSO)))) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ if(!strequal(needle->user, check->user) || -- cgit v1.2.1 From ef2176109fca302ed89193716b62c3a7113552a3 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 24 Jul 2011 04:39:43 +0200 Subject: errno.h inclusion conditionally done in setup_once.h --- lib/url.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index adb96c4cc..b28446c3b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -29,7 +29,6 @@ #include #include #include -#include #ifdef WIN32 #include -- cgit v1.2.1 From 0337b871975ab515c513d2c5d596feb9a489494d Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 25 Jul 2011 04:08:08 +0200 Subject: time.h and sys/time.h inclusion conditionally done in setup_once.h --- lib/url.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b28446c3b..f2bd6a0c7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -31,7 +31,6 @@ #include #ifdef WIN32 -#include #include #else #ifdef HAVE_SYS_SOCKET_H @@ -40,9 +39,6 @@ #ifdef HAVE_NETINET_IN_H #include #endif -#ifdef HAVE_SYS_TIME_H -#include -#endif #ifdef HAVE_UNISTD_H #include #endif -- cgit v1.2.1 From 983f3d70f9610a35f279b656a3322087e272f2a6 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 25 Jul 2011 05:30:14 +0200 Subject: WIN32 io.h and fcntl.h inclusion done in setup_once.h --- lib/url.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f2bd6a0c7..39e9bab5d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -30,9 +30,6 @@ #include #include -#ifdef WIN32 -#include -#else #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -68,8 +65,6 @@ #error "We can't compile without socket() support!" #endif -#endif /* WIN32 */ - #ifdef HAVE_LIMITS_H #include #endif -- cgit v1.2.1 From f1586cb4775681810afd8e6626e7842d459f3b85 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 26 Jul 2011 17:23:27 +0200 Subject: stdio.h, stdlib.h, string.h, stdarg.h and ctype.h inclusion done in setup_once.h --- lib/url.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 39e9bab5d..aa1e6f8cb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -20,16 +20,8 @@ * ***************************************************************************/ -/* -- WIN32 approved -- */ - #include "setup.h" -#include -#include -#include -#include -#include - #ifdef HAVE_SYS_SOCKET_H #include #endif -- cgit v1.2.1 From ad8193fbb903331faa16adb42374a397669640fc Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 29 Jul 2011 16:27:15 +0200 Subject: NTLM single-sign on adjustments (VII) Initialize variables when connectdata object is created. --- lib/url.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index aa1e6f8cb..bffa23423 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3515,6 +3515,13 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) conn->ip_version = data->set.ipver; +#ifdef USE_NTLM_SSO + conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; + conn->ntlm_auth_hlpr_pid = 0; + conn->challenge_header = NULL; + conn->response_header = NULL; +#endif + if(data->multi && Curl_multi_canPipeline(data->multi) && !conn->master_buffer) { /* Allocate master_buffer to be used for pipelining */ -- cgit v1.2.1 From 10a0bed48536e5a3fe801a5e0d94bd84ad80c559 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 31 Jul 2011 20:44:41 +0200 Subject: NTLM single-sign on adjustments (VIII) Use preprocessor symbols WINBIND_NTLM_AUTH_ENABLED and WINBIND_NTLM_AUTH_FILE for Samba's winbind daemon ntlm_auth helper code implementation and filename. Retain preprocessor symbol USE_NTLM_SSO for NTLM single-sign-on feature availability implementation independent. For test harness, prefix NTLM_AUTH environment vars with CURL_ Refactor and rename configure option --with-ntlm-auth to --enable-wb-ntlm-auth[=FILE] --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index bffa23423..59da3e991 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3515,7 +3515,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) conn->ip_version = data->set.ipver; -#ifdef USE_NTLM_SSO +#ifdef WINBIND_NTLM_AUTH_ENABLED conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; conn->ntlm_auth_hlpr_pid = 0; conn->challenge_header = NULL; -- cgit v1.2.1 From ebf42c4be76df40ec6d3bf32f229bbb274e2c32f Mon Sep 17 00:00:00 2001 From: Adam Tkac Date: Tue, 19 Jul 2011 19:10:43 +0200 Subject: Add new CURLOPT_GSSAPI_DELEGATION option. Curl_gss_init_sec_context got new parameter - SessionHandle. Signed-off-by: Adam Tkac --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 59da3e991..050be2c1d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1975,6 +1975,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, va_arg(param, char *)); data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]); break; + case CURLOPT_GSSAPI_DELEGATION: + /* + * allow GSSAPI credential delegation + */ + data->set.gssapi_delegation = (bool)(0 != va_arg(param, long)); + break; case CURLOPT_SSL_VERIFYPEER: /* * Enable peer SSL verifying. -- cgit v1.2.1 From a7864c41db6ac12a1b67f2646f837174f75a240b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 25 Jul 2011 11:49:26 +0200 Subject: curl_gssapi: refine the handling of CURLOPT_GSSAPI_DELEGATION Suggested by Richard Silverman. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 050be2c1d..a3a475dfd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1977,9 +1977,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_GSSAPI_DELEGATION: /* - * allow GSSAPI credential delegation + * GSSAPI credential delegation */ - data->set.gssapi_delegation = (bool)(0 != va_arg(param, long)); + data->set.gssapi_delegation = va_arg(param, long); break; case CURLOPT_SSL_VERIFYPEER: /* -- cgit v1.2.1 From 17f343290c9888ab5f108b0e4c8f6510cff47959 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Aug 2011 00:44:40 +0200 Subject: create_conn: mark non-HTTP proxies accordingly A proxy could be marked 'httpproxy' wrongly before if set with an environment variable or with the CURLOPT_PROXY option with a socks*:// prefix or similar. Added test 710 to verify Bug: http://curl.haxx.se/mail/lib-2011-07/0194.html --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a3a475dfd..400ceffde 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3501,6 +3501,8 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) #else /* CURL_DISABLE_PROXY */ + /* note that these two proxy bits are now just on what looks to be + requested, they may be altered down the road */ conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && *data->set.str[STRING_PROXY]); conn->bits.httpproxy = (bool)(conn->bits.proxy && @@ -4825,6 +4827,8 @@ static CURLcode create_conn(struct SessionHandle *data, conn->bits.httpproxy = TRUE; #endif } + else + conn->bits.httpproxy = FALSE; /* not a HTTP proxy */ conn->bits.proxy = TRUE; } else { -- cgit v1.2.1 From 5ed17de326765d4e18b7886b046b0c2f9ab363cb Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Tue, 9 Aug 2011 22:53:48 +0200 Subject: http NTLM: Tidied up http_ntlm prior to splitting the ntlm specific code --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 400ceffde..5f0be160c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2617,7 +2617,9 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) if(has_host_ntlm || has_proxy_ntlm) { data->state.authproblem = FALSE; - Curl_ntlm_cleanup(conn); +#ifdef USE_NTLM + Curl_http_ntlm_cleanup(conn); +#endif } } -- cgit v1.2.1 From c7fb556f26f4ba8e29c6d98eed23478d5ce2efe1 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 9 Aug 2011 22:56:17 +0200 Subject: http NTLM: Further tiding up to libcurl standards --- lib/url.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5f0be160c..f888c1dcb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2617,9 +2617,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) if(has_host_ntlm || has_proxy_ntlm) { data->state.authproblem = FALSE; -#ifdef USE_NTLM Curl_http_ntlm_cleanup(conn); -#endif } } -- cgit v1.2.1 From b998d95b4d6de388ddc59a48714a2a1d9a43dc43 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 18 Aug 2011 23:35:15 +0200 Subject: FTP: fix proxy connect race condition When using the multi interface, a SOCKS proxy, and a connection that wouldn't immediately consider itself connected (which my Linux tests do by default), libcurl would be tricked into doing _two_ connects to the SOCKS proxy when it setup the data connection and then of course the second attempt would fail miserably and cause error. This problem is a regression that was introduced by commit 4a42e5cdaa344755 that was introduced in the 7.21.7 release. Bug: http://curl.haxx.se/mail/lib-2011-08/0199.html Reported by: Fabian Keil --- lib/url.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f888c1dcb..6d0b2aff8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3200,8 +3200,11 @@ static CURLcode ConnectPlease(struct SessionHandle *data, /* All is cool, we store the current information */ conn->ip_addr = addr; - if(*connected) + if(*connected) { result = Curl_connected_proxy(conn); + if(!result) + conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; + } } if(result) @@ -3294,7 +3297,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, *protocol_done = FALSE; - if(conn->bits.tcpconnect && conn->bits.protoconnstart) { + if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { /* We already are connected, get back. This may happen when the connect worked fine in the first call, like when we connect to a local server or proxy. Note that we don't know if the protocol is actually done. @@ -3307,7 +3310,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, return CURLE_OK; } - if(!conn->bits.tcpconnect) { + if(!conn->bits.tcpconnect[FIRSTSOCKET]) { Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ Curl_verboseconnect(conn); @@ -4870,7 +4873,7 @@ static CURLcode create_conn(struct SessionHandle *data, /* Setup a "faked" transfer that'll do nothing */ if(CURLE_OK == result) { conn->data = data; - conn->bits.tcpconnect = TRUE; /* we are "connected */ + conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */ ConnectionStore(data, conn); @@ -5064,10 +5067,10 @@ CURLcode Curl_setup_conn(struct connectdata *conn, if(connected) { result = Curl_protocol_connect(conn, protocol_done); if(CURLE_OK == result) - conn->bits.tcpconnect = TRUE; + conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; } else - conn->bits.tcpconnect = FALSE; + conn->bits.tcpconnect[FIRSTSOCKET] = FALSE; /* if the connection was closed by the server while exchanging authentication informations, retry with the new set @@ -5086,7 +5089,7 @@ CURLcode Curl_setup_conn(struct connectdata *conn, else { Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */ - conn->bits.tcpconnect = TRUE; + conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; *protocol_done = TRUE; Curl_verboseconnect(conn); Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]); -- cgit v1.2.1 From 3af9ba166cfd456c943d2dbf92a1d4b4b893949c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Aug 2011 00:16:01 +0200 Subject: connect: set TIMER_CONNECT When connecting, make sure TIMER_CONNECT is set. --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 6d0b2aff8..ded03ddd8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3202,8 +3202,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data, if(*connected) { result = Curl_connected_proxy(conn); - if(!result) + if(!result) { conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ + } } } -- cgit v1.2.1 From 407e08baad45b060e3fa1387190a8b12aca9ab60 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 26 Aug 2011 18:57:50 +0200 Subject: NTLM single-sign on adjustments (X) Functions renamed: Curl_output_ntlm_sso -> Curl_output_ntlm_wb sso_ntlm_close -> wb_ntlm_close sso_ntlm_response -> wb_ntlm_response sso_ntlm_initiate -> wb_ntlm_initiate Preprocessor symbols renamed: CURLAUTH_NTLM_SSO -> CURLAUTH_NTLM_WB CURL_VERSION_NTLM_SSO -> CURL_VERSION_NTLM_WB --- lib/url.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ded03ddd8..0cd6ac1b2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1389,8 +1389,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef USE_NTLM_SSO - auth &= ~CURLAUTH_NTLM_SSO; /* no NTLM single-sign-on without SSL - and ntlm_auth */ + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM single-sign-on without SSL + and ntlm_auth */ #endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or @@ -1454,8 +1454,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif #ifndef USE_NTLM_SSO - auth &= ~CURLAUTH_NTLM_SSO; /* no NTLM single-sign-on without SSL - and ntlm_auth */ + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM single-sign-on without SSL + and ntlm_auth */ #endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or @@ -2999,7 +2999,7 @@ ConnectionExists(struct SessionHandle *data, if((needle->handler->protocol & CURLPROTO_FTP) || ((needle->handler->protocol & CURLPROTO_HTTP) && ((data->state.authhost.want==CURLAUTH_NTLM) || - (data->state.authhost.want==CURLAUTH_NTLM_SSO)))) { + (data->state.authhost.want==CURLAUTH_NTLM_WB)))) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ if(!strequal(needle->user, check->user) || -- cgit v1.2.1 From b4f6319cf77ca2642154bdac76d6729dde56dd8e Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 27 Aug 2011 01:32:49 +0200 Subject: NTLM single-sign on adjustments (XI) Feature string literal NTLM_SSO renamed to NTLM_WB. Preprocessor symbol USE_NTLM_SSO renamed to WINBIND_NTLM_AUTH_ENABLED. curl's 'long' option 'ntlm-sso' renamed to 'ntlm-wb'. Fix some comments to make clear that this is actually a NTLM delegation. --- lib/url.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 0cd6ac1b2..73f633f0d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1388,9 +1388,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef USE_NTLM_SSO - auth &= ~CURLAUTH_NTLM_WB; /* no NTLM single-sign-on without SSL - and ntlm_auth */ +#ifndef WINBIND_NTLM_AUTH_ENABLED + auth &= ~CURLAUTH_NTLM_WB; #endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or @@ -1453,9 +1452,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef USE_NTLM_SSO - auth &= ~CURLAUTH_NTLM_WB; /* no NTLM single-sign-on without SSL - and ntlm_auth */ +#ifndef WINBIND_NTLM_AUTH_ENABLED + auth &= ~CURLAUTH_NTLM_WB; #endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or -- cgit v1.2.1 From b976d108f1beecff743f912f190ffc89f1ef9098 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 27 Aug 2011 06:31:18 +0200 Subject: NTLM_WB: final congruency naming adjustments Configure script option --enable-wb-ntlm-auth renamed to --enable-ntlm-wb Configure script option --disable-wb-ntlm-auth renamed to --disable-ntlm-wb Preprocessor symbol WINBIND_NTLM_AUTH_ENABLED renamed to NTLM_WB_ENABLED Preprocessor symbol WINBIND_NTLM_AUTH_FILE renamed to NTLM_WB_FILE Test harness env var CURL_NTLM_AUTH renamed to CURL_NTLM_WB_FILE Static function wb_ntlm_close renamed to ntlm_wb_cleanup Static function wb_ntlm_initiate renamed to ntlm_wb_init Static function wb_ntlm_response renamed to ntlm_wb_response --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 73f633f0d..9834e04f8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1388,7 +1388,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef WINBIND_NTLM_AUTH_ENABLED +#ifndef NTLM_WB_ENABLED auth &= ~CURLAUTH_NTLM_WB; #endif #ifndef USE_HTTP_NEGOTIATE @@ -1452,7 +1452,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ #endif -#ifndef WINBIND_NTLM_AUTH_ENABLED +#ifndef NTLM_WB_ENABLED auth &= ~CURLAUTH_NTLM_WB; #endif #ifndef USE_HTTP_NEGOTIATE @@ -3526,7 +3526,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) conn->ip_version = data->set.ipver; -#ifdef WINBIND_NTLM_AUTH_ENABLED +#ifdef NTLM_WB_ENABLED conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; conn->ntlm_auth_hlpr_pid = 0; conn->challenge_header = NULL; -- cgit v1.2.1 From 662c1d87f3933a7deece63d484f4c0c248a13ded Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 28 Aug 2011 02:00:02 +0200 Subject: NTLM: END of refactoring/splitting/moving First: File curl_ntlm.h renamed curl_ntlm_msgs.h File curl_ntlm.c renamed curl_ntlm_msgs.c Afterwards: File http_ntlm.c renamed curl_ntlm.c File http_ntlm.h renamed curl_ntlm.h --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9834e04f8..4d39f2e01 100644 --- a/lib/url.c +++ b/lib/url.c @@ -119,7 +119,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "url.h" #include "connect.h" #include "inet_ntop.h" -#include "http_ntlm.h" +#include "curl_ntlm.h" #include "socks.h" #include "curl_rtmp.h" #include "gopher.h" -- cgit v1.2.1 From 9194e1700312f27c6e2abdfb1f604e130497e887 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 2 Sep 2011 19:40:53 +0200 Subject: MemoryTracking: fix logging of free() calls done where Curl_safefree is called Just internal stuff... Curl_safefree is now a macro defined in memdebug.h instead of a function prototyped in url.h and implemented in url.c, so inclusion of url.h is no longer required in order to simply use Curl_safefree. Provide definition of macro WHILE_FALSE in setup_once.h in order to allow other macros such as DEBUGF and DEBUGASSERT, and code using it, to compile without 'conditional expression is constant' warnings. The WHILE_FALSE stuff fixes 150+ MSVC compiler warnings. --- lib/url.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4d39f2e01..23ca7a5d4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -252,12 +252,6 @@ static const struct Curl_handler Curl_handler_dummy = { PROTOPT_NONE /* flags */ }; -void Curl_safefree(void *ptr) -{ - if(ptr) - free(ptr); -} - static void close_connections(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ -- cgit v1.2.1 From bdc311cf980eaebc0e3dc43801fa4a98b568832d Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 4 Sep 2011 01:56:30 +0200 Subject: NTLM WB: fix file descriptor leak upon OOM condition --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 23ca7a5d4..dcaf76fef 100644 --- a/lib/url.c +++ b/lib/url.c @@ -120,6 +120,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "connect.h" #include "inet_ntop.h" #include "curl_ntlm.h" +#include "curl_ntlm_wb.h" #include "socks.h" #include "curl_rtmp.h" #include "gopher.h" @@ -2531,6 +2532,10 @@ static void conn_free(struct connectdata *conn) if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) Curl_closesocket(conn, conn->sock[FIRSTSOCKET]); +#ifdef NTLM_WB_ENABLED + Curl_ntlm_wb_cleanup(conn); +#endif + Curl_safefree(conn->user); Curl_safefree(conn->passwd); Curl_safefree(conn->proxyuser); -- cgit v1.2.1 From a50210710ab6fd772e2762ed36602c15adfb49e1 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 5 Sep 2011 20:46:09 +0200 Subject: fix bool variables checking and assignment --- lib/url.c | 107 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 53 insertions(+), 54 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index dcaf76fef..19f591200 100644 --- a/lib/url.c +++ b/lib/url.c @@ -821,7 +821,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, { /* remember we want this enabled */ long use_cache = va_arg(param, long); - data->set.global_dns_cache = (bool)(0 != use_cache); + data->set.global_dns_cache = (0 != use_cache)?TRUE:FALSE; } break; case CURLOPT_SSL_CIPHER_LIST: @@ -857,33 +857,33 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * When this transfer is done, it must not be left to be reused by a * subsequent transfer but shall be closed immediately. */ - data->set.reuse_forbid = (bool)(0 != va_arg(param, long)); + data->set.reuse_forbid = (0 != 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->set.reuse_fresh = (bool)(0 != va_arg(param, long)); + data->set.reuse_fresh = (0 != 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->set.verbose = (bool)(0 != va_arg(param, long)); + data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_HEADER: /* * Set to include the header in the general data output stream. */ - data->set.include_header = (bool)(0 != va_arg(param, long)); + data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_NOPROGRESS: /* * Shut off the internal supported progress meter */ - data->set.hide_progress = (bool)(0 != va_arg(param, long)); + data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE; if(data->set.hide_progress) data->progress.flags |= PGRS_HIDE; else @@ -893,14 +893,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Do not include the body part in the output data stream. */ - data->set.opt_no_body = (bool)(0 != va_arg(param, long)); + data->set.opt_no_body = (0 != 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->set.http_fail_on_error = (bool)(0 != va_arg(param, long)); + data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_UPLOAD: case CURLOPT_PUT: @@ -908,7 +908,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * We want to sent data to the remote host. If this is HTTP, that equals * using the PUT request. */ - data->set.upload = (bool)(0 != va_arg(param, long)); + data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE; if(data->set.upload) { /* If this is HTTP, PUT is what's needed to "upload" */ data->set.httpreq = HTTPREQ_PUT; @@ -924,7 +924,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Try to get the file time of the remote document. The time will * later (possibly) become available using curl_easy_getinfo(). */ - data->set.get_filetime = (bool)(0 != va_arg(param, long)); + data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FTP_CREATE_MISSING_DIRS: /* @@ -965,13 +965,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * An option that changes the command to one that asks for a list * only, no file info details. */ - data->set.ftp_list_only = (bool)(0 != va_arg(param, long)); + data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_APPEND: /* * We want to upload and append to an existing file. */ - data->set.ftp_append = (bool)(0 != va_arg(param, long)); + data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FTP_FILEMETHOD: /* @@ -999,7 +999,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * * Transfer using ASCII (instead of BINARY). */ - data->set.prefer_ascii = (bool)(0 != va_arg(param, long)); + data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_TIMECONDITION: /* @@ -1028,7 +1028,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Switch on automatic referer that gets set if curl follows locations. */ - data->set.http_auto_referer = (bool)(0 != va_arg(param, long)); + data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_ACCEPT_ENCODING: @@ -1048,14 +1048,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_TRANSFER_ENCODING: - data->set.http_transfer_encoding = (bool)(0 != va_arg(param, long)); + data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FOLLOWLOCATION: /* * Follow Location: header hints on a HTTP-server. */ - data->set.http_follow_location = (bool)(0 != va_arg(param, long)); + data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_UNRESTRICTED_AUTH: @@ -1064,7 +1064,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * hostname changed. */ data->set.http_disable_hostname_check_before_authentication = - (bool)(0 != va_arg(param, long)); + (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_MAXREDIRS: @@ -1086,8 +1086,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * other - POST is kept as POST after 301 and 302 */ long postRedir = va_arg(param, long); - data->set.post301 = (bool)((postRedir & CURL_REDIR_POST_301)?TRUE:FALSE); - data->set.post302 = (bool)((postRedir & CURL_REDIR_POST_302)?TRUE:FALSE); + data->set.post301 = (postRedir & CURL_REDIR_POST_301)?TRUE:FALSE; + data->set.post302 = (postRedir & CURL_REDIR_POST_302)?TRUE:FALSE; } break; @@ -1296,7 +1296,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * We run mostly with the original cookie spec, as hardly anyone implements * anything else. */ - data->set.cookiesession = (bool)(0 != va_arg(param, long)); + data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_COOKIELIST: @@ -1371,8 +1371,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authhost.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)? - TRUE:FALSE); + data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -1417,7 +1416,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Tunnel operations through the proxy instead of normal proxy use */ - data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long)); + data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_PROXYPORT: @@ -1436,8 +1435,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authproxy.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)? - TRUE:FALSE); + data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -1514,7 +1512,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * set flag for nec socks5 support */ - data->set.socks5_gssapi_nec = (bool)(0 != va_arg(param, long)); + data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE; break; #endif @@ -1543,19 +1541,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ result = setstropt(&data->set.str[STRING_FTPPORT], va_arg(param, char *)); - data->set.ftp_use_port = (bool)(NULL != data->set.str[STRING_FTPPORT]); + data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ? + TRUE:FALSE; break; case CURLOPT_FTP_USE_EPRT: - data->set.ftp_use_eprt = (bool)(0 != va_arg(param, long)); + data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FTP_USE_EPSV: - data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long)); + data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FTP_USE_PRET: - data->set.ftp_use_pret = (bool)(0 != va_arg(param, long)); + data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FTP_SSL_CCC: @@ -1567,7 +1566,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the * bypass of the IP address in PASV responses. */ - data->set.ftp_skip_ip = (bool)(0 != va_arg(param, long)); + data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_INFILE: @@ -1937,7 +1936,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Kludgy option to enable CRLF conversions. Subject for removal. */ - data->set.crlf = (bool)(0 != va_arg(param, long)); + data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_INTERFACE: @@ -1966,7 +1965,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ result = setstropt(&data->set.str[STRING_KRB_LEVEL], va_arg(param, char *)); - data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]); + data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE; break; case CURLOPT_GSSAPI_DELEGATION: /* @@ -2004,7 +2003,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ssl.fsslctxp = va_arg(param, void *); break; case CURLOPT_CERTINFO: - data->set.ssl.certinfo = (bool)(0 != va_arg(param, long)); + data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE; break; #endif case CURLOPT_CAINFO: @@ -2064,7 +2063,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * The application asks not to set any signal() or alarm() handlers, * even when using a timeout. */ - data->set.no_signal = (bool)(0 != va_arg(param, long)); + data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_SHARE: @@ -2168,7 +2167,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Enable or disable TCP_NODELAY, which will disable/enable the Nagle * algorithm */ - data->set.tcp_nodelay = (bool)(0 != va_arg(param, long)); + data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FTP_ACCOUNT: @@ -2177,14 +2176,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_IGNORE_CONTENT_LENGTH: - data->set.ignorecl = (bool)(0 != va_arg(param, long)); + data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_CONNECT_ONLY: /* * No data transfer, set up connection and let application use the socket */ - data->set.connect_only = (bool)(0 != va_arg(param, long)); + data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_FTP_ALTERNATIVE_TO_USER: @@ -2237,7 +2236,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_SSL_SESSIONID_CACHE: - data->set.ssl.sessionid = (bool)(0 != va_arg(param, long)); + data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE; break; #ifdef USE_LIBSSH2 @@ -2298,14 +2297,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * disable libcurl transfer encoding is used */ - data->set.http_te_skip = (bool)(0 == va_arg(param, long)); + data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_HTTP_CONTENT_DECODING: /* * raw data passed to the application when content encoding is used */ - data->set.http_ce_skip = (bool)(0 == va_arg(param, long)); + data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_NEW_FILE_PERMS: @@ -2467,7 +2466,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_WILDCARDMATCH: - data->set.wildcardmatch = (bool)(0 != va_arg(param, long)); + data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_CHUNK_BGN_FUNCTION: data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); @@ -2766,11 +2765,11 @@ static struct SessionHandle* gethandleathead(struct curl_llist *pipeline) void Curl_getoff_all_pipelines(struct SessionHandle *data, struct connectdata *conn) { - bool recv_head = (bool)(conn->readchannel_inuse && - (gethandleathead(conn->recv_pipe) == data)); + bool recv_head = (conn->readchannel_inuse && + (gethandleathead(conn->recv_pipe) == data)) ? TRUE : FALSE; - bool send_head = (bool)(conn->writechannel_inuse && - (gethandleathead(conn->send_pipe) == data)); + bool send_head = (conn->writechannel_inuse && + (gethandleathead(conn->send_pipe) == data)) ? TRUE : FALSE; if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head) conn->readchannel_inuse = FALSE; @@ -3505,18 +3504,18 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) /* note that these two proxy bits are now just on what looks to be requested, they may be altered down the road */ - conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && - *data->set.str[STRING_PROXY]); - conn->bits.httpproxy = (bool)(conn->bits.proxy && - (conn->proxytype == CURLPROXY_HTTP || - conn->proxytype == CURLPROXY_HTTP_1_0)); + conn->bits.proxy = (data->set.str[STRING_PROXY] && + *data->set.str[STRING_PROXY])?TRUE:FALSE; + conn->bits.httpproxy = (conn->bits.proxy && + (conn->proxytype == CURLPROXY_HTTP || + conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE; conn->bits.proxy_user_passwd = - (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); + (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE; conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; #endif /* CURL_DISABLE_PROXY */ - conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); + conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; @@ -3860,7 +3859,7 @@ static CURLcode setup_range(struct SessionHandle *data) else s->range = strdup(data->set.str[STRING_SET_RANGE]); - s->rangestringalloc = (bool)(s->range?TRUE:FALSE); + s->rangestringalloc = (s->range)?TRUE:FALSE; if(!s->range) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 01c172f5e8c78b781397003e22fc462a503d2c24 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 22 Sep 2011 00:24:02 +0200 Subject: NTLM_WB: fix disabling of NTLM_WB when NTLM is disabled --- lib/url.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 19f591200..086091485 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1380,10 +1380,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* switch off bits we can't support */ #ifndef USE_NTLM - auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ -#endif -#ifndef NTLM_WB_ENABLED - auth &= ~CURLAUTH_NTLM_WB; + auth &= ~CURLAUTH_NTLM; /* no NTLM support */ + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ +#elif !defined(NTLM_WB_ENABLED) + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ #endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or @@ -1443,10 +1443,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } /* switch off bits we can't support */ #ifndef USE_NTLM - auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ -#endif -#ifndef NTLM_WB_ENABLED - auth &= ~CURLAUTH_NTLM_WB; + auth &= ~CURLAUTH_NTLM; /* no NTLM support */ + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ +#elif !defined(NTLM_WB_ENABLED) + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ #endif #ifndef USE_HTTP_NEGOTIATE auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or @@ -2531,7 +2531,7 @@ static void conn_free(struct connectdata *conn) if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) Curl_closesocket(conn, conn->sock[FIRSTSOCKET]); -#ifdef NTLM_WB_ENABLED +#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED) Curl_ntlm_wb_cleanup(conn); #endif @@ -3524,7 +3524,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) conn->ip_version = data->set.ipver; -#ifdef NTLM_WB_ENABLED +#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED) conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; conn->ntlm_auth_hlpr_pid = 0; conn->challenge_header = NULL; -- cgit v1.2.1 From 5793bc370c794a10e6ed014cb535a47672842ae6 Mon Sep 17 00:00:00 2001 From: Alejandro Alvarez Date: Tue, 20 Sep 2011 17:43:54 +0200 Subject: SSL session sharing support added With locking, plus test, plus documentation --- lib/url.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 086091485..c9135a6b3 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2083,6 +2083,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(data->share->cookies == data->cookies) data->cookies = NULL; + if(data->share->sslsession == data->state.session) { + data->state.session = NULL; + data->set.ssl.numsessions = 0; + } + data->share->dirty--; Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); @@ -2114,6 +2119,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->cookies = data->share->cookies; } #endif /* CURL_DISABLE_HTTP */ + if(data->share->sslsession) { + data->set.ssl.numsessions = data->share->nsslsession; + data->state.session = data->share->sslsession; + } Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } -- cgit v1.2.1 From 9dd85bced56f6951107f69e581c872c1e7e3e58e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 2 Oct 2011 19:28:39 +0200 Subject: multi: progress function abort must close connection When the progress function returns to cancel the request, we must mark the connection to get closed and it must do to the DONE state. do_init() must be called as early as possible so that state variables for new connections are reset early. We could otherwise see that the old values were still there when a connection was to be disconnected very early and it would make it behave wrongly. Bug: http://curl.haxx.se/mail/lib-2011-10/0006.html Reported by: Vladimir Grishchenko --- lib/url.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c9135a6b3..abb5a9ccc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -136,6 +136,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); static long ConnectionKillOne(struct SessionHandle *data); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); +static CURLcode do_init(struct connectdata *conn); /* * Protocol table. @@ -4988,6 +4989,9 @@ static CURLcode create_conn(struct SessionHandle *data, ConnectionStore(data, conn); } + /* Setup and init stuff before DO starts, in preparing for the transfer. */ + do_init(conn); + /* * Setup whatever necessary for a resumed transfer */ @@ -5334,9 +5338,6 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) struct connectdata *conn = *connp; struct SessionHandle *data = conn->data; - /* setup and init stuff before DO starts, in preparing for the transfer */ - do_init(conn); - if(conn->handler->do_it) { /* generic protocol-specific function pointer set in curl_connect() */ result = conn->handler->do_it(conn, done); -- cgit v1.2.1 From 17f48fe87979f159e2d8769d678641c60f4c0eed Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 7 Oct 2011 20:50:57 +0200 Subject: libcurl: some OOM handling fixes --- lib/url.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index abb5a9ccc..7813b8285 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2569,6 +2569,11 @@ static void conn_free(struct connectdata *conn) Curl_llist_destroy(conn->pend_pipe, NULL); Curl_llist_destroy(conn->done_pipe, NULL); + conn->send_pipe = NULL; + conn->recv_pipe = NULL; + conn->pend_pipe = NULL; + conn->done_pipe = NULL; + Curl_safefree(conn->localdev); Curl_free_ssl_config(&conn->ssl_config); @@ -3583,6 +3588,12 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) Curl_llist_destroy(conn->recv_pipe, NULL); Curl_llist_destroy(conn->pend_pipe, NULL); Curl_llist_destroy(conn->done_pipe, NULL); + + conn->send_pipe = NULL; + conn->recv_pipe = NULL; + conn->pend_pipe = NULL; + conn->done_pipe = NULL; + Curl_safefree(conn->master_buffer); Curl_safefree(conn->localdev); Curl_safefree(conn); @@ -4650,10 +4661,17 @@ static void reuse_conn(struct connectdata *old_conn, Curl_safefree(old_conn->passwd); Curl_safefree(old_conn->proxyuser); Curl_safefree(old_conn->proxypasswd); + Curl_llist_destroy(old_conn->send_pipe, NULL); Curl_llist_destroy(old_conn->recv_pipe, NULL); Curl_llist_destroy(old_conn->pend_pipe, NULL); Curl_llist_destroy(old_conn->done_pipe, NULL); + + old_conn->send_pipe = NULL; + old_conn->recv_pipe = NULL; + old_conn->pend_pipe = NULL; + old_conn->done_pipe = NULL; + Curl_safefree(old_conn->master_buffer); } -- cgit v1.2.1 From 584dc8b8af862f7f47a3a9f02f874ac0bd0076be Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 11 Oct 2011 19:41:30 +0200 Subject: OOM handling/cleanup slight adjustments --- lib/url.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7813b8285..7eb59f5bb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -458,6 +458,7 @@ CURLcode Curl_close(struct SessionHandle *data) /* free the connection cache if allocated privately */ Curl_rm_connc(data->state.connc); + data->state.connc = NULL; } } @@ -618,13 +619,19 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, curl_multi_cleanup(). */ void Curl_rm_connc(struct conncache *c) { + if(!c) + return; + if(c->connects) { long i; - for(i = 0; i < c->num; ++i) + for(i = 0; i < c->num; ++i) { conn_free(c->connects[i]); - + c->connects[i] = NULL; + } free(c->connects); + c->connects = NULL; } + c->num = 0; free(c); } @@ -1258,10 +1265,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* append the cookie file name to the list of file names, and deal with them later */ cl = curl_slist_append(data->change.cookielist, argptr); - - if(!cl) + if(!cl) { + curl_slist_free_all(data->change.cookielist); + data->change.cookielist = NULL; return CURLE_OUT_OF_MEMORY; - + } data->change.cookielist = cl; /* store the list for later use */ } break; -- cgit v1.2.1 From bff78cc18e8dc22926d4b0219e6fac08758ed790 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 12 Oct 2011 21:32:10 +0200 Subject: OOM handling/cleanup slight adjustments --- lib/url.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 7eb59f5bb..5b00ca750 100644 --- a/lib/url.c +++ b/lib/url.c @@ -276,10 +276,7 @@ static CURLcode setstropt(char **charp, char * s) /* Release the previous storage at `charp' and replace by a dynamic storage copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ - if(*charp) { - free(*charp); - *charp = (char *) NULL; - } + Curl_safefree(*charp); if(s) { s = strdup(s); @@ -480,6 +477,8 @@ CURLcode Curl_close(struct SessionHandle *data) /* Free the pathbuffer */ Curl_safefree(data->state.pathbuffer); + data->state.path = NULL; + Curl_safefree(data->state.proto.generic); /* Close down all open SSL info and sessions */ @@ -488,11 +487,17 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.scratch); Curl_ssl_free_certinfo(data); - if(data->change.referer_alloc) - free(data->change.referer); + if(data->change.referer_alloc) { + Curl_safefree(data->change.referer); + data->change.referer_alloc = FALSE; + } + data->change.referer = NULL; - if(data->change.url_alloc) - free(data->change.url); + if(data->change.url_alloc) { + Curl_safefree(data->change.url); + data->change.url_alloc = FALSE; + } + data->change.url = NULL; Curl_safefree(data->state.headerbuff); @@ -1216,7 +1221,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * String to set in the HTTP Referer: field. */ if(data->change.referer_alloc) { - free(data->change.referer); + Curl_safefree(data->change.referer); data->change.referer_alloc = FALSE; } result = setstropt(&data->set.str[STRING_SET_REFERER], @@ -1633,8 +1638,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ if(data->change.url_alloc) { /* the already set URL is allocated, free it first! */ - free(data->change.url); - data->change.url_alloc=FALSE; + Curl_safefree(data->change.url); + data->change.url_alloc = FALSE; } result = setstropt(&data->set.str[STRING_SET_URL], va_arg(param, char *)); @@ -4428,8 +4433,10 @@ static CURLcode parse_remote_port(struct SessionHandle *data, if(!url) return CURLE_OUT_OF_MEMORY; - if(data->change.url_alloc) - free(data->change.url); + if(data->change.url_alloc) { + Curl_safefree(data->change.url); + data->change.url_alloc = FALSE; + } data->change.url = url; data->change.url_alloc = TRUE; @@ -4653,11 +4660,11 @@ static void reuse_conn(struct connectdata *old_conn, /* host can change, when doing keepalive with a proxy ! */ if(conn->bits.proxy) { - free(conn->host.rawalloc); + Curl_safefree(conn->host.rawalloc); conn->host=old_conn->host; } else - free(old_conn->host.rawalloc); /* free the newly allocated name buffer */ + Curl_safefree(old_conn->host.rawalloc); /* free the newly allocated name buffer */ /* persist connection info in session handle */ Curl_persistconninfo(conn); @@ -4756,14 +4763,19 @@ static CURLcode create_conn(struct SessionHandle *data, */ Curl_safefree(data->state.pathbuffer); + data->state.path = NULL; + data->state.pathbuffer = malloc(urllen+2); if(NULL == data->state.pathbuffer) return CURLE_OUT_OF_MEMORY; /* really bad error */ data->state.path = data->state.pathbuffer; conn->host.rawalloc = malloc(urllen+2); - if(NULL == conn->host.rawalloc) + if(NULL == conn->host.rawalloc) { + Curl_safefree(data->state.pathbuffer); + data->state.path = NULL; return CURLE_OUT_OF_MEMORY; + } conn->host.name = conn->host.rawalloc; conn->host.name[0] = 0; @@ -4788,6 +4800,11 @@ static CURLcode create_conn(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; } + if(data->change.url_alloc) { + Curl_safefree(data->change.url); + data->change.url_alloc = FALSE; + } + data->change.url = reurl; data->change.url_alloc = TRUE; /* free this later */ } -- cgit v1.2.1 From 880cf0bedc7bae7a937bae7fc54bb7b7d8048d3a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 13 Oct 2011 01:52:56 +0200 Subject: url.c: make line shorter than 80 chars --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5b00ca750..e9451b67f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4664,7 +4664,8 @@ static void reuse_conn(struct connectdata *old_conn, conn->host=old_conn->host; } else - Curl_safefree(old_conn->host.rawalloc); /* free the newly allocated name buffer */ + /* free the newly allocated name buffer */ + Curl_safefree(old_conn->host.rawalloc); /* persist connection info in session handle */ Curl_persistconninfo(conn); -- cgit v1.2.1 From 1bab38780b55cc4bd39267f54aacb49ddeb00eb2 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 14 Oct 2011 17:34:42 +0200 Subject: url.c: fix endless loop upon transport connection timeout Jerry Wu detected and provided detailed info about this issue. --- lib/url.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index e9451b67f..8ccef459a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5073,7 +5073,7 @@ static CURLcode create_conn(struct SessionHandle *data, CURLcode Curl_setup_conn(struct connectdata *conn, bool *protocol_done) { - CURLcode result=CURLE_OK; + CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; Curl_pgrsTime(data, TIMER_NAMELOOKUP); @@ -5119,6 +5119,12 @@ CURLcode Curl_setup_conn(struct connectdata *conn, result = ConnectPlease(data, conn, &connected); + if(result && !conn->ip_addr) { + /* transport connection failure not related with authentication */ + conn->bits.tcpconnect[FIRSTSOCKET] = FALSE; + return result; + } + if(connected) { result = Curl_protocol_connect(conn, protocol_done); if(CURLE_OK == result) -- cgit v1.2.1 From 90fcad63cbb9943c7c7a564944a3bce7d10e581a Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 20 Oct 2011 17:54:18 -0700 Subject: Fixed compilation when HTTP or cookies are disabled --- lib/url.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8ccef459a..c3beaaa6f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2094,8 +2094,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->dns.hostcachetype = HCACHE_NONE; } +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(data->share->cookies == data->cookies) data->cookies = NULL; +#endif if(data->share->sslsession == data->state.session) { data->state.session = NULL; -- cgit v1.2.1 From d7934b8bd49114cbb54f7401742f7fb088e2f796 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 21 Oct 2011 23:36:54 +0200 Subject: curl_multi_fdset: correct fdset with FTP PORT use After a PORT has been issued, and the multi handle would switch to the CURLM_STATE_DO_MORE state (which is unique for FTP), libcurl would return the wrong fdset to wait for when curl_multi_fdset() is called. The code would blindly assume that it was waiting for a connect of the second connection, while that isn't true immediately after the PORT command. Also, the function multi.c:domore_getsock() was highly FTP-centric and therefore ugly to keep in protocol-agnostic code. I solved this problem by introducing a new function pointer in the Curl_handler struct called domore_getsock() which is only called during the DOMORE state for protocols that set that pointer. The new ftp.c:ftp_domore_getsock() function now returns fdset info about the control connection's command/response handling while such a state is in use, and goes over to waiting for a writable second connection first once the commands are done. The original problem could be seen by running test 525 and checking the time stamps in the FTP server log. I can verify that this fix at least fixes this problem. Bug: http://curl.haxx.se/mail/lib-2011-10/0250.html Reported by: Gokhan Sengun --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c3beaaa6f..40dcd1568 100644 --- a/lib/url.c +++ b/lib/url.c @@ -246,6 +246,7 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* doing */ ZERO_NULL, /* proto_getsock */ ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ -- cgit v1.2.1 From 6bdeca967d0c449fe379c56dda75b0d236f39780 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 2 Nov 2011 22:34:41 +0100 Subject: url.c and transfer.c: nullify connection pointer when free()'ed --- lib/url.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 40dcd1568..8118fe5c5 100644 --- a/lib/url.c +++ b/lib/url.c @@ -593,8 +593,10 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, NOTE: for conncache_multi cases we must make sure that we only close handles not in use. */ - for(i=newamount; i< c->num; i++) + for(i=newamount; i< c->num; i++) { Curl_disconnect(c->connects[i], /* dead_connection */ FALSE); + c->connects[i] = NULL; + } /* If the most recent connection is no longer valid, mark it invalid. */ -- cgit v1.2.1 From 93e57d0628aad62330dc62ff809752a0478824c4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Nov 2011 09:54:12 +0100 Subject: rename ftp_ssl: the struct field is used for many protocols Now called 'use_ssl' instead, which better matches the current CURLOPT name and since the option is used for all pingpong protocols (at least) it makes sense to not use 'ftp' in the name. --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8118fe5c5..9c7966fc0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2169,7 +2169,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Make transfers attempt to use SSL/TLS. */ - data->set.ftp_ssl = (curl_usessl)va_arg(param, long); + data->set.use_ssl = (curl_usessl)va_arg(param, long); break; #endif case CURLOPT_FTPSSLAUTH: -- cgit v1.2.1 From 6fa6567b92621de2d5f5958fa6f29b00384b9174 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 3 Nov 2011 21:56:51 +0100 Subject: url.c and file.c: fix OOM triggered segfault --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9c7966fc0..4bc82a65f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2606,7 +2606,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) data = conn->data; if(!data) { - DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n")); + DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n")); return CURLE_OK; } -- cgit v1.2.1 From 8d0a504f0d34c2471393ef23fb2345c73c5d4746 Mon Sep 17 00:00:00 2001 From: Jason Glasgow Date: Tue, 12 Apr 2011 11:34:28 -0400 Subject: CURLOPT_DNS_SERVERS: set name servers if possible --- lib/url.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 4bc82a65f..f478e3828 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2531,6 +2531,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ssl.authtype = CURL_TLSAUTH_NONE; break; #endif + case CURLOPT_DNS_SERVERS: + result = Curl_set_dns_servers(data, va_arg(param, char *)); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; -- cgit v1.2.1 From 7248439fece7d0f32cc3d52c253b3960a66ad2b3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 21 Nov 2011 23:36:21 +0100 Subject: protocol_connect: show verbose connect and set connect time Regression: commit b998d95b (shipped first in release 7.22.0) made the condition always equal false that should reset the TIMER_CONNECT timer and call the Curl_verboseconnect() function. Reported by: "Captain Basil" Bug: http://curl.haxx.se/mail/archive-2011-11/0035.html --- lib/url.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index f478e3828..517dc18da 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3345,11 +3345,8 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, return CURLE_OK; } - if(!conn->bits.tcpconnect[FIRSTSOCKET]) { - - Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ - Curl_verboseconnect(conn); - } + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ + Curl_verboseconnect(conn); if(!conn->bits.protoconnstart) { if(conn->handler->connect_it) { -- cgit v1.2.1 From 2c905fd1f8200349667dc990a17daf37214700bf Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 24 Nov 2011 23:28:54 +0100 Subject: query-part: ignore the URI part for given protocols By setting PROTOPT_NOURLQUERY in the protocol handler struct, the protocol will get the "query part" of the URL cut off before the data is handled by the protocol-specific code. This makes libcurl adhere to RFC3986 section 2.2. Test 1220 is added to verify a file:// URL with query-part. --- lib/url.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 517dc18da..2c5cb39b8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4824,6 +4824,25 @@ static CURLcode create_conn(struct SessionHandle *data, if(result != CURLE_OK) return result; + + /************************************************************* + * If the protocol can't handle url query strings, then cut + * of the unhandable part + *************************************************************/ + if((conn->given->flags&PROTOPT_NOURLQUERY)) { + char *path_q_sep = strchr(conn->data->state.path, '?'); + if(path_q_sep) { + /* according to rfc3986, allow the query (?foo=bar) + also on protocols that can't handle it. + + cut the string-part after '?' + */ + + /* terminate the string */ + path_q_sep[0] = 0; + } + } + #ifndef CURL_DISABLE_PROXY /************************************************************* * Extract the user and password from the authentication string -- cgit v1.2.1 From 07e3b7512c9a2723daac046501c7ea40ede4bd28 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 9 Dec 2011 22:51:08 +0100 Subject: create_conn: don't switch to HTTP protocol if tunneling is enabled This is a regression since who knows when. When spotting that a HTTP proxy is used we must not uncondititionally enable the HTTP protocol since if we do tunneling through the proxy we're still using the target protocol. Reported by: Naveen Chandran --- lib/url.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 2c5cb39b8..42e1756f9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4900,8 +4900,9 @@ static CURLcode create_conn(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; #else /* force this connection's protocol to become HTTP if not already - compatible */ - if(!(conn->handler->protocol & CURLPROTO_HTTP)) + compatible - if it isn't tunneling through */ + if(!(conn->handler->protocol & CURLPROTO_HTTP) && + !conn->bits.tunnel_proxy) conn->handler = &Curl_handler_http; conn->bits.httpproxy = TRUE; -- cgit v1.2.1 From 1259ccf747498b7cc2c29a202645ed240fee167e Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sun, 11 Dec 2011 16:03:08 +0000 Subject: ConnectionExists: Fix reuse for TLS upgraded connections Fixed the connection reuse detection in ConnectionExists() when comparing a new connection that is non-SSL based against that of a SSL based connection that has become so by being upgraded via TLS. --- lib/url.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 42e1756f9..b0ec7c41f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2961,7 +2961,9 @@ ConnectionExists(struct SessionHandle *data, if((needle->handler->flags&PROTOPT_SSL) != (check->handler->flags&PROTOPT_SSL)) /* don't do mixed SSL and non-SSL connections */ - continue; + if(!(needle->handler->protocol & check->handler->protocol)) + /* except protocols that have been upgraded via TLS */ + continue; if(needle->handler->flags&PROTOPT_SSL) { if((data->set.ssl.verifypeer != check->verifypeer) || @@ -3005,14 +3007,16 @@ ConnectionExists(struct SessionHandle *data, (needle->port == check->port))) { /* The requested connection does not use a HTTP proxy or it uses SSL or it is a non-SSL protocol tunneled over the same http proxy name and - port number */ + port number or it is a non-SSL protocol which is allowed to be + upgraded via TLS */ - if(Curl_raw_equal(needle->handler->scheme, check->handler->scheme) && + if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) || + needle->handler->protocol & check->handler->protocol) && Curl_raw_equal(needle->host.name, check->host.name) && - (needle->remote_port == check->remote_port) ) { + needle->remote_port == check->remote_port) { if(needle->handler->flags & PROTOPT_SSL) { - /* This is SSL, verify that we're using the same - ssl options as well */ + /* This is a SSL connection so verify that we're using the same + SSL options as well */ if(!Curl_ssl_config_matches(&needle->ssl_config, &check->ssl_config)) { DEBUGF(infof(data, @@ -3023,7 +3027,7 @@ ConnectionExists(struct SessionHandle *data, } else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) { DEBUGF(infof(data, - "Connection #%ld has not started ssl connect, " + "Connection #%ld has not started SSL connect, " "can't reuse\n", check->connectindex)); continue; -- cgit v1.2.1 From ce896875f89f66d8d1659d57e6d6f80c157c1071 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Dec 2011 14:59:46 +0100 Subject: timer: restore PRETRANSFER timing Regression introduced in 7.23.0 with commit 9dd85bce. The function in which the PRETRANSFER time stamp was recorded was moved in time causing it be stored very quickly after the start timestamp. On most systems shorter than 1 millisecond and thus it wouldn't even show with -w "%{time_pretransfer}" using the command line tool. Bug: http://curl.haxx.se/mail/archive-2011-12/0022.html Reported by: Toni Moreno --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b0ec7c41f..a4aadb28d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5390,7 +5390,6 @@ static CURLcode do_init(struct connectdata *conn) k->hbufp = data->state.headerbuff; k->ignorebody=FALSE; - Curl_pgrsTime(data, TIMER_PRETRANSFER); Curl_speedinit(data); Curl_pgrsSetUploadCounter(data, 0); @@ -5410,6 +5409,7 @@ static void do_complete(struct connectdata *conn) conn->data->req.chunk=FALSE; conn->data->req.maxfd = (conn->sockfd>conn->writesockfd? conn->sockfd:conn->writesockfd)+1; + Curl_pgrsTime(conn->data, TIMER_PRETRANSFER); } CURLcode Curl_do(struct connectdata **connp, bool *done) -- cgit v1.2.1 From c834213ad52c52431e9ca597862dc81839cabe84 Mon Sep 17 00:00:00 2001 From: Gokhan Sengun Date: Mon, 19 Dec 2011 14:35:20 +0100 Subject: FTP: perform active connections non-blocking 1- Two new error codes are introduced. CURLE_FTP_ACCEPT_FAILED to be set whenever ACCEPTing fails because of FTP server connected. CURLE_FTP_ACCEPT_TIMEOUT to be set whenever ACCEPTing timeouts. Neither of these errors are considered fatal and control connection remains OK because it could just be a firewall blocking server to connect to the client. 2- One new setopt option was introduced. CURLOPT_ACCEPTTIMEOUT_MS It sets the maximum amount of time FTP client is going to wait for a server to connect. Internal default accept timeout is 60 seconds. --- lib/url.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a4aadb28d..b952e920a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1677,6 +1677,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.connecttimeout = va_arg(param, long); break; + case CURLOPT_ACCEPTTIMEOUT_MS: + /* + * The maximum time you allow curl to wait for server connect + */ + data->set.accepttimeout = va_arg(param, long); + break; + case CURLOPT_USERPWD: /* * user:password to use in the operation @@ -5457,7 +5464,7 @@ CURLcode Curl_do_more(struct connectdata *conn) if(conn->handler->do_more) result = conn->handler->do_more(conn); - if(result == CURLE_OK) + if(result == CURLE_OK && conn->bits.wait_data_conn == FALSE) /* do_complete must be called after the protocol-specific DO function */ do_complete(conn); -- cgit v1.2.1 From dfdac61522c7d660f884ec7a663dedb2d69d16a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 Dec 2011 12:52:24 +0100 Subject: non-blocking active FTP: cleanup multi state usage Backpedaled out the funny double-change of state in the multi state machine by adding a new argument to the do_more() function to signal completion. This way it can remain in the DO_MORE state properly until done. Long term, the entire DO_MORE logic should be moved into the FTP code and be hidden from the multi code as the logic is only used for FTP. --- lib/url.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b952e920a..9896dd8c0 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5457,14 +5457,25 @@ CURLcode Curl_do(struct connectdata **connp, bool *done) return result; } -CURLcode Curl_do_more(struct connectdata *conn) +/* + * Curl_do_more() is called during the DO_MORE multi state. It is basically a + * second stage DO state which (wrongly) was introduced to support FTP's + * second connection. + * + * TODO: A future libcurl should be able to work away this state. + * + */ + +CURLcode Curl_do_more(struct connectdata *conn, bool *completed) { CURLcode result=CURLE_OK; + *completed = FALSE; + if(conn->handler->do_more) - result = conn->handler->do_more(conn); + result = conn->handler->do_more(conn, completed); - if(result == CURLE_OK && conn->bits.wait_data_conn == FALSE) + if(!result && completed) /* do_complete must be called after the protocol-specific DO function */ do_complete(conn); -- cgit v1.2.1 From 2caa454dc19237588ee3696fac2d74fb86eb0d98 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 23 Dec 2011 14:30:43 +0100 Subject: resolve: don't leak pre-populated dns entries CURLOPT_RESOLVE populates the DNS cache with entries that are marked as eternally in use. Those entries need to be taken care of when the cache is killed off. Bug: http://curl.haxx.se/bug/view.cgi?id=3463121 Reported by: "tw84452852" --- lib/url.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9896dd8c0..75b298706 100644 --- a/lib/url.c +++ b/lib/url.c @@ -467,11 +467,8 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } - if(data->dns.hostcachetype == HCACHE_PRIVATE) { - Curl_hash_destroy(data->dns.hostcache); - data->dns.hostcachetype = HCACHE_NONE; - data->dns.hostcache = NULL; - } + if(data->dns.hostcachetype == HCACHE_PRIVATE) + Curl_hostcache_destroy(data); if(data->state.rangestringalloc) free(data->state.range); @@ -2131,7 +2128,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, if(data->share->hostcache) { /* use shared host cache, first free the private one if any */ if(data->dns.hostcachetype == HCACHE_PRIVATE) - Curl_hash_destroy(data->dns.hostcache); + Curl_hostcache_destroy(data); data->dns.hostcache = data->share->hostcache; data->dns.hostcachetype = HCACHE_SHARED; @@ -2626,12 +2623,6 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) conn->dns_entry = NULL; } -#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST) - /* scan for DNS cache entries still marked as in use */ - Curl_hash_apply(data->hostcache, - NULL, Curl_scan_cache_used); -#endif - Curl_hostcache_prune(data); /* kill old DNS cache entries */ { -- cgit v1.2.1 From 4f8db8bf957b4e3efafa517ba14770dac7781204 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Dec 2011 00:09:41 +0100 Subject: Curl_do_more: fix typo logic In the recent do_more fix the new logic was mistakenly checking the pointer instead of what it points to. Reported by: Gokhan Sengun Bug: http://curl.haxx.se/mail/lib-2011-12/0250.html --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 75b298706..a95426fe6 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5466,7 +5466,7 @@ CURLcode Curl_do_more(struct connectdata *conn, bool *completed) if(conn->handler->do_more) result = conn->handler->do_more(conn, completed); - if(!result && completed) + if(!result && *completed) /* do_complete must be called after the protocol-specific DO function */ do_complete(conn); -- cgit v1.2.1 From 207cf15032a7e8eab71b2f4655fc5c21e5d3623d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 31 Dec 2011 10:39:54 +0100 Subject: changed case: use new host name for subsequent HTTP requests When a HTTP connection is re-used for a subsequent request without proxy, it would always re-use the Host: header of the first request. As host names are case insensitive it would make curl send another host name case that what the particular request used. Now it will instead always use the most recent host name to always use the desired casing. Added test case 1318 to verify. Bug: http://curl.haxx.se/mail/lib-2011-12/0314.html Reported by: Alex Vinnik --- lib/url.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a95426fe6..86a5576c8 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4666,14 +4666,10 @@ static void reuse_conn(struct connectdata *old_conn, old_conn->proxypasswd = NULL; } - /* host can change, when doing keepalive with a proxy ! */ - if(conn->bits.proxy) { - Curl_safefree(conn->host.rawalloc); - conn->host=old_conn->host; - } - else - /* free the newly allocated name buffer */ - Curl_safefree(old_conn->host.rawalloc); + /* host can change, when doing keepalive with a proxy or if the case is + different this time etc */ + Curl_safefree(conn->host.rawalloc); + conn->host=old_conn->host; /* persist connection info in session handle */ Curl_persistconninfo(conn); -- cgit v1.2.1 From 0ce2bca741ae596a346b2ab767dfbf5be9bc7dae Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 16 Jan 2012 21:14:05 +0100 Subject: add LF termination to infof() trace string --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 86a5576c8..d9dec701b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -3484,7 +3484,7 @@ static void fix_hostname(struct SessionHandle *data, host->name = host->encalloc; } #else - infof (data, "IDN support not present, can't parse Unicode domains"); + infof(data, "IDN support not present, can't parse Unicode domains\n"); #endif } } -- cgit v1.2.1 From d56b4c3f89ad3ee28dc62a22cffe2c85ced19830 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 18 Jan 2012 23:39:30 +0100 Subject: ssl session caching: fix compiler warnings --- lib/url.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d9dec701b..fd46a7e03 100644 --- a/lib/url.c +++ b/lib/url.c @@ -683,7 +683,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ /* Set the default size of the SSL session ID cache */ - set->ssl.numsessions = 5; + set->ssl.max_ssl_sessions = 5; set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */ set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ @@ -2106,10 +2106,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->cookies = NULL; #endif - if(data->share->sslsession == data->state.session) { + if(data->share->sslsession == data->state.session) data->state.session = NULL; - data->set.ssl.numsessions = 0; - } data->share->dirty--; @@ -2143,7 +2141,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, } #endif /* CURL_DISABLE_HTTP */ if(data->share->sslsession) { - data->set.ssl.numsessions = data->share->nsslsession; + data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions; data->state.session = data->share->sslsession; } Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); -- cgit v1.2.1 From 7883cd5af38a824e41b42c94890ea94bf4356fd3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 20 Jan 2012 23:32:43 +0100 Subject: URL parse: user name with ipv6 numerical address Using a URL with embedded user name and password didn't work if the host was given as a numerical IPv6 string, like ftp://user:password@[::1]/ Reported by: Brandon Wang Bug: http://curl.haxx.se/mail/archive-2012-01/0047.html --- lib/url.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index fd46a7e03..466748bfc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -137,7 +137,9 @@ static long ConnectionKillOne(struct SessionHandle *data); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); static CURLcode do_init(struct connectdata *conn); - +static CURLcode parse_url_userpass(struct SessionHandle *data, + struct connectdata *conn, + char *user, char *passwd); /* * Protocol table. */ @@ -3666,7 +3668,9 @@ static CURLcode findprotocol(struct SessionHandle *data, */ static CURLcode parseurlandfillconn(struct SessionHandle *data, struct connectdata *conn, - bool *prot_missing) + bool *prot_missing, + char *user, + char *passwd) { char *at; char *fragment; @@ -3675,6 +3679,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, int rc; char protobuf[16]; const char *protop; + CURLcode result; *prot_missing = FALSE; @@ -3841,6 +3846,14 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, path[0] = '/'; } + /************************************************************* + * Parse a user name and password in the URL and strip it out + * of the host name + *************************************************************/ + result = parse_url_userpass(data, conn, user, passwd); + if(result != CURLE_OK) + return result; + if(conn->host.name[0] == '[') { /* This looks like an IPv6 address literal. See if there is an address scope. */ @@ -4783,7 +4796,7 @@ static CURLcode create_conn(struct SessionHandle *data, conn->host.name = conn->host.rawalloc; conn->host.name[0] = 0; - result = parseurlandfillconn(data, conn, &prot_missing); + result = parseurlandfillconn(data, conn, &prot_missing, user, passwd); if(result != CURLE_OK) return result; @@ -4812,15 +4825,6 @@ static CURLcode create_conn(struct SessionHandle *data, data->change.url_alloc = TRUE; /* free this later */ } - /************************************************************* - * Parse a user name and password in the URL and strip it out - * of the host name - *************************************************************/ - result = parse_url_userpass(data, conn, user, passwd); - if(result != CURLE_OK) - return result; - - /************************************************************* * If the protocol can't handle url query strings, then cut * of the unhandable part -- cgit v1.2.1 From ea055407fa45c4247042e7370d463364f03c3136 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Feb 2012 22:59:49 +0100 Subject: curl_easy_reset: reset the referer string When CURLOPT_REFERER has been used, curl_easy_reset() did not properly clear it. Verified with the new test 598 Bug: http://curl.haxx.se/bug/view.cgi?id=3481551 Reported by: Michael Day --- lib/url.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 466748bfc..395055f4e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -272,6 +272,12 @@ void Curl_freeset(struct SessionHandle * data) enum dupstring i; for(i=(enum dupstring)0; i < STRING_LAST; i++) Curl_safefree(data->set.str[i]); + + if(data->change.referer_alloc) { + Curl_safefree(data->change.referer); + data->change.referer_alloc = FALSE; + } + data->change.referer = NULL; } static CURLcode setstropt(char **charp, char * s) -- cgit v1.2.1 From 705f0f7a5b6120bb783d139c9266b285a4c8acd8 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 24 Jan 2012 01:28:06 +0000 Subject: add library support for tuning TCP_KEEPALIVE This adds three new options to control the behavior of TCP keepalives: - CURLOPT_TCP_KEEPALIVE: enable/disable probes - CURLOPT_TCP_KEEPIDLE: idle time before sending first probe - CURLOPT_TCP_KEEPINTVL: delay between successive probes While not all operating systems support the TCP_KEEPIDLE and TCP_KEEPINTVL knobs, the library will still allow these options to be set by clients, silently ignoring the values. --- lib/url.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 395055f4e..c89234d74 100644 --- a/lib/url.c +++ b/lib/url.c @@ -748,6 +748,13 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->chunk_bgn = ZERO_NULL; set->chunk_end = ZERO_NULL; + /* tcp keepalives are disabled by default, but provide reasonable values for + * the interval and idle times. + */ + set->tcp_keepalive = 0; + set->tcp_keepintvl = 60; + set->tcp_keepidle = 60; + return res; } @@ -811,6 +818,7 @@ CURLcode Curl_open(struct SessionHandle **curl) multi stack. */ } + if(res) { Curl_resolver_cleanup(data->state.resolver); if(data->state.headerbuff) @@ -2545,6 +2553,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = Curl_set_dns_servers(data, va_arg(param, char *)); break; + case CURLOPT_TCP_KEEPALIVE: + data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE; + break; + case CURLOPT_TCP_KEEPIDLE: + data->set.tcp_keepidle = va_arg(param, long); + break; + case CURLOPT_TCP_KEEPINTVL: + data->set.tcp_keepintvl = va_arg(param, long); + break; + default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; -- cgit v1.2.1 From 2a699bc6e94b8223d900e8880ad628aebf17ab6d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 6 Feb 2012 22:12:06 +0100 Subject: CURLOPT_SSL_OPTIONS: added Allow an appliction to set libcurl specific SSL options. The first and only options supported right now is CURLSSLOPT_ALLOW_BEAST. It will make libcurl to disable any work-arounds the underlying SSL library may have to address a known security flaw in the SSL3 and TLS1.0 protocol versions. This is a reaction to us unconditionally removing that behavior after this security advisory: http://curl.haxx.se/docs/adv_20120124B.html ... it did however cause a lot of programs to fail because of old servers not liking this work-around. Now programs can opt to decrease the security in order to interoperate with old servers better. --- lib/url.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c89234d74..b3040b26d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -838,6 +838,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, { char *argptr; CURLcode result = CURLE_OK; + long arg; #ifndef CURL_DISABLE_HTTP curl_off_t bigsize; #endif @@ -847,12 +848,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.dns_cache_timeout = va_arg(param, long); break; case CURLOPT_DNS_USE_GLOBAL_CACHE: - { /* remember we want this enabled */ - long use_cache = va_arg(param, long); - data->set.global_dns_cache = (0 != use_cache)?TRUE:FALSE; - } - break; + arg = va_arg(param, long); + data->set.global_dns_cache = (0 != arg)?TRUE:FALSE; + break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], @@ -2189,6 +2188,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ data->set.use_ssl = (curl_usessl)va_arg(param, long); break; + + case CURLOPT_SSL_OPTIONS: + arg = va_arg(param, long); + data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE; + break; + #endif case CURLOPT_FTPSSLAUTH: /* -- cgit v1.2.1 From ecc93caaebe4d7c0168cedd99c3a6c42f7db9666 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Feb 2012 16:26:20 +0100 Subject: parse_proxy: bail out on zero-length proxy names! The proxy parser function strips off trailing slashes off the proxy name which could lead to a mistaken zero length proxy name which would be treated as no proxy at all by subsequent functions! This is now detected and an error is returned. Verified by the new test 1329. Reported by: Chandrakant Bagul Bug: http://curl.haxx.se/mail/lib-2012-02/0000.html --- lib/url.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b3040b26d..d0e0eaeb2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4271,11 +4271,20 @@ static CURLcode parse_proxy(struct SessionHandle *data, conn->port = strtol(prox_portno, NULL, 10); } else { + if(proxyptr[0]=='/') { + /* If the first character in the proxy string is a slash, fail + immediately. The following code will otherwise clear the string which + will lead to code running as if no proxy was set! */ + free(proxy); /* free the former proxy string */ + return CURLE_COULDNT_RESOLVE_PROXY; + } + /* without a port number after the host name, some people seem to use a slash so we strip everything from the first slash */ atsign = strchr(proxyptr, '/'); - if(atsign) + if(atsign) { *atsign = 0x0; /* cut off path part from host name */ + } if(data->set.proxyport) /* None given in the proxy string, then get the default one if it is -- cgit v1.2.1 From 7ed25fcc5c89c135bac3120b5efd820649dc9083 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Feb 2012 17:00:55 +0100 Subject: parse_proxy: simply memory handling ... by making sure that the string is always freed after the invoke as parse_proxy will always copy the data and this way there's a single free() instead of multiple ones. --- lib/url.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d0e0eaeb2..277078ebf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4224,20 +4224,16 @@ static CURLcode parse_proxy(struct SessionHandle *data, if(CURLE_OK == res) { conn->bits.proxy_user_passwd = TRUE; /* enable it */ - atsign = strdup(atsign+1); /* the right side of the @-letter */ + atsign++; /* the right side of the @-letter */ - if(atsign) { - free(proxy); /* free the former proxy string */ + if(atsign) proxy = proxyptr = atsign; /* now use this instead */ - } else res = CURLE_OUT_OF_MEMORY; } - if(res) { - free(proxy); /* free the allocated proxy string */ + if(res) return res; - } } } @@ -4271,20 +4267,17 @@ static CURLcode parse_proxy(struct SessionHandle *data, conn->port = strtol(prox_portno, NULL, 10); } else { - if(proxyptr[0]=='/') { + if(proxyptr[0]=='/') /* If the first character in the proxy string is a slash, fail immediately. The following code will otherwise clear the string which will lead to code running as if no proxy was set! */ - free(proxy); /* free the former proxy string */ return CURLE_COULDNT_RESOLVE_PROXY; - } /* without a port number after the host name, some people seem to use a slash so we strip everything from the first slash */ atsign = strchr(proxyptr, '/'); - if(atsign) { + if(atsign) *atsign = 0x0; /* cut off path part from host name */ - } if(data->set.proxyport) /* None given in the proxy string, then get the default one if it is @@ -4296,7 +4289,6 @@ static CURLcode parse_proxy(struct SessionHandle *data, conn->proxy.rawalloc = strdup(proxyptr); conn->proxy.name = conn->proxy.rawalloc; - free(proxy); if(!conn->proxy.rawalloc) return CURLE_OUT_OF_MEMORY; @@ -4927,8 +4919,9 @@ static CURLcode create_conn(struct SessionHandle *data, if(proxy) { result = parse_proxy(data, conn, proxy); - /* parse_proxy has freed the proxy string, so don't try to use it again */ - if(result != CURLE_OK) + free(proxy); /* parse_proxy copies the proxy string */ + + if(result) return result; if((conn->proxytype == CURLPROXY_HTTP) || -- cgit v1.2.1 From 0cf0ab6f3008aaad0bb5e3291539e80123028864 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Wed, 5 Oct 2011 22:22:29 +0100 Subject: smtp_mail: Added support to MAIL FROM for the optional AUTH parameter Added a new CURLOPT_MAIL_AUTH option that allows the calling program to set the optional AUTH parameter in the MAIL FROM command. When this option is specified and an authentication mechanism is used to communicate with the mail server then the AUTH parameter will be included in the MAIL FROM command. This is particularly useful when the calling program is acting as a relay in a trusted environment and performing server to server communication, as it allows the relaying server to specify the address of the mailbox that was used to authenticate and send the original email. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 277078ebf..c4e84550f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2402,6 +2402,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, va_arg(param, char *)); break; + case CURLOPT_MAIL_AUTH: + result = setstropt(&data->set.str[STRING_MAIL_AUTH], + va_arg(param, char *)); + break; + case CURLOPT_MAIL_RCPT: /* get a list of mail recipients */ data->set.mail_rcpt = va_arg(param, struct curl_slist *); -- cgit v1.2.1 From 41b02378342322aa8e264260057502f4d7493239 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 8 Mar 2012 23:31:38 +0100 Subject: CONNECT: made generically not per-protocol Curl_protocol_connect() now does the tunneling through the HTTP proxy if requested instead of letting each protocol specific connection function do it. --- lib/url.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c4e84550f..9660ce609 100644 --- a/lib/url.c +++ b/lib/url.c @@ -124,6 +124,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "socks.h" #include "curl_rtmp.h" #include "gopher.h" +#include "http_proxy.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -3385,13 +3386,45 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, Curl_verboseconnect(conn); if(!conn->bits.protoconnstart) { + + /* Set start time here for timeout purposes in the connect procedure, it + is later set again for the progress meter purpose */ + conn->now = Curl_tvnow(); + + if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { +#ifndef CURL_DISABLE_PROXY + /* for [protocol] tunneled through HTTP proxy */ + struct HTTP http_proxy; + void *prot_save; + + /* BLOCKING */ + /* We want "seamless" operations through HTTP proxy tunnel */ + + /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the + * member conn->proto.http; we want [protocol] through HTTP and we have + * to change the member temporarily for connecting to the HTTP + * proxy. After Curl_proxyCONNECT we have to set back the member to the + * original pointer + */ + prot_save = data->state.proto.generic; + memset(&http_proxy, 0, sizeof(http_proxy)); + data->state.proto.http = &http_proxy; + + result = Curl_proxyCONNECT(conn, FIRSTSOCKET, + conn->host.name, conn->remote_port); + + data->state.proto.generic = prot_save; + + if(CURLE_OK != result) + return result; +#else + return CURLE_NOT_BUILT_IN; +#endif + } + if(conn->handler->connect_it) { /* is there a protocol-specific connect() procedure? */ - /* Set start time here for timeout purposes in the connect procedure, it - is later set again for the progress meter purpose */ - conn->now = Curl_tvnow(); - /* Call the protocol-specific connect function */ result = conn->handler->connect_it(conn, protocol_done); } -- cgit v1.2.1 From 8af4b657d0f44bd6f2b1d672666c046e53af0e0c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 16 Mar 2012 19:06:34 +0100 Subject: fix some compiler warnings --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9660ce609..a78e27fb9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -752,7 +752,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) /* tcp keepalives are disabled by default, but provide reasonable values for * the interval and idle times. */ - set->tcp_keepalive = 0; + set->tcp_keepalive = FALSE; set->tcp_keepintvl = 60; set->tcp_keepidle = 60; -- cgit v1.2.1 From c83de6d07625b813e3bbc31f9a0827c3a0007355 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 21 Mar 2012 23:22:39 +0100 Subject: CONNECT: fix multi interface regression The refactoring of HTTP CONNECT handling in commit 41b0237834232 that made it protocol independent broke it for the multi interface. This fix now introduce a better state handling and moved some logic to the http_proxy.c source file. Reported by: Yang Tse Bug: http://curl.haxx.se/mail/lib-2012-03/0162.html --- lib/url.c | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a78e27fb9..01e217cd9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3391,36 +3391,9 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, is later set again for the progress meter purpose */ conn->now = Curl_tvnow(); - if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { -#ifndef CURL_DISABLE_PROXY - /* for [protocol] tunneled through HTTP proxy */ - struct HTTP http_proxy; - void *prot_save; - - /* BLOCKING */ - /* We want "seamless" operations through HTTP proxy tunnel */ - - /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the - * member conn->proto.http; we want [protocol] through HTTP and we have - * to change the member temporarily for connecting to the HTTP - * proxy. After Curl_proxyCONNECT we have to set back the member to the - * original pointer - */ - prot_save = data->state.proto.generic; - memset(&http_proxy, 0, sizeof(http_proxy)); - data->state.proto.http = &http_proxy; - - result = Curl_proxyCONNECT(conn, FIRSTSOCKET, - conn->host.name, conn->remote_port); - - data->state.proto.generic = prot_save; - - if(CURLE_OK != result) - return result; -#else - return CURLE_NOT_BUILT_IN; -#endif - } + result = Curl_proxy_connect(conn); + if(result) + return result; if(conn->handler->connect_it) { /* is there a protocol-specific connect() procedure? */ -- cgit v1.2.1 From 0b516b7162dc387ed80b0f24476b950ab2e18cb7 Mon Sep 17 00:00:00 2001 From: Andrei Cipu Date: Fri, 30 Mar 2012 10:40:04 +0300 Subject: CURLOPT_POSTREDIR: also allow 303 to do POST on the redirected URL As it turns out, some people do want that after all. --- lib/url.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 01e217cd9..9ae977e11 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1111,12 +1111,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 * CURL_REDIR_POST_301 - POST is kept as POST after 301 * CURL_REDIR_POST_302 - POST is kept as POST after 302 - * CURL_REDIR_POST_ALL - POST is kept as POST after 301 and 302 + * CURL_REDIR_POST_303 - POST is kept as POST after 303 + * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 * other - POST is kept as POST after 301 and 302 */ long postRedir = va_arg(param, long); - data->set.post301 = (postRedir & CURL_REDIR_POST_301)?TRUE:FALSE; - data->set.post302 = (postRedir & CURL_REDIR_POST_302)?TRUE:FALSE; + data->set.keep_post = postRedir & CURL_REDIR_POST_ALL; } break; -- cgit v1.2.1 From 8c29bf5640709f9b4497a75cf08859a66c46a3d1 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 12 Apr 2012 20:39:15 +0200 Subject: url.c: fix compiler warning --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 9ae977e11..a290e3cea 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1115,7 +1115,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 * other - POST is kept as POST after 301 and 302 */ - long postRedir = va_arg(param, long); + int postRedir = curlx_sltosi(va_arg(param, long)); data->set.keep_post = postRedir & CURL_REDIR_POST_ALL; } break; -- cgit v1.2.1 From 9421b06397d25426ab013e2b90d4604ed6430926 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 18 Apr 2012 23:04:35 +0200 Subject: Take in account that CURLAUTH_* bitmasks are now 'unsigned long' Data type of internal vars holding CURLAUTH_* bitmasks changed from 'long' to 'unsigned long' for proper handling and operating. --- lib/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a290e3cea..ac496bb8d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1397,7 +1397,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set HTTP Authentication type BITMASK. */ { - long auth = va_arg(param, long); + unsigned long auth = va_arg(param, unsigned long); /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ @@ -1461,7 +1461,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set HTTP Authentication type BITMASK. */ { - long auth = va_arg(param, long); + unsigned long auth = va_arg(param, unsigned long); /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ -- cgit v1.2.1 From df4205c10a459dccd480bdaefd22ef6768a4a49c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 19 Apr 2012 00:35:44 +0200 Subject: url.c: CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH fixes Fail with CURLE_NOT_BUILT_IN when none of requested auth methods is supported. Reject CURLAUTH_ONLY bit when given alone or with CURLAUTH_NONE. --- lib/url.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index ac496bb8d..d0c64281e 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1397,8 +1397,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set HTTP Authentication type BITMASK. */ { + int bitcheck; + bool authbits; unsigned long auth = va_arg(param, unsigned long); + if(auth == CURLAUTH_NONE) { + data->set.httpauth = auth; + break; + } + /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; @@ -1419,7 +1426,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ #endif - if(!auth) + + /* check if any auth bit lower than CURLAUTH_ONLY is still set */ + bitcheck = 0; + authbits = FALSE; + while(bitcheck < 31) { + if(auth & (1UL << bitcheck++)) { + authbits = TRUE; + break; + } + } + if(!authbits) return CURLE_NOT_BUILT_IN; /* no supported types left! */ data->set.httpauth = auth; @@ -1461,8 +1478,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set HTTP Authentication type BITMASK. */ { + int bitcheck; + bool authbits; unsigned long auth = va_arg(param, unsigned long); + if(auth == CURLAUTH_NONE) { + data->set.proxyauth = auth; + break; + } + /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; @@ -1482,7 +1506,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or WINDOWS_SSPI */ #endif - if(!auth) + + /* check if any auth bit lower than CURLAUTH_ONLY is still set */ + bitcheck = 0; + authbits = FALSE; + while(bitcheck < 31) { + if(auth & (1UL << bitcheck++)) { + authbits = TRUE; + break; + } + } + if(!authbits) return CURLE_NOT_BUILT_IN; /* no supported types left! */ data->set.proxyauth = auth; -- cgit v1.2.1 From 72b72fe8edc7e4fadc1d2f5ff106b60aeb88d512 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 23 Apr 2012 20:23:53 +0200 Subject: URL parse: reject numerical IPv6 addresses outside brackets Roman Mamedov spotted (in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=670126) that curl would not complain when given a URL with an IPv6 numerical address without brackets. It would simply cut off the last ":[hex]" part and thus not work correctly. That's a URL using an illegal syntax and now libcurl will instead return a clear error code and error message detailing the error. The above mentioned bug report claims this to be a regression but libcurl does not guarantee functionality when given URLs that aren't following the URL spec (RFC3986 mostly). I consider the fact that it used to handle this differently a mere coincidence. --- lib/url.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index d0c64281e..b78c200fa 100644 --- a/lib/url.c +++ b/lib/url.c @@ -105,6 +105,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "rawstr.h" #include "warnless.h" #include "non-ascii.h" +#include "inet_pton.h" /* And now for the protocols */ #include "ftp.h" @@ -4495,8 +4496,19 @@ static CURLcode parse_remote_port(struct SessionHandle *data, portptr = NULL; /* no port number available */ } } - else + else { +#ifdef ENABLE_IPV6 + struct in6_addr in6; + if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) { + /* This is a numerical IPv6 address, meaning this is a wrongly formatted + URL */ + failf(data, "IPv6 numerical address used in URL without brackets"); + return CURLE_URL_MALFORMAT; + } +#endif + portptr = strrchr(conn->host.name, ':'); + } if(data->set.use_port && data->state.allow_port) { /* if set, we use this and ignore the port possibly given in the URL */ -- cgit v1.2.1 From 6cd084a3b5129d9ab8db3e5bc0f094943d7eef89 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 10 Jun 2012 23:39:04 +0200 Subject: Curl_pgrsDone: return int and acknowledge return code Since Curl_pgrsDone() itself calls Curl_pgrsUpdate() which may return an abort instruction or similar we need to return that info back and subsequently properly handle return codes from Curl_pgrsDone() where used. (Spotted by a Coverity scan) --- lib/url.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b78c200fa..88e169c98 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5379,7 +5379,8 @@ CURLcode Curl_done(struct connectdata **connp, else result = CURLE_OK; - Curl_pgrsDone(conn); /* done with the operation */ + if(Curl_pgrsDone(conn) && !result) + result = CURLE_ABORTED_BY_CALLBACK; /* if the transfer was completed in a paused state there can be buffered data left to write and then kill */ -- cgit v1.2.1 From 9ca313798760494df4136f99cf7cd935e43e9ab2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 13 Jul 2012 14:28:12 +0200 Subject: parse_proxy: remove dead assignment Spotted by clang-analyzer --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 88e169c98..87b870113 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4273,7 +4273,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, atsign++; /* the right side of the @-letter */ if(atsign) - proxy = proxyptr = atsign; /* now use this instead */ + proxyptr = atsign; /* now use this instead */ else res = CURLE_OUT_OF_MEMORY; } -- cgit v1.2.1 From 15108d6308466072a8474e4c23cdfcce2e65a032 Mon Sep 17 00:00:00 2001 From: Mike Crowe Date: Tue, 17 Jul 2012 18:43:49 +0200 Subject: Avoid leak of local device string when reusing connection Ensure that the copy of the CURLOPT_INTERFACE string is freed if we decide we can reuse an existing connection. --- lib/url.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 87b870113..567f1de90 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4779,6 +4779,7 @@ static void reuse_conn(struct connectdata *old_conn, Curl_safefree(old_conn->passwd); Curl_safefree(old_conn->proxyuser); Curl_safefree(old_conn->proxypasswd); + Curl_safefree(old_conn->localdev); Curl_llist_destroy(old_conn->send_pipe, NULL); Curl_llist_destroy(old_conn->recv_pipe, NULL); -- cgit v1.2.1 From bf6dc61967c044e2d4fb695f651a8c728c421cb6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 8 Aug 2012 13:49:35 +0200 Subject: verbose messages: fixed output of hostnames in re-used connections I suspect this is a regression introduced in commit 207cf150, included since 7.24.0. Avoid showing '(nil)' as hostname in verbose output by making sure the hostname fixup function is called early enough to set the pointers that are used for this. The name data is set again for each request even for re-used connections to handle multiple hostnames over the same connection (like with proxy) or that the casing etc of the host name is changed between requests (which has proven to be important at least once in the past). Test1011 was modified to use a redirect with a re-used a connection since it then showed the bug and now lo longer does. There's currently no easy way to have the test suite detect 'nil' texts in verbose ouputs so no tests will detect if this problem gets reintroduced. Bug: http://curl.haxx.se/mail/lib-2012-07/0111.html Reported by: Gisle Vanem --- lib/url.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 567f1de90..c2f488280 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4659,13 +4659,12 @@ static CURLcode resolve_server(struct SessionHandle *data, /************************************************************* * Resolve the name of the server or proxy *************************************************************/ - if(conn->bits.reuse) { - /* We're reusing the connection - no need to resolve anything */ + if(conn->bits.reuse) + /* We're reusing the connection - no need to resolve anything, and + fix_hostname() was called already in create_conn() for the re-use + case. */ *async = FALSE; - if(conn->bits.proxy) - fix_hostname(data, conn, &conn->host); - } else { /* this is a fresh connect */ int rc; @@ -5136,6 +5135,10 @@ static CURLcode create_conn(struct SessionHandle *data, free(conn); /* we don't need this anymore */ conn = conn_temp; *in_connect = conn; + + /* set a pointer to the hostname we display */ + fix_hostname(data, conn, &conn->host); + infof(data, "Re-using existing connection! (#%ld) with host %s\n", conn->connectindex, conn->proxy.name?conn->proxy.dispname:conn->host.dispname); -- cgit v1.2.1 From 5ede86ae51b8f71be35152584815f80dbd5a327a Mon Sep 17 00:00:00 2001 From: Joe Mason Date: Mon, 20 Aug 2012 17:00:40 -0400 Subject: NTLM: re-use existing connection better If we need an NTLM connection and one already exists, always choose that one. --- lib/url.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c2f488280..c05c50e62 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2928,10 +2928,14 @@ ConnectionExists(struct SessionHandle *data, { long i; struct connectdata *check; + struct connectdata *chosen = 0; bool canPipeline = IsPipeliningPossible(data, needle); + bool wantNTLM = (data->state.authhost.want==CURLAUTH_NTLM) || + (data->state.authhost.want==CURLAUTH_NTLM_WB); for(i=0; i< data->state.connc->num; i++) { bool match = FALSE; + bool credentialsMatch = FALSE; size_t pipeLen = 0; /* * Note that if we use a HTTP proxy, we check connections to that @@ -3102,9 +3106,7 @@ ConnectionExists(struct SessionHandle *data, } } if((needle->handler->protocol & CURLPROTO_FTP) || - ((needle->handler->protocol & CURLPROTO_HTTP) && - ((data->state.authhost.want==CURLAUTH_NTLM) || - (data->state.authhost.want==CURLAUTH_NTLM_WB)))) { + ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ if(!strequal(needle->user, check->user) || @@ -3112,6 +3114,7 @@ ConnectionExists(struct SessionHandle *data, /* one of them was different */ continue; } + credentialsMatch = TRUE; } match = TRUE; } @@ -3129,14 +3132,29 @@ ConnectionExists(struct SessionHandle *data, } if(match) { - check->inuse = TRUE; /* mark this as being in use so that no other - handle in a multi stack may nick it */ + chosen = check; - *usethis = check; - return TRUE; /* yes, we found one to use! */ + /* If we are not looking for an NTLM connection, we can choose this one + immediately. */ + if(!wantNTLM) + break; + + /* Otherwise, check if this is already authenticating with the right + credentials. If not, keep looking so that we can reuse NTLM + connections if possible. (Especially we must reuse the same + connection if partway through a handshake!) */ + if(credentialsMatch && chosen->ntlm.state != NTLMSTATE_NONE) + break; } } + if(chosen) { + chosen->inuse = TRUE; /* mark this as being in use so that no other + handle in a multi stack may nick it */ + *usethis = chosen; + return TRUE; /* yes, we found one to use! */ + } + return FALSE; /* no matching connecting exists */ } -- cgit v1.2.1 From 775cc1be66b7dd7994480bcb6d6a0fbf43620a96 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 13 Sep 2012 22:57:38 +0200 Subject: parse_proxy: treat "socks://x" as a socks4 proxy Selected socks proxy in Google's Chrome browser. Resulting in the following environment variables: NO_PROXY=localhost,127.0.0.0/8 ALL_PROXY=socks://localhost:1080/ all_proxy=socks://localhost:1080/ no_proxy=localhost,127.0.0.0/8 ... and libcurl didn't treat 'socks://' as socks but instead picked HTTP proxy. Reported by: Scott Bailey Bug: http://curl.haxx.se/bug/view.cgi?id=3566860 --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index c05c50e62..8bbd3e478 100644 --- a/lib/url.c +++ b/lib/url.c @@ -4249,7 +4249,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, conn->proxytype = CURLPROXY_SOCKS5; else if(checkprefix("socks4a", proxy)) conn->proxytype = CURLPROXY_SOCKS4A; - else if(checkprefix("socks4", proxy)) + else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy)) conn->proxytype = CURLPROXY_SOCKS4; /* Any other xxx:// : change to http proxy */ } -- cgit v1.2.1 From 74fe1b95fb44053fdbef4b1eb9f550a3da332eda Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 23 Oct 2012 23:12:58 +0200 Subject: tlsauthtype: deal with the string case insensitively When given a string as 'srp' it didn't work, but required 'SRP'. Starting now, the check disregards casing. Bug: http://curl.haxx.se/bug/view.cgi?id=3578418 Reported by: Jeff Connelly --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 8bbd3e478..b30a4fa51 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2589,7 +2589,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ break; case CURLOPT_TLSAUTH_TYPE: - if(strncmp((char *)va_arg(param, char *), "SRP", strlen("SRP")) == 0) + if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP"))) data->set.ssl.authtype = CURL_TLSAUTH_SRP; else data->set.ssl.authtype = CURL_TLSAUTH_NONE; -- cgit v1.2.1 From da82f59b697310229ccdf66104d5d65a44dfab98 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 27 Oct 2012 12:31:39 +0200 Subject: CURLOPT_SSL_VERIFYHOST: stop supporting the 1 value After a research team wrote a document[1] that found several live source codes out there in the wild that misused the CURLOPT_SSL_VERIFYHOST option thinking it was a boolean, this change now bans 1 as a value and will make libcurl return error for it. 1 was never a sensible value to use in production but was introduced back in the days to help debugging. It was always documented clearly this way. 1 was never supported by all SSL backends in libcurl, so this cleanup makes the treatment of it unified. The report's list of mistakes for this option were all PHP code and while there's a binding layer between libcurl and PHP, the PHP team has decided that they have an as thin layer as possible on top of libcurl so they will not alter or specifically filter a 'TRUE' value for this particular option. I sympathize with that position. [1] = http://daniel.haxx.se/blog/2012/10/25/libcurl-claimed-to-be-dangerous/ --- lib/url.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index b30a4fa51..5ffaa7305 100644 --- a/lib/url.c +++ b/lib/url.c @@ -708,7 +708,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) * switched off unless wanted. */ set->ssl.verifypeer = TRUE; - set->ssl.verifyhost = 2; + set->ssl.verifyhost = TRUE; #ifdef USE_TLS_SRP set->ssl.authtype = CURL_TLSAUTH_NONE; #endif @@ -2049,13 +2049,25 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, /* * Enable peer SSL verifying. */ - data->set.ssl.verifypeer = va_arg(param, long); + data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_SSL_VERIFYHOST: /* - * Enable verification of the CN contained in the peer certificate + * Enable verification of the host name in the peer certificate */ - data->set.ssl.verifyhost = va_arg(param, long); + arg = va_arg(param, long); + + /* Obviously people are not reading documentation and too many thought + this argument took a boolean when it wasn't and misused it. We thus ban + 1 as a sensible input and we warn about its use. Then we only have the + 2 action internally stored as TRUE. */ + + if(1 == arg) { + failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE; break; #ifdef USE_SSLEAY /* since these two options are only possible to use on an OpenSSL- -- cgit v1.2.1 From 473003fbdffc4a36e69d396e5164308e3800011d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 6 Nov 2012 23:17:57 +0100 Subject: URL parser: cut off '#' fragments from URLs (better) The existing logic only cut off the fragment from the separate 'path' buffer which is used when sending HTTP to hosts. The buffer that held the full URL used for proxies were not dealt with. It is now. Test case 5 was updated to use a fragment on a URL over a proxy. Bug: http://curl.haxx.se/bug/view.cgi?id=3579813 --- lib/url.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 5ffaa7305..601d8d364 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3987,9 +3987,17 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, last part of the URI. We are looking for the first '#' so that we deal gracefully with non conformant URI such as http://example.com#foo#bar. */ fragment = strchr(path, '#'); - if(fragment) + if(fragment) { *fragment = 0; + /* we know the path part ended with a fragment, so we know the full URL + string does too and we need to cut it off from there so it isn't used + over proxy */ + fragment = strchr(data->change.url, '#'); + if(fragment) + *fragment = 0; + } + /* * So if the URL was A://B/C#D, * protop is A -- cgit v1.2.1 From 79954a1b07c6fc8ed4cf9d48c6383521b184c818 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 26 Nov 2012 16:23:02 +0100 Subject: avoid mixing of enumerated type with another type --- lib/url.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 601d8d364..a781798e9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2943,7 +2943,7 @@ ConnectionExists(struct SessionHandle *data, struct connectdata *chosen = 0; bool canPipeline = IsPipeliningPossible(data, needle); bool wantNTLM = (data->state.authhost.want==CURLAUTH_NTLM) || - (data->state.authhost.want==CURLAUTH_NTLM_WB); + (data->state.authhost.want==CURLAUTH_NTLM_WB) ? TRUE : FALSE; for(i=0; i< data->state.connc->num; i++) { bool match = FALSE; -- cgit v1.2.1 From d021f2e8a0067fc769652f27afec9024c0d02b3d Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Thu, 6 Dec 2012 12:12:04 +0100 Subject: Introducing a new persistent connection caching system using "bundles". A bundle is a list of all persistent connections to the same host. The connection cache consists of a hash of bundles, with the hostname as the key. The benefits may not be obvious, but they are two: 1) Faster search for connections to reuse, since the hash lookup only finds connections to the host in question. 2) It lays out the groundworks for an upcoming patch, which will introduce multiple HTTP pipelines. This patch also removes the awkward list of "closure handles", which were needed to send QUIT commands to the FTP server when closing a connection. Now we allocate a separate closure handle and use that one to close all connections. This has been tested in a live system for a few weeks, and of course passes the test suite. --- lib/url.c | 708 ++++++++++++++++++++++---------------------------------------- 1 file changed, 253 insertions(+), 455 deletions(-) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index a781798e9..574751716 100644 --- a/lib/url.c +++ b/lib/url.c @@ -126,6 +126,8 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "curl_rtmp.h" #include "gopher.h" #include "http_proxy.h" +#include "bundles.h" +#include "conncache.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -135,7 +137,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out); #include "memdebug.h" /* Local static prototypes */ -static long ConnectionKillOne(struct SessionHandle *data); +static bool ConnectionKillOne(struct SessionHandle *data); static void conn_free(struct connectdata *conn); static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); static CURLcode do_init(struct connectdata *conn); @@ -262,10 +264,10 @@ static const struct Curl_handler Curl_handler_dummy = { static void close_connections(struct SessionHandle *data) { /* Loop through all open connections and kill them one by one */ - long i; + bool killed; do { - i = ConnectionKillOne(data); - } while(i != -1L); + killed = ConnectionKillOne(data); + } while(killed); } void Curl_freeset(struct SessionHandle * data) @@ -378,66 +380,6 @@ CURLcode Curl_close(struct SessionHandle *data) { struct Curl_multi *m = data->multi; -#ifdef DEBUGBUILD - /* only for debugging, scan through all connections and see if there's a - pipe reference still identifying this handle */ - - if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) { - struct conncache *c = data->state.connc; - long i; - struct curl_llist *pipeline; - struct curl_llist_element *curr; - struct connectdata *connptr; - - for(i=0; i< c->num; i++) { - connptr = c->connects[i]; - if(!connptr) - continue; - - pipeline = connptr->send_pipe; - if(pipeline) { - for(curr = pipeline->head; curr; curr=curr->next) { - if(data == (struct SessionHandle *) curr->ptr) { - fprintf(stderr, - "problem we %p are still in send pipe for %p done %d\n", - data, connptr, (int)connptr->bits.done); - } - } - } - pipeline = connptr->recv_pipe; - if(pipeline) { - for(curr = pipeline->head; curr; curr=curr->next) { - if(data == (struct SessionHandle *) curr->ptr) { - fprintf(stderr, - "problem we %p are still in recv pipe for %p done %d\n", - data, connptr, (int)connptr->bits.done); - } - } - } - pipeline = connptr->done_pipe; - if(pipeline) { - for(curr = pipeline->head; curr; curr=curr->next) { - if(data == (struct SessionHandle *) curr->ptr) { - fprintf(stderr, - "problem we %p are still in done pipe for %p done %d\n", - data, connptr, (int)connptr->bits.done); - } - } - } - pipeline = connptr->pend_pipe; - if(pipeline) { - for(curr = pipeline->head; curr; curr=curr->next) { - if(data == (struct SessionHandle *) curr->ptr) { - fprintf(stderr, - "problem we %p are still in pend pipe for %p done %d\n", - data, connptr, (int)connptr->bits.done); - } - } - } - } - } -#endif - Curl_expire(data, 0); /* shut off timers */ if(m) @@ -457,26 +399,16 @@ CURLcode Curl_close(struct SessionHandle *data) the multi handle, since that function uses the magic field! */ - if(data->state.connc) { - - if(data->state.connc->type == CONNCACHE_PRIVATE) { + if(data->state.conn_cache) { + if(data->state.conn_cache->type == CONNCACHE_PRIVATE) { /* close all connections still alive that are in the private connection cache, as we no longer have the pointer left to the shared one. */ close_connections(data); - - /* free the connection cache if allocated privately */ - Curl_rm_connc(data->state.connc); - data->state.connc = NULL; + Curl_conncache_destroy(data->state.conn_cache); + data->state.conn_cache = NULL; } } - if(data->state.shared_conn) { - /* marked to be used by a pending connection so we can't kill this handle - just yet */ - data->state.closed = TRUE; - return CURLE_OK; - } - if(data->dns.hostcachetype == HCACHE_PRIVATE) Curl_hostcache_destroy(data); @@ -533,124 +465,6 @@ CURLcode Curl_close(struct SessionHandle *data) return CURLE_OK; } -/* create a connection cache of a private or multi type */ -struct conncache *Curl_mk_connc(int type, - long amount) /* set -1 to use default */ -{ - /* It is subject for debate how many default connections to have for a multi - connection cache... */ - - struct conncache *c; - long default_amount; - long max_amount = (long)(((size_t)INT_MAX) / sizeof(struct connectdata *)); - - if(type == CONNCACHE_PRIVATE) { - default_amount = (amount < 1L) ? 5L : amount; - } - else { - default_amount = (amount < 1L) ? 10L : amount; - } - - if(default_amount > max_amount) - default_amount = max_amount; - - c = calloc(1, sizeof(struct conncache)); - if(!c) - return NULL; - - c->connects = calloc((size_t)default_amount, sizeof(struct connectdata *)); - if(!c->connects) { - free(c); - return NULL; - } - - c->num = default_amount; - - return c; -} - -/* Change number of entries of a connection cache */ -CURLcode Curl_ch_connc(struct SessionHandle *data, - struct conncache *c, - long newamount) -{ - long i; - struct connectdata **newptr; - long max_amount = (long)(((size_t)INT_MAX) / sizeof(struct connectdata *)); - - if(newamount < 1) - newamount = 1; /* we better have at least one entry */ - - if(!c) { - /* we get a NULL pointer passed in as connection cache, which means that - there is no cache created for this SessionHandle just yet, we create a - brand new with the requested size. - */ - data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, newamount); - if(!data->state.connc) - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; - } - - if(newamount < c->num) { - /* 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! - - NOTE: for conncache_multi cases we must make sure that we only - close handles not in use. - */ - for(i=newamount; i< c->num; i++) { - Curl_disconnect(c->connects[i], /* dead_connection */ FALSE); - c->connects[i] = NULL; - } - - /* If the most recent connection is no longer valid, mark it - invalid. */ - if(data->state.lastconnect <= newamount) - data->state.lastconnect = -1; - } - if(newamount > 0) { - if(newamount > max_amount) - newamount = max_amount; - newptr = realloc(c->connects, sizeof(struct connectdata *) * newamount); - if(!newptr) - /* we closed a few connections in vain, but so what? */ - return CURLE_OUT_OF_MEMORY; - - /* nullify the newly added pointers */ - for(i=c->num; iconnects = newptr; - c->num = newamount; - } - /* we no longer support less than 1 as size for the connection cache, and - I'm not sure it ever worked to set it to zero */ - return CURLE_OK; -} - -/* Free a connection cache. This is called from Curl_close() and - curl_multi_cleanup(). */ -void Curl_rm_connc(struct conncache *c) -{ - if(!c) - return; - - if(c->connects) { - long i; - for(i = 0; i < c->num; ++i) { - conn_free(c->connects[i]); - c->connects[i] = NULL; - } - free(c->connects); - c->connects = NULL; - } - c->num = 0; - - free(c); -} - /* * Initialize the UserDefined fields within a SessionHandle. * This may be safely called on a new or existing SessionHandle. @@ -807,7 +621,7 @@ CURLcode Curl_open(struct SessionHandle **curl) Curl_convert_init(data); /* most recent connection is not yet defined */ - data->state.lastconnect = -1; + data->state.lastconnect = NULL; data->progress.flags |= PGRS_HIDE; data->state.current_speed = -1; /* init to negative == impossible */ @@ -880,7 +694,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Set the absolute number of maximum simultaneous alive connection that * libcurl is allowed to have. */ - result = Curl_ch_connc(data, data->state.connc, va_arg(param, long)); + data->set.maxconnects = va_arg(param, long); break; case CURLOPT_FORBID_REUSE: /* @@ -2744,14 +2558,9 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) /* This is set if protocol-specific cleanups should be made */ conn->handler->disconnect(conn, dead_connection); - if(-1 != conn->connectindex) { /* unlink ourselves! */ - infof(data, "Closing connection #%ld\n", conn->connectindex); - if(data->state.connc) - /* only clear the table entry if we still know in which cache we - used to be in */ - data->state.connc->connects[conn->connectindex] = NULL; - } + infof(data, "Closing connection %d\n", conn->connection_id); + Curl_conncache_remove_conn(data->state.conn_cache, conn); #if defined(USE_LIBIDN) if(conn->host.encalloc) @@ -2938,225 +2747,229 @@ ConnectionExists(struct SessionHandle *data, struct connectdata *needle, struct connectdata **usethis) { - long i; struct connectdata *check; struct connectdata *chosen = 0; bool canPipeline = IsPipeliningPossible(data, needle); bool wantNTLM = (data->state.authhost.want==CURLAUTH_NTLM) || (data->state.authhost.want==CURLAUTH_NTLM_WB) ? TRUE : FALSE; + struct connectbundle *bundle; - for(i=0; i< data->state.connc->num; i++) { - bool match = FALSE; - bool credentialsMatch = FALSE; - size_t pipeLen = 0; - /* - * Note that if we use a HTTP proxy, we check connections to that - * proxy and not to the actual remote server. - */ - check = data->state.connc->connects[i]; - if(!check) - /* NULL pointer means not filled-in entry */ - continue; - - pipeLen = check->send_pipe->size + check->recv_pipe->size; + /* Look up the bundle with all the connections to this + particular host */ + bundle = Curl_conncache_find_bundle(data->state.conn_cache, + needle->host.name); + if(bundle) { + struct curl_llist_element *curr; - if(check->connectindex == -1) { - check->connectindex = i; /* Set this appropriately since it might have - been set to -1 when the easy was removed - from the multi */ - } + infof(data, "Found bundle for host %s: %p\n", needle->host.name, bundle); - if(!pipeLen && !check->inuse) { - /* The check for a dead socket makes sense only if there are no - handles in pipeline and the connection isn't already marked in - use */ - bool dead; - if(check->handler->protocol & CURLPROTO_RTSP) - /* RTSP is a special case due to RTP interleaving */ - dead = Curl_rtsp_connisdead(check); - else - dead = SocketIsDead(check->sock[FIRSTSOCKET]); + curr = bundle->conn_list->head; + while(curr) { + bool match = FALSE; + bool credentialsMatch = FALSE; + size_t pipeLen; - if(dead) { - check->data = data; - infof(data, "Connection #%ld seems to be dead!\n", i); - - /* disconnect resources */ - Curl_disconnect(check, /* dead_connection */ TRUE); - data->state.connc->connects[i]=NULL; /* nothing here */ + /* + * Note that if we use a HTTP proxy, we check connections to that + * proxy and not to the actual remote server. + */ + check = curr->ptr; + curr = curr->next; + + pipeLen = check->send_pipe->size + check->recv_pipe->size; + + if(!pipeLen && !check->inuse) { + /* The check for a dead socket makes sense only if there are no + handles in pipeline and the connection isn't already marked in + use */ + bool dead; + if(check->handler->protocol & CURLPROTO_RTSP) + /* RTSP is a special case due to RTP interleaving */ + dead = Curl_rtsp_connisdead(check); + else + dead = SocketIsDead(check->sock[FIRSTSOCKET]); - continue; - } - } + if(dead) { + check->data = data; + infof(data, "Connection %d seems to be dead!\n", + check->connection_id); - if(canPipeline) { - /* Make sure the pipe has only GET requests */ - struct SessionHandle* sh = gethandleathead(check->send_pipe); - struct SessionHandle* rh = gethandleathead(check->recv_pipe); - if(sh) { - if(!IsPipeliningPossible(sh, check)) - continue; - } - else if(rh) { - if(!IsPipeliningPossible(rh, check)) + /* disconnect resources */ + Curl_disconnect(check, /* dead_connection */ TRUE); continue; + } } + if(canPipeline) { + /* Make sure the pipe has only GET requests */ + struct SessionHandle* sh = gethandleathead(check->send_pipe); + struct SessionHandle* rh = gethandleathead(check->recv_pipe); + if(sh) { + if(!IsPipeliningPossible(sh, check)) + continue; + } + else if(rh) { + if(!IsPipeliningPossible(rh, check)) + continue; + } #ifdef DEBUGBUILD if(pipeLen > MAX_PIPELINE_LENGTH) { infof(data, "BAD! Connection #%ld has too big pipeline!\n", - check->connectindex); + check->connection_id); } #endif - } - else { - if(pipeLen > 0) { - /* can only happen within multi handles, and means that another easy - handle is using this connection */ - continue; } - - if(Curl_resolver_asynch()) { - /* ip_addr_str[0] is NUL only if the resolving of the name hasn't - completed yet and until then we don't re-use this connection */ - if(!check->ip_addr_str[0]) { - infof(data, - "Connection #%ld hasn't finished name resolve, can't reuse\n", - check->connectindex); + else { + if(pipeLen > 0) { + /* can only happen within multi handles, and means that another easy + handle is using this connection */ continue; } - } - if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) { - /* Don't pick a connection that hasn't connected yet or that is going - to get closed. */ - infof(data, "Connection #%ld isn't open enough, can't reuse\n", - check->connectindex); -#ifdef DEBUGBUILD - if(check->recv_pipe->size > 0) { - infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", - check->connectindex); + if(Curl_resolver_asynch()) { + /* ip_addr_str[0] is NUL only if the resolving of the name hasn't + completed yet and until then we don't re-use this connection */ + if(!check->ip_addr_str[0]) { + infof(data, + "Connection #%ld is still name resolving, can't reuse\n", + check->connection_id); + continue; + } } + + if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || + check->bits.close) { + /* Don't pick a connection that hasn't connected yet or that is going + to get closed. */ + infof(data, "Connection #%ld isn't open enough, can't reuse\n", + check->connection_id); +#ifdef DEBUGBUILD + if(check->recv_pipe->size > 0) { + infof(data, + "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", + check->connection_id); + } #endif - continue; + continue; + } } - } - if((needle->handler->flags&PROTOPT_SSL) != - (check->handler->flags&PROTOPT_SSL)) - /* don't do mixed SSL and non-SSL connections */ - if(!(needle->handler->protocol & check->handler->protocol)) - /* except protocols that have been upgraded via TLS */ - continue; + if((needle->handler->flags&PROTOPT_SSL) != + (check->handler->flags&PROTOPT_SSL)) + /* don't do mixed SSL and non-SSL connections */ + if(!(needle->handler->protocol & check->handler->protocol)) + /* except protocols that have been upgraded via TLS */ + continue; - if(needle->handler->flags&PROTOPT_SSL) { - if((data->set.ssl.verifypeer != check->verifypeer) || - (data->set.ssl.verifyhost != check->verifyhost)) + if(needle->handler->flags&PROTOPT_SSL) { + if((data->set.ssl.verifypeer != check->verifypeer) || + (data->set.ssl.verifyhost != check->verifyhost)) + continue; + } + + if(needle->bits.proxy != check->bits.proxy) + /* don't do mixed proxy and non-proxy connections */ continue; - } - if(needle->bits.proxy != check->bits.proxy) - /* don't do mixed proxy and non-proxy connections */ - continue; - - if(!canPipeline && check->inuse) - /* this request can't be pipelined but the checked connection is already - in use so we skip it */ - continue; - - if(needle->localdev || needle->localport) { - /* If we are bound to a specific local end (IP+port), we must not re-use - a random other one, although if we didn't ask for a particular one we - can reuse one that was bound. - - This comparison is a bit rough and too strict. Since the input - parameters can be specified in numerous ways and still end up the - same it would take a lot of processing to make it really accurate. - Instead, this matching will assume that re-uses of bound connections - will most likely also re-use the exact same binding parameters and - missing out a few edge cases shouldn't hurt anyone very much. - */ - if((check->localport != needle->localport) || - (check->localportrange != needle->localportrange) || - !check->localdev || - !needle->localdev || - strcmp(check->localdev, needle->localdev)) + if(!canPipeline && check->inuse) + /* this request can't be pipelined but the checked connection is + already in use so we skip it */ continue; - } - if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL || - (needle->bits.httpproxy && check->bits.httpproxy && - needle->bits.tunnel_proxy && check->bits.tunnel_proxy && - Curl_raw_equal(needle->proxy.name, check->proxy.name) && - (needle->port == check->port))) { - /* The requested connection does not use a HTTP proxy or it uses SSL or - it is a non-SSL protocol tunneled over the same http proxy name and - port number or it is a non-SSL protocol which is allowed to be - upgraded via TLS */ - - if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) || - needle->handler->protocol & check->handler->protocol) && - Curl_raw_equal(needle->host.name, check->host.name) && - needle->remote_port == check->remote_port) { - if(needle->handler->flags & PROTOPT_SSL) { - /* This is a SSL connection so verify that we're using the same - SSL options as well */ - if(!Curl_ssl_config_matches(&needle->ssl_config, - &check->ssl_config)) { - DEBUGF(infof(data, - "Connection #%ld has different SSL parameters, " - "can't reuse\n", - check->connectindex)); - continue; - } - else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) { - DEBUGF(infof(data, - "Connection #%ld has not started SSL connect, " - "can't reuse\n", - check->connectindex)); - continue; + if(needle->localdev || needle->localport) { + /* If we are bound to a specific local end (IP+port), we must not + re-use a random other one, although if we didn't ask for a + particular one we can reuse one that was bound. + + This comparison is a bit rough and too strict. Since the input + parameters can be specified in numerous ways and still end up the + same it would take a lot of processing to make it really accurate. + Instead, this matching will assume that re-uses of bound connections + will most likely also re-use the exact same binding parameters and + missing out a few edge cases shouldn't hurt anyone very much. + */ + if((check->localport != needle->localport) || + (check->localportrange != needle->localportrange) || + !check->localdev || + !needle->localdev || + strcmp(check->localdev, needle->localdev)) + continue; + } + + if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL || + (needle->bits.httpproxy && check->bits.httpproxy && + needle->bits.tunnel_proxy && check->bits.tunnel_proxy && + Curl_raw_equal(needle->proxy.name, check->proxy.name) && + (needle->port == check->port))) { + /* The requested connection does not use a HTTP proxy or it uses SSL or + it is a non-SSL protocol tunneled over the same http proxy name and + port number or it is a non-SSL protocol which is allowed to be + upgraded via TLS */ + + if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) || + needle->handler->protocol & check->handler->protocol) && + Curl_raw_equal(needle->host.name, check->host.name) && + needle->remote_port == check->remote_port) { + if(needle->handler->flags & PROTOPT_SSL) { + /* This is a SSL connection so verify that we're using the same + SSL options as well */ + if(!Curl_ssl_config_matches(&needle->ssl_config, + &check->ssl_config)) { + DEBUGF(infof(data, + "Connection #%ld has different SSL parameters, " + "can't reuse\n", + check->connection_id)); + continue; + } + else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) { + DEBUGF(infof(data, + "Connection #%ld has not started SSL connect, " + "can't reuse\n", + check->connection_id)); + continue; + } } - } - if((needle->handler->protocol & CURLPROTO_FTP) || - ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) { - /* This is FTP or HTTP+NTLM, verify that we're using the same name - and password as well */ - if(!strequal(needle->user, check->user) || - !strequal(needle->passwd, check->passwd)) { - /* one of them was different */ - continue; + if((needle->handler->protocol & CURLPROTO_FTP) || + ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) { + /* This is FTP or HTTP+NTLM, verify that we're using the same name + and password as well */ + if(!strequal(needle->user, check->user) || + !strequal(needle->passwd, check->passwd)) { + /* one of them was different */ + continue; + } + credentialsMatch = TRUE; } - credentialsMatch = TRUE; + match = TRUE; } - match = TRUE; } - } - else { /* The requested needle connection is using a proxy, - is the checked one using the same host, port and type? */ - if(check->bits.proxy && - (needle->proxytype == check->proxytype) && - (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) && - Curl_raw_equal(needle->proxy.name, check->proxy.name) && - needle->port == check->port) { - /* This is the same proxy connection, use it! */ - match = TRUE; + else { /* The requested needle connection is using a proxy, + is the checked one using the same host, port and type? */ + if(check->bits.proxy && + (needle->proxytype == check->proxytype) && + (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) && + Curl_raw_equal(needle->proxy.name, check->proxy.name) && + needle->port == check->port) { + /* This is the same proxy connection, use it! */ + match = TRUE; + } } - } - if(match) { - chosen = check; + if(match) { + chosen = check; - /* If we are not looking for an NTLM connection, we can choose this one - immediately. */ - if(!wantNTLM) - break; + /* If we are not looking for an NTLM connection, we can choose this one + immediately. */ + if(!wantNTLM) + break; - /* Otherwise, check if this is already authenticating with the right - credentials. If not, keep looking so that we can reuse NTLM - connections if possible. (Especially we must reuse the same - connection if partway through a handshake!) */ - if(credentialsMatch && chosen->ntlm.state != NTLMSTATE_NONE) - break; + /* Otherwise, check if this is already authenticating with the right + credentials. If not, keep looking so that we can reuse NTLM + connections if possible. (Especially we must reuse the same + connection if partway through a handshake!) */ + if(credentialsMatch && chosen->ntlm.state != NTLMSTATE_NONE) + break; + } } } @@ -3170,53 +2983,67 @@ ConnectionExists(struct SessionHandle *data, return FALSE; /* no matching connecting exists */ } - - /* * This function kills and removes an existing connection in the connection * cache. The connection that has been unused for the longest time. * - * Returns -1 if it can't find any unused connection to kill. + * Returns FALSE if it can't find any unused connection to kill. */ -static long +static bool ConnectionKillOne(struct SessionHandle *data) { - long i; - struct connectdata *conn; + struct conncache *bc = data->state.conn_cache; + struct curl_hash_iterator iter; + struct curl_llist_element *curr; + struct curl_hash_element *he; long highscore=-1; - long connindex=-1; long score; struct timeval now; + struct connectdata *conn_candidate = NULL; + struct connectbundle *bundle; now = Curl_tvnow(); - for(i=0; data->state.connc && (i< data->state.connc->num); i++) { - conn = data->state.connc->connects[i]; + Curl_hash_start_iterate(bc->hash, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + struct connectdata *conn; + + bundle = he->ptr; - if(!conn || conn->inuse) - continue; + curr = bundle->conn_list->head; + while(curr) { + conn = curr->ptr; - /* Set higher score for the age passed since the connection was used */ - score = Curl_tvdiff(now, conn->now); + if(!conn->inuse) { + /* Set higher score for the age passed since the connection was used */ + score = Curl_tvdiff(now, conn->now); - if(score > highscore) { - highscore = score; - connindex = i; + if(score > highscore) { + highscore = score; + conn_candidate = conn; + } + } + curr = curr->next; } + + he = Curl_hash_next_element(&iter); } - if(connindex >= 0) { + + if(conn_candidate) { /* Set the connection's owner correctly */ - conn = data->state.connc->connects[connindex]; - conn->data = data; + conn_candidate->data = data; + + bundle = conn_candidate->bundle; /* the winner gets the honour of being disconnected */ - (void)Curl_disconnect(conn, /* dead_connection */ FALSE); + (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); - /* clean the array entry */ - data->state.connc->connects[connindex] = NULL; + return TRUE; } - return connindex; /* return the available index or -1 */ + return FALSE; } /* this connection can now be marked 'idle' */ @@ -3234,41 +3061,16 @@ ConnectionDone(struct connectdata *conn) * The given connection should be unique. That must've been checked prior to * this call. */ -static void ConnectionStore(struct SessionHandle *data, - struct connectdata *conn) +static CURLcode ConnectionStore(struct SessionHandle *data, + struct connectdata *conn) { - long i; - for(i=0; i< data->state.connc->num; i++) { - if(!data->state.connc->connects[i]) - break; - } - if(i == data->state.connc->num) { - /* there was no room available, kill one */ - i = ConnectionKillOne(data); - if(-1 != i) - infof(data, "Connection (#%ld) was killed to make room (holds %ld)\n", - i, data->state.connc->num); - else - infof(data, "This connection did not fit in the connection cache\n"); - } + static int connection_id_counter = 0; - conn->connectindex = i; /* Make the child know where the pointer to this - particular data is stored. But note that this -1 - if this is not within the cache and this is - probably not checked for everywhere (yet). */ - conn->inuse = TRUE; - if(-1 != i) { - /* Only do this if a true index was returned, if -1 was returned there - is no room in the cache for an unknown reason and we cannot store - this there. - - TODO: make sure we really can work with more handles than positions in - the cache, or possibly we should (allow to automatically) resize the - connection cache when we add more easy handles to a multi handle! - */ - data->state.connc->connects[i] = conn; /* fill in this */ - conn->data = data; - } + /* Assign a number to the connection for easier tracking in the log + output */ + conn->connection_id = connection_id_counter++; + + return Curl_conncache_add_conn(data->state.conn_cache, conn); } /* after a TCP connection to the proxy has been verified, this function does @@ -3318,7 +3120,7 @@ static CURLcode ConnectPlease(struct SessionHandle *data, infof(data, "About to connect() to %s%s port %ld (#%ld)\n", conn->bits.proxy?"proxy ":"", - hostname, conn->port, conn->connectindex); + hostname, conn->port, conn->connection_id); #else (void)data; #endif @@ -3359,7 +3161,7 @@ void Curl_verboseconnect(struct connectdata *conn) if(conn->data->set.verbose) infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, - conn->ip_addr_str, conn->port, conn->connectindex); + conn->ip_addr_str, conn->port, conn->connection_id); } #endif @@ -3618,7 +3420,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->connectindex = -1; /* no index */ + conn->connection_id = -1; /* no ID */ conn->port = -1; /* unknown at this point */ /* Default protocol-independent behavior doesn't support persistent @@ -4898,7 +4700,7 @@ static CURLcode create_conn(struct SessionHandle *data, urllen=LEAST_PATH_ALLOC; /* - * We malloc() the buffers below urllen+2 to make room for to possibilities: + * We malloc() the buffers below urllen+2 to make room for 2 possibilities: * 1 - an extra terminating zero * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) */ @@ -4960,8 +4762,8 @@ static CURLcode create_conn(struct SessionHandle *data, /* according to rfc3986, allow the query (?foo=bar) also on protocols that can't handle it. - cut the string-part after '?' - */ + cut the string-part after '?' + */ /* terminate the string */ path_q_sep[0] = 0; @@ -4975,7 +4777,7 @@ static CURLcode create_conn(struct SessionHandle *data, if(conn->bits.proxy_user_passwd) { result = parse_proxy_auth(data, conn); if(result != CURLE_OK) - return result; + return result; } /************************************************************* @@ -5178,7 +4980,7 @@ static CURLcode create_conn(struct SessionHandle *data, fix_hostname(data, conn, &conn->host); infof(data, "Re-using existing connection! (#%ld) with host %s\n", - conn->connectindex, + conn->connection_id, conn->proxy.name?conn->proxy.dispname:conn->host.dispname); } else { @@ -5443,12 +5245,8 @@ CURLcode Curl_done(struct connectdata **connp, state it is for re-using, so we're forced to close it. In a perfect world we can add code that keep track of if we really must close it here or not, but currently we have no such detail knowledge. - - connectindex == -1 here means that the connection has no spot in the - connection cache and thus we must disconnect it here. */ - if(data->set.reuse_forbid || conn->bits.close || premature || - (-1 == conn->connectindex)) { + if(data->set.reuse_forbid || conn->bits.close || premature) { CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */ /* If we had an error already, make sure we return that one. But @@ -5460,10 +5258,10 @@ CURLcode Curl_done(struct connectdata **connp, ConnectionDone(conn); /* the connection is no longer in use */ /* remember the most recently used connection */ - data->state.lastconnect = conn->connectindex; + data->state.lastconnect = conn; infof(data, "Connection #%ld to host %s left intact\n", - conn->connectindex, + conn->connection_id, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); } -- cgit v1.2.1 From 4675ab7c81e2bea5f4d15fc2ea4bad29f3d4b0a4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Nov 2012 23:06:10 +0100 Subject: internals: always use multi interface internally curl_easy_perform() is now just a wrapper-function that uses multi functions to achieve its functionality. All internals are all non-blocking and multi interface friendly. No more two different behaviors depending on which interface that is used. --- lib/url.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/url.c') diff --git a/lib/url.c b/lib/url.c index 574751716..6a3fc4735 100644 --- a/lib/url.c +++ b/lib/url.c @@ -387,6 +387,11 @@ CURLcode Curl_close(struct SessionHandle *data) and detach this handle from there. */ curl_multi_remove_handle(data->multi, data); + if(data->multi_easy) + /* when curl_easy_perform() is used, it creates its own multi handle to + use and this is the one */ + curl_multi_cleanup(data->multi_easy); + /* Destroy the timeout list that is held in the easy handle. It is /normally/ done by curl_multi_remove_handle() but this is "just in case" */ -- cgit v1.2.1