# endif
#endif
-#ifdef WINDOWS
-# include <winsock.h>
-#else
-# include <netdb.h> /* for h_errno */
-#endif
-
#include "wget.h"
#include "utils.h"
#include "url.h"
#include "connect.h"
#include "fnmatch.h"
#include "netrc.h"
-#if USE_DIGEST
-# include "md5.h"
-#endif
#ifdef HAVE_SSL
# include "gen_sslfunc.h"
#endif /* HAVE_SSL */
#include "cookies.h"
+#ifdef USE_DIGEST
+# include "gen-md5.h"
+#endif
extern char *version_string;
#ifndef errno
extern int errno;
#endif
-#ifndef h_errno
-# ifndef __CYGWIN__
-extern int h_errno;
-# endif
-#endif
\f
static int cookies_loaded_p;
if (!strncasecmp (hdr, "bytes", 5))
{
hdr += 5;
+ /* "JavaWebServer/1.1.1" sends "bytes: x-y/z", contrary to the
+ HTTP spec. */
+ if (*hdr == ':')
+ ++hdr;
hdr += skip_lws (hdr);
if (!*hdr)
return 0;
/* Whether a persistent connection is active. */
static int pc_active_p;
/* Host and port of currently active persistent connection. */
-static unsigned char pc_last_host[4];
+static struct address_list *pc_last_host_ip;
static unsigned short pc_last_port;
/* File descriptor of the currently active persistent connection. */
#ifdef HAVE_SSL
pc_active_ssl = 0;
#endif /* HAVE_SSL */
+ if (pc_last_host_ip != NULL)
+ {
+ address_list_release (pc_last_host_ip);
+ pc_last_host_ip = NULL;
+ }
DEBUGP (("Invalidating fd %d from further reuse.\n", pc_last_fd));
}
#endif
)
{
- int success;
-
if (pc_active_p)
{
if (pc_last_fd == fd)
}
}
- /* This store_hostaddress may not fail, because it has the results
- in the cache. */
- success = store_hostaddress (pc_last_host, host);
- assert (success);
+ assert (pc_last_host_ip == NULL);
+
+ /* This lookup_host cannot fail, because it has the results in the
+ cache. */
+ pc_last_host_ip = lookup_host (host, 1);
+ assert (pc_last_host_ip != NULL);
+
pc_last_port = port;
pc_last_fd = fd;
pc_active_p = 1;
DEBUGP (("Registered fd %d for persistent reuse.\n", fd));
}
+#ifdef HAVE_SSL
+# define SHUTDOWN_SSL(ssl) do { \
+ if (ssl) \
+ shutdown_ssl (ssl); \
+} while (0)
+#else
+# define SHUTDOWN_SSL(ssl)
+#endif
+
/* Return non-zero if a persistent connection is available for
connecting to HOST:PORT. */
#endif
)
{
- unsigned char this_host[4];
+ int success;
+ struct address_list *this_host_ip;
+
/* First, check whether a persistent connection is active at all. */
if (!pc_active_p)
return 0;
(HOST, PORT) ordered pair. */
if (port != pc_last_port)
return 0;
+
#ifdef HAVE_SSL
/* Second, a): check if current connection is (not) ssl, too. This
test is unlikely to fail because HTTP and HTTPS typicaly use
if (ssl != pc_active_ssl)
return 0;
#endif /* HAVE_SSL */
- if (!store_hostaddress (this_host, host))
+
+ this_host_ip = lookup_host (host, 1);
+ if (!this_host_ip)
return 0;
- if (memcmp (pc_last_host, this_host, 4))
+
+ /* To equate the two host names for the purposes of persistent
+ connections, they need to share all the IP addresses in the
+ list. */
+ success = address_list_match_all (pc_last_host_ip, this_host_ip);
+ address_list_release (this_host_ip);
+ if (!success)
return 0;
+
/* Third: check whether the connection is still open. This is
important because most server implement a liberal (short) timeout
on persistent connections. Wget can of course always reconnect
let's invalidate the persistent connection before returning
0. */
CLOSE (pc_last_fd);
+#ifdef HAVE_SSL
+ SHUTDOWN_SSL (pc_last_ssl);
+ pc_last_ssl = NULL;
+#endif
invalidate_persistent ();
return 0;
}
return 1;
}
-#ifdef HAVE_SSL
-# define SHUTDOWN_SSL(ssl) do { \
- if (ssl) \
- shutdown_ssl (ssl); \
-} while (0)
-#else
-# define SHUTDOWN_SSL(ssl)
-#endif
-
/* The idea behind these two CLOSE macros is to distinguish between
two cases: one when the job we've been doing is finished, and we
want to close the connection and leave, and two when something is
long dltime; /* time of the download */
int no_truncate; /* whether truncating the file is
forbidden. */
+ const char *referer; /* value of the referer header. */
+ char **local_file; /* local file. */
};
-/* Free the elements of hstat X. */
-#define FREEHSTAT(x) do \
-{ \
- FREE_MAYBE ((x).newloc); \
- FREE_MAYBE ((x).remote_time); \
- FREE_MAYBE ((x).error); \
- (x).newloc = (x).remote_time = (x).error = NULL; \
-} while (0)
+static void
+free_hstat (struct http_stat *hs)
+{
+ FREE_MAYBE (hs->newloc);
+ FREE_MAYBE (hs->remote_time);
+ FREE_MAYBE (hs->error);
+
+ /* Guard against being called twice. */
+ hs->newloc = NULL;
+ hs->remote_time = NULL;
+ hs->error = NULL;
+}
static char *create_authorization_line PARAMS ((const char *, const char *,
const char *, const char *,
response code correctly, it is not used in a sane way. The caller
can do that, though.
- If u->proxy is non-NULL, the URL u will be taken as a proxy URL,
- and u->proxy->url will be given to the proxy server (bad naming,
- I'm afraid). */
+ If PROXY is non-NULL, the connection will be made to the proxy
+ server, and u->url will be requested. */
static uerr_t
-gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
+gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
{
- char *request, *type, *command, *path;
+ char *request, *type, *command, *full_path;
char *user, *passwd;
- char *pragma_h, *referer, *useragent, *range, *wwwauth, *remhost;
+ char *pragma_h, *referer, *useragent, *range, *wwwauth;
char *authenticate_h;
char *proxyauth;
char *all_headers;
char *port_maybe;
char *request_keep_alive;
- int sock, hcount, num_written, all_length, remport, statcode;
+ int sock, hcount, num_written, all_length, statcode;
long contlen, contrange;
- struct urlinfo *ou;
- uerr_t err;
+ struct url *conn;
FILE *fp;
int auth_tried_already;
struct rbuf rbuf;
static SSL_CTX *ssl_ctx = NULL;
SSL *ssl = NULL;
#endif /* HAVE_SSL */
- struct wget_timer *timer;
char *cookies = NULL;
/* Whether this connection will be kept alive after the HTTP request
/* initialize ssl_ctx on first run */
if (!ssl_ctx)
{
- err=init_ssl (&ssl_ctx);
+ uerr_t err = init_ssl (&ssl_ctx);
if (err != 0)
{
switch (err)
if (!(*dt & HEAD_ONLY))
/* If we're doing a GET on the URL, as opposed to just a HEAD, we need to
know the local filename so we can save to it. */
- assert (u->local != NULL);
+ assert (*hs->local_file != NULL);
authenticate_h = 0;
auth_tried_already = 0;
- inhibit_keep_alive = (!opt.http_keep_alive || u->proxy != NULL);
+ inhibit_keep_alive = !opt.http_keep_alive || proxy != NULL;
again:
/* We need to come back here when the initial attempt to retrieve
hs->remote_time = NULL;
hs->error = NULL;
- /* Which structure to use to retrieve the original URL data. */
- if (u->proxy)
- ou = u->proxy;
- else
- ou = u;
+ /* If we're using a proxy, we will be connecting to the proxy
+ server. */
+ conn = proxy ? proxy : u;
/* First: establish the connection. */
if (inhibit_keep_alive
||
#ifndef HAVE_SSL
- !persistent_available_p (u->host, u->port)
+ !persistent_available_p (conn->host, conn->port)
#else
- !persistent_available_p (u->host, u->port, (u->proto==URLHTTPS ? 1 : 0))
+ !persistent_available_p (conn->host, conn->port,
+ u->scheme == SCHEME_HTTPS)
#endif /* HAVE_SSL */
)
{
- logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
- err = make_connection (&sock, u->host, u->port);
- switch (err)
- {
- case HOSTERR:
- logputs (LOG_VERBOSE, "\n");
- logprintf (LOG_NOTQUIET, "%s: %s.\n", u->host, herrmsg (h_errno));
- return HOSTERR;
- break;
- case CONSOCKERR:
- logputs (LOG_VERBOSE, "\n");
- logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
- return CONSOCKERR;
- break;
- case CONREFUSED:
- logputs (LOG_VERBOSE, "\n");
- logprintf (LOG_NOTQUIET,
- _("Connection to %s:%hu refused.\n"), u->host, u->port);
- CLOSE (sock);
- return CONREFUSED;
- case CONERROR:
- logputs (LOG_VERBOSE, "\n");
- logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
- CLOSE (sock);
- return CONERROR;
- break;
- case NOCONERROR:
- /* Everything is fine! */
- logputs (LOG_VERBOSE, _("connected!\n"));
- break;
- default:
- abort ();
- break;
- }
+ struct address_list *al = lookup_host (conn->host, 0);
+ if (!al)
+ return HOSTERR;
+ set_connection_host_name (conn->host);
+ sock = connect_to_many (al, conn->port, 0);
+ set_connection_host_name (NULL);
+ address_list_release (al);
+
+ if (sock < 0)
+ return errno == ECONNREFUSED ? CONREFUSED : CONERROR;
+
#ifdef HAVE_SSL
- if (u->proto == URLHTTPS)
+ if (conn->scheme == SCHEME_HTTPS)
if (connect_ssl (&ssl, ssl_ctx,sock) != 0)
{
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
+ ssl_printerrors ();
CLOSE (sock);
return CONSSLERR;
}
}
else
{
- logprintf (LOG_VERBOSE, _("Reusing connection to %s:%hu.\n"), u->host, u->port);
+ logprintf (LOG_VERBOSE, _("Reusing connection to %s:%hu.\n"),
+ conn->host, conn->port);
/* #### pc_last_fd should be accessed through an accessor
function. */
sock = pc_last_fd;
DEBUGP (("Reusing fd %d.\n", sock));
}
- if (u->proxy)
- path = u->proxy->url;
- else
- path = u->path;
-
command = (*dt & HEAD_ONLY) ? "HEAD" : "GET";
+
referer = NULL;
- if (ou->referer)
+ if (hs->referer)
{
- referer = (char *)alloca (9 + strlen (ou->referer) + 3);
- sprintf (referer, "Referer: %s\r\n", ou->referer);
+ referer = (char *)alloca (9 + strlen (hs->referer) + 3);
+ sprintf (referer, "Referer: %s\r\n", hs->referer);
}
+
if (*dt & SEND_NOCACHE)
pragma_h = "Pragma: no-cache\r\n";
else
pragma_h = "";
+
if (hs->restval)
{
range = (char *)alloca (13 + numdigit (hs->restval) + 4);
sprintf (useragent, "Wget/%s", version_string);
}
/* Construct the authentication, if userid is present. */
- user = ou->user;
- passwd = ou->passwd;
- search_netrc (ou->host, (const char **)&user, (const char **)&passwd, 0);
+ user = u->user;
+ passwd = u->passwd;
+ search_netrc (u->host, (const char **)&user, (const char **)&passwd, 0);
user = user ? user : opt.http_user;
passwd = passwd ? passwd : opt.http_passwd;
}
else
{
+ /* Use the full path, i.e. one that includes the leading
+ slash and the query string, but is independent of proxy
+ setting. */
+ char *pth = url_full_path (u);
wwwauth = create_authorization_line (authenticate_h, user, passwd,
- command, ou->path);
+ command, pth);
+ xfree (pth);
}
}
proxyauth = NULL;
- if (u->proxy)
+ if (proxy)
{
char *proxy_user, *proxy_passwd;
/* For normal username and password, URL components override
}
else
{
- proxy_user = u->user;
- proxy_passwd = u->passwd;
+ proxy_user = proxy->user;
+ proxy_passwd = proxy->passwd;
}
- /* #### This is junky. Can't the proxy request, say, `Digest'
- authentication? */
+ /* #### This does not appear right. Can't the proxy request,
+ say, `Digest' authentication? */
if (proxy_user && proxy_passwd)
proxyauth = basic_authentication_encode (proxy_user, proxy_passwd,
"Proxy-Authorization");
}
- remhost = ou->host;
- remport = ou->port;
/* String of the form :PORT. Used only for non-standard ports. */
port_maybe = NULL;
- if (1
-#ifdef HAVE_SSL
- && remport != (u->proto == URLHTTPS
- ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT)
-#else
- && remport != DEFAULT_HTTP_PORT
-#endif
- )
+ if (u->port != scheme_default_port (u->scheme))
{
- port_maybe = (char *)alloca (numdigit (remport) + 2);
- sprintf (port_maybe, ":%d", remport);
+ port_maybe = (char *)alloca (numdigit (u->port) + 2);
+ sprintf (port_maybe, ":%d", u->port);
}
if (!inhibit_keep_alive)
request_keep_alive = NULL;
if (opt.cookies)
- cookies = build_cookies_request (ou->host, ou->port, ou->path,
- ou->proto == URLHTTPS);
+ cookies = build_cookies_request (u->host, u->port, u->path,
+#ifdef HAVE_SSL
+ u->scheme == SCHEME_HTTPS
+#else
+ 0
+#endif
+ );
+
+ if (proxy)
+ full_path = xstrdup (u->url);
+ else
+ /* Use the full path, i.e. one that includes the leading slash and
+ the query string. E.g. if u->path is "foo/bar" and u->query is
+ "param=value", full_path will be "/foo/bar?param=value". */
+ full_path = url_full_path (u);
/* Allocate the memory for the request. */
- request = (char *)alloca (strlen (command) + strlen (path)
+ request = (char *)alloca (strlen (command)
+ + strlen (full_path)
+ strlen (useragent)
- + strlen (remhost)
+ + strlen (u->host)
+ (port_maybe ? strlen (port_maybe) : 0)
+ strlen (HTTP_ACCEPT)
+ (request_keep_alive
Host: %s%s\r\n\
Accept: %s\r\n\
%s%s%s%s%s%s%s%s\r\n",
- command, path, useragent, remhost,
+ command, full_path,
+ useragent, u->host,
port_maybe ? port_maybe : "",
HTTP_ACCEPT,
request_keep_alive ? request_keep_alive : "",
pragma_h,
opt.user_header ? opt.user_header : "");
DEBUGP (("---request begin---\n%s---request end---\n", request));
- /* Free the temporary memory. */
+
+ /* Free the temporary memory. */
FREE_MAYBE (wwwauth);
FREE_MAYBE (proxyauth);
FREE_MAYBE (cookies);
+ xfree (full_path);
/* Send the request to server. */
#ifdef HAVE_SSL
- if (u->proto == URLHTTPS)
+ if (conn->scheme == SCHEME_HTTPS)
num_written = ssl_iwrite (ssl, request, strlen (request));
else
#endif /* HAVE_SSL */
return WRITEFAILED;
}
logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "),
- u->proxy ? "Proxy" : "HTTP");
+ proxy ? "Proxy" : "HTTP");
contlen = contrange = -1;
type = NULL;
statcode = -1;
/* Before reading anything, initialize the rbuf. */
rbuf_initialize (&rbuf, sock);
#ifdef HAVE_SSL
- if (u->proto == URLHTTPS)
+ if (conn->scheme == SCHEME_HTTPS)
rbuf.ssl = ssl;
else
rbuf.ssl = NULL;
all_headers[all_length] = '\0';
}
- /* Print the header if requested. */
- if (opt.server_response && hcount != 1)
- logprintf (LOG_VERBOSE, "\n%d %s", hcount, hdr);
-
/* Check for status line. */
if (hcount == 1)
{
&& !opt.debug
#endif
)
- logprintf (LOG_VERBOSE, "%d %s", statcode, error);
+ {
+ if (opt.server_response)
+ logprintf (LOG_VERBOSE, "\n%2d %s", hcount, hdr);
+ else
+ logprintf (LOG_VERBOSE, "%2d %s", statcode, error);
+ }
goto done_header;
}
break;
}
+ /* Print the header if requested. */
+ if (opt.server_response && hcount != 1)
+ logprintf (LOG_VERBOSE, "\n%2d %s", hcount, hdr);
+
/* Try getting content-length. */
if (contlen == -1 && !opt.ignore_length)
if (header_process (hdr, "Content-Length", header_extract_number,
/* The server has promised that it will not close the connection
when we're done. This means that we can register it. */
#ifndef HAVE_SSL
- register_persistent (u->host, u->port, sock);
+ register_persistent (conn->host, conn->port, sock);
#else
- register_persistent (u->host, u->port, sock, ssl);
+ register_persistent (conn->host, conn->port, sock, ssl);
#endif /* HAVE_SSL */
if ((statcode == HTTP_STATUS_UNAUTHORIZED)
/* Authorization is required. */
FREE_MAYBE (type);
type = NULL;
- FREEHSTAT (*hs);
+ free_hstat (hs);
CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
might be more bytes in the body. */
if (auth_tried_already)
text/html file. If some case-insensitive variation on ".htm[l]" isn't
already the file's suffix, tack on ".html". */
{
- char* last_period_in_local_filename = strrchr(u->local, '.');
+ char* last_period_in_local_filename = strrchr(*hs->local_file, '.');
if (last_period_in_local_filename == NULL ||
!(strcasecmp(last_period_in_local_filename, ".htm") == EQ ||
strcasecmp(last_period_in_local_filename, ".html") == EQ))
{
- size_t local_filename_len = strlen(u->local);
+ size_t local_filename_len = strlen(*hs->local_file);
- u->local = xrealloc(u->local, local_filename_len + sizeof(".html"));
- strcpy(u->local + local_filename_len, ".html");
+ *hs->local_file = xrealloc(*hs->local_file,
+ local_filename_len + sizeof(".html"));
+ strcpy(*hs->local_file + local_filename_len, ".html");
*dt |= ADDED_HTML_EXTENSION;
}
_("\
\n\
Continued download failed on this file, which conflicts with `-c'.\n\
-Refusing to truncate existing file `%s'.\n\n"), u->local);
+Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
FREE_MAYBE (type);
FREE_MAYBE (all_headers);
CLOSE_INVALIDATE (sock);
/* Open the local file. */
if (!opt.dfp)
{
- mkalldirs (u->local);
+ mkalldirs (*hs->local_file);
if (opt.backups)
- rotate_backups (u->local);
- fp = fopen (u->local, hs->restval ? "ab" : "wb");
+ rotate_backups (*hs->local_file);
+ fp = fopen (*hs->local_file, hs->restval ? "ab" : "wb");
if (!fp)
{
- logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
+ logprintf (LOG_NOTQUIET, "%s: %s\n", *hs->local_file, strerror (errno));
CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
might be more bytes in the body. */
FREE_MAYBE (all_headers);
should be some overhead information. */
if (opt.save_headers)
fwrite (all_headers, 1, all_length, fp);
- timer = wtimer_new ();
+
/* Get the contents of the document. */
hs->res = get_contents (sock, fp, &hs->len, hs->restval,
(contlen != -1 ? contlen : 0),
- &rbuf, keep_alive);
- hs->dltime = wtimer_elapsed (timer);
- wtimer_delete (timer);
+ &rbuf, keep_alive, &hs->dltime);
+
{
/* Close or flush the file. We have to be careful to check for
error here. Checking the result of fwrite() is not enough --
/* The genuine HTTP loop! This is the part where the retrieval is
retried, and retried, and retried, and... */
uerr_t
-http_loop (struct urlinfo *u, char **newloc, int *dt)
+http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
+ int *dt, struct url *proxy)
{
int count;
int use_ts, got_head = 0; /* time-stamping info */
size_t filename_len;
struct http_stat hstat; /* HTTP status */
struct stat st;
+ char *dummy = NULL;
/* This used to be done in main(), but it's a better idea to do it
here so that we don't go through the hoops if we're just using
logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
/* Determine the local filename. */
- if (!u->local)
- u->local = url_filename (u->proxy ? u->proxy : u);
+ if (local_file && *local_file)
+ hstat.local_file = local_file;
+ else if (local_file)
+ {
+ *local_file = url_filename (u);
+ hstat.local_file = local_file;
+ }
+ else
+ {
+ dummy = url_filename (u);
+ hstat.local_file = &dummy;
+ }
if (!opt.output_document)
- locf = u->local;
+ locf = *hstat.local_file;
else
locf = opt.output_document;
- filename_len = strlen (u->local);
+ hstat.referer = referer;
+
+ filename_len = strlen (*hstat.local_file);
filename_plus_orig_suffix = alloca (filename_len + sizeof (".orig"));
- if (opt.noclobber && file_exists_p (u->local))
+ if (opt.noclobber && file_exists_p (*hstat.local_file))
{
/* If opt.noclobber is turned on and file already exists, do not
retrieve the file */
logprintf (LOG_VERBOSE, _("\
-File `%s' already there, will not retrieve.\n"), u->local);
+File `%s' already there, will not retrieve.\n"), *hstat.local_file);
/* If the file is there, we suppose it's retrieved OK. */
*dt |= RETROKF;
/* #### Bogusness alert. */
- /* If its suffix is "html" or (yuck!) "htm", we suppose it's
- text/html, a harmless lie. */
- if (((suf = suffix (u->local)) != NULL)
+ /* If its suffix is "html" or "htm", assume text/html. */
+ if (((suf = suffix (*hstat.local_file)) != NULL)
&& (!strcmp (suf, "html") || !strcmp (suf, "htm")))
*dt |= TEXTHTML;
- xfree (suf);
- /* Another harmless lie: */
+
+ FREE_MAYBE (dummy);
return RETROK;
}
in url.c. Replacing sprintf with inline calls to
strcpy() and long_to_string() made a difference.
--hniksic */
- memcpy (filename_plus_orig_suffix, u->local, filename_len);
+ memcpy (filename_plus_orig_suffix, *hstat.local_file, filename_len);
memcpy (filename_plus_orig_suffix + filename_len,
".orig", sizeof (".orig"));
if (!local_dot_orig_file_exists)
/* Couldn't stat() <file>.orig, so try to stat() <file>. */
- if (stat (u->local, &st) == 0)
- local_filename = u->local;
+ if (stat (*hstat.local_file, &st) == 0)
+ local_filename = *hstat.local_file;
if (local_filename != NULL)
/* There was a local file, so we'll check later to see if the version
/* Print fetch message, if opt.verbose. */
if (opt.verbose)
{
- char *hurl = str_url (u->proxy ? u->proxy : u, 1);
+ char *hurl = url_string (u, 1);
char tmp[15];
strcpy (tmp, " ");
if (count > 1)
Some proxies are notorious for caching incomplete data, so
we require a fresh get.
b) caching is explicitly inhibited. */
- if ((u->proxy && count > 1) /* a */
- || !opt.allow_cache /* b */
+ if ((proxy && count > 1) /* a */
+ || !opt.allow_cache /* b */
)
*dt |= SEND_NOCACHE;
else
*dt &= ~SEND_NOCACHE;
- /* Try fetching the document, or at least its head. :-) */
- err = gethttp (u, &hstat, dt);
+ /* Try fetching the document, or at least its head. */
+ err = gethttp (u, &hstat, dt, proxy);
/* It's unfortunate that wget determines the local filename before finding
out the Content-Type of the file. Barring a major restructuring of the
code, we need to re-set locf here, since gethttp() may have xrealloc()d
- u->local to tack on ".html". */
+ *hstat.local_file to tack on ".html". */
if (!opt.output_document)
- locf = u->local;
+ locf = *hstat.local_file;
else
locf = opt.output_document;
/* Non-fatal errors continue executing the loop, which will
bring them to "while" statement at the end, to judge
whether the number of tries was exceeded. */
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
printwhat (count, opt.ntry);
continue;
break;
case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED:
case SSLERRCTXCREATE: case CONTNOTSUPPORTED:
/* Fatal errors just return from the function. */
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return err;
break;
case FWRITEERR: case FOPENERR:
/* Another fatal error. */
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"),
- u->local, strerror (errno));
- FREEHSTAT (hstat);
+ *hstat.local_file, strerror (errno));
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return err;
break;
case CONSSLERR:
/* Another fatal error. */
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return err;
break;
case NEWLOCATION:
logprintf (LOG_NOTQUIET,
_("ERROR: Redirection (%d) without location.\n"),
hstat.statcode);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return WRONGCODE;
}
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return NEWLOCATION;
break;
case RETRUNNEEDED:
/* The file was already fully retrieved. */
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return RETROK;
break;
case RETRFINISHED:
if (!opt.verbose)
{
/* #### Ugly ugly ugly! */
- char *hurl = str_url (u->proxy ? u->proxy : u, 1);
+ char *hurl = url_string (u, 1);
logprintf (LOG_NONVERBOSE, "%s:\n", hurl);
xfree (hurl);
}
logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"),
tms, hstat.statcode, hstat.error);
logputs (LOG_VERBOSE, "\n");
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return WRONGCODE;
}
logprintf (LOG_VERBOSE, _("\
Server file no newer than local file `%s' -- not retrieving.\n\n"),
local_filename);
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return RETROK;
}
else if (tml >= tmr)
logputs (LOG_VERBOSE,
_("Remote file is newer, retrieving.\n"));
}
- FREEHSTAT (hstat);
+ free_hstat (&hstat);
continue;
}
if ((tmr != (time_t) (-1))
fl = opt.output_document;
}
else
- fl = u->local;
+ fl = *hstat.local_file;
if (fl)
touch (fl, tmr);
}
if (opt.spider)
{
logprintf (LOG_NOTQUIET, "%d %s\n\n", hstat.statcode, hstat.error);
+ FREE_MAYBE (dummy);
return RETROK;
}
- /* It is now safe to free the remainder of hstat, since the
- strings within it will no longer be used. */
- FREEHSTAT (hstat);
-
- tmrate = rate (hstat.len - hstat.restval, hstat.dltime, 0);
+ tmrate = retr_rate (hstat.len - hstat.restval, hstat.dltime, 0);
if (hstat.len == hstat.contlen)
{
else
downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return RETROK;
}
else if (hstat.res == 0) /* No read error */
else
downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return RETROK;
}
else if (hstat.len < hstat.contlen) /* meaning we lost the
_("%s (%s) - Connection closed at byte %ld. "),
tms, tmrate, hstat.len);
printwhat (count, opt.ntry);
+ free_hstat (&hstat);
continue;
}
else if (!opt.kill_longer) /* meaning we got more than expected */
else
downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
+ free_hstat (&hstat);
+ FREE_MAYBE (dummy);
return RETROK;
}
else /* the same, but not accepted */
_("%s (%s) - Connection closed at byte %ld/%ld. "),
tms, tmrate, hstat.len, hstat.contlen);
printwhat (count, opt.ntry);
+ free_hstat (&hstat);
continue;
}
}
_("%s (%s) - Read error at byte %ld (%s)."),
tms, tmrate, hstat.len, strerror (errno));
printwhat (count, opt.ntry);
+ free_hstat (&hstat);
continue;
}
else /* hstat.res == -1 and contlen is given */
tms, tmrate, hstat.len, hstat.contlen,
strerror (errno));
printwhat (count, opt.ntry);
+ free_hstat (&hstat);
continue;
}
}
/* Take the line apart to find the challenge, and compose a digest
authorization header. See RFC2069 section 2.1.2. */
-char *
+static char *
digest_authentication_encode (const char *au, const char *user,
const char *passwd, const char *method,
const char *path)
/* Calculate the digest value. */
{
- struct md5_ctx ctx;
+ ALLOCA_MD5_CONTEXT (ctx);
unsigned char hash[MD5_HASHLEN];
unsigned char a1buf[MD5_HASHLEN * 2 + 1], a2buf[MD5_HASHLEN * 2 + 1];
unsigned char response_digest[MD5_HASHLEN * 2 + 1];
/* A1BUF = H(user ":" realm ":" password) */
- md5_init_ctx (&ctx);
- md5_process_bytes (user, strlen (user), &ctx);
- md5_process_bytes (":", 1, &ctx);
- md5_process_bytes (realm, strlen (realm), &ctx);
- md5_process_bytes (":", 1, &ctx);
- md5_process_bytes (passwd, strlen (passwd), &ctx);
- md5_finish_ctx (&ctx, hash);
+ gen_md5_init (ctx);
+ gen_md5_update ((unsigned char *)user, strlen (user), ctx);
+ gen_md5_update ((unsigned char *)":", 1, ctx);
+ gen_md5_update ((unsigned char *)realm, strlen (realm), ctx);
+ gen_md5_update ((unsigned char *)":", 1, ctx);
+ gen_md5_update ((unsigned char *)passwd, strlen (passwd), ctx);
+ gen_md5_finish (ctx, hash);
dump_hash (a1buf, hash);
/* A2BUF = H(method ":" path) */
- md5_init_ctx (&ctx);
- md5_process_bytes (method, strlen (method), &ctx);
- md5_process_bytes (":", 1, &ctx);
- md5_process_bytes (path, strlen (path), &ctx);
- md5_finish_ctx (&ctx, hash);
+ gen_md5_init (ctx);
+ gen_md5_update ((unsigned char *)method, strlen (method), ctx);
+ gen_md5_update ((unsigned char *)":", 1, ctx);
+ gen_md5_update ((unsigned char *)path, strlen (path), ctx);
+ gen_md5_finish (ctx, hash);
dump_hash (a2buf, hash);
/* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */
- md5_init_ctx (&ctx);
- md5_process_bytes (a1buf, MD5_HASHLEN * 2, &ctx);
- md5_process_bytes (":", 1, &ctx);
- md5_process_bytes (nonce, strlen (nonce), &ctx);
- md5_process_bytes (":", 1, &ctx);
- md5_process_bytes (a2buf, MD5_HASHLEN * 2, &ctx);
- md5_finish_ctx (&ctx, hash);
+ gen_md5_init (ctx);
+ gen_md5_update (a1buf, MD5_HASHLEN * 2, ctx);
+ gen_md5_update ((unsigned char *)":", 1, ctx);
+ gen_md5_update ((unsigned char *)nonce, strlen (nonce), ctx);
+ gen_md5_update ((unsigned char *)":", 1, ctx);
+ gen_md5_update (a2buf, MD5_HASHLEN * 2, ctx);
+ gen_md5_finish (ctx, hash);
dump_hash (response_digest, hash);
res = (char*) xmalloc (strlen (user)
#endif /* USE_DIGEST */
return wwwauth;
}
+\f
+void
+http_cleanup (void)
+{
+ if (pc_last_host_ip)
+ address_list_release (pc_last_host_ip);
+}