X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fhttp.c;h=b8151ea2f751cbbf280aa26502478e89709b7421;hp=71706e1d1f4babe2657703721de46f2968adfef2;hb=07f60f19a4ee99ddc343bb51568b0c474e9b853d;hpb=7828e81c7905a8e9b864c7e386c9ebadcb474b82 diff --git a/src/http.c b/src/http.c index 71706e1d..b8151ea2 100644 --- a/src/http.c +++ b/src/http.c @@ -44,12 +44,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ # endif #endif -#ifdef HAVE_SSL -#include "gen_sslfunc.h" -#endif /* HAVE_SSL */ - #ifdef WINDOWS # include +#else +# include /* for h_errno */ #endif #include "wget.h" @@ -65,6 +63,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #if USE_DIGEST # include "md5.h" #endif +#ifdef HAVE_SSL +# include "gen_sslfunc.h" +#endif /* HAVE_SSL */ extern char *version_string; @@ -72,7 +73,9 @@ extern char *version_string; extern int errno; #endif #ifndef h_errno +# ifndef __CYGWIN__ extern int h_errno; +# endif #endif @@ -311,11 +314,11 @@ invalidate_persistent (void) If a previous connection was persistent, it is closed. */ static void -#ifndef HAVE_SSL -register_persistent (const char *host, unsigned short port, int fd) -#else -register_persistent (const char *host, unsigned short port, int fd, SSL* ssl) -#endif /* HAVE_SSL */ +register_persistent (const char *host, unsigned short port, int fd +#ifdef HAVE_SSL + , SSL *ssl +#endif + ) { int success; @@ -335,9 +338,11 @@ register_persistent (const char *host, unsigned short port, int fd, SSL* ssl) different host, and try to register a persistent connection to that one. */ #ifdef HAVE_SSL - /* the ssl disconnect has to take place before the closing of pc_last_fd */ - if (pc_last_ssl) shutdown_ssl(pc_last_ssl); -#endif /* HAVE_SSL */ + /* The ssl disconnect has to take place before the closing + of pc_last_fd. */ + if (pc_last_ssl) + shutdown_ssl(pc_last_ssl); +#endif CLOSE (pc_last_fd); invalidate_persistent (); } @@ -351,9 +356,9 @@ register_persistent (const char *host, unsigned short port, int fd, SSL* ssl) pc_last_fd = fd; pc_active_p = 1; #ifdef HAVE_SSL - pc_last_ssl=ssl; - pc_active_ssl= ssl ? 1 : 0; -#endif /* HAVE_SSL */ + pc_last_ssl = ssl; + pc_active_ssl = ssl ? 1 : 0; +#endif DEBUGP (("Registered fd %d for persistent reuse.\n", fd)); } @@ -361,11 +366,11 @@ register_persistent (const char *host, unsigned short port, int fd, SSL* ssl) connecting to HOST:PORT. */ static int -#ifndef HAVE_SSL -persistent_available_p (const char *host, unsigned short port) -#else -persistent_available_p (const char *host, unsigned short port,int ssl) -#endif /* HAVE_SSL */ +persistent_available_p (const char *host, unsigned short port +#ifdef HAVE_SSL + , int ssl +#endif + ) { unsigned char this_host[4]; /* First, check whether a persistent connection is active at all. */ @@ -375,6 +380,15 @@ persistent_available_p (const char *host, unsigned short port,int ssl) (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 + different ports. Yet it is possible, or so I [Christian + Fraenkel] have been told, to run HTTPS and HTTP simultaneus on + the same port. */ + if (ssl != pc_active_ssl) + return 0; +#endif /* HAVE_SSL */ if (!store_hostaddress (this_host, host)) return 0; if (memcmp (pc_last_host, this_host, 4)) @@ -394,18 +408,18 @@ persistent_available_p (const char *host, unsigned short port,int ssl) invalidate_persistent (); return 0; } -#ifdef HAVE_SSL - /* Fourth: check if current connection is (not) ssl, too. - This test is unlikely to fail because HTTP and HTTPS - typicaly use different ports. Yet it is possible (or so - I have been told) to run HTTPS and HTTP simultaneus on - the same port. */ - if (ssl!=pc_active_ssl) - return 0; -#endif /* HAVE_SSL */ 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 @@ -421,10 +435,10 @@ persistent_available_p (const char *host, unsigned short port,int ssl) `pc_active_p && (fd) == pc_last_fd' is "we're *now* using an active, registered connection". */ -#ifndef HAVE_SSL #define CLOSE_FINISH(fd) do { \ if (!keep_alive) \ { \ + SHUTDOWN_SSL (ssl); \ CLOSE (fd); \ if (pc_active_p && (fd) == pc_last_fd) \ invalidate_persistent (); \ @@ -432,30 +446,11 @@ persistent_available_p (const char *host, unsigned short port,int ssl) } while (0) #define CLOSE_INVALIDATE(fd) do { \ + SHUTDOWN_SSL (ssl); \ CLOSE (fd); \ if (pc_active_p && (fd) == pc_last_fd) \ invalidate_persistent (); \ } while (0) - -#else - -#define CLOSE_FINISH(fd,ssl) do { \ - if (!keep_alive) \ - { \ - if (ssl) shutdown_ssl(ssl); \ - CLOSE (fd); \ - if (pc_active_p && (fd) == pc_last_fd) \ - invalidate_persistent (); \ - } \ -} while (0) - -#define CLOSE_INVALIDATE(fd,ssl) do { \ - if (ssl) shutdown_ssl(ssl); \ - CLOSE (fd); \ - if (pc_active_p && (fd) == pc_last_fd) \ - invalidate_persistent (); \ -} while (0) -#endif /* HAVE_SSL */ struct http_stat { @@ -525,8 +520,8 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt) int auth_tried_already; struct rbuf rbuf; #ifdef HAVE_SSL - static SSL_CTX *ssl_ctx=NULL; - SSL *ssl=NULL; + static SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; #endif /* HAVE_SSL */ /* Whether this connection will be kept alive after the HTTP request @@ -541,8 +536,41 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt) int inhibit_keep_alive; #ifdef HAVE_SSL -/* initialize ssl_ctx on first run */ - if (!ssl_ctx) init_ssl(&ssl_ctx); + /* initialize ssl_ctx on first run */ + if (!ssl_ctx) + { + err=init_ssl (&ssl_ctx); + if (err != 0) + { + switch (err) + { + case SSLERRCTXCREATE: + /* this is fatal */ + logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n")); + ssl_printerrors (); + return err; + case SSLERRCERTFILE: + /* try without certfile */ + logprintf (LOG_NOTQUIET, + _("Failed to load certificates from %s\n"), + opt.sslcertfile); + ssl_printerrors (); + logprintf (LOG_NOTQUIET, + _("Trying without the specified certificate\n")); + break; + case SSLERRCERTKEY: + logprintf (LOG_NOTQUIET, + _("Failed to get certificate key from %s\n"), + opt.sslcertkey); + ssl_printerrors (); + logprintf (LOG_NOTQUIET, + _("Trying without the specified certificate\n")); + break; + default: + break; + } + } + } #endif /* HAVE_SSL */ if (!(*dt & HEAD_ONLY)) @@ -579,11 +607,13 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt) /* First: establish the connection. */ if (inhibit_keep_alive + || #ifndef HAVE_SSL - || !persistent_available_p (u->host, u->port)) + !persistent_available_p (u->host, u->port) #else - || !persistent_available_p (u->host, u->port, (u->proto==URLHTTPS ? 1 : 0))) + !persistent_available_p (u->host, u->port, (u->proto==URLHTTPS ? 1 : 0)) #endif /* HAVE_SSL */ + ) { logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port); err = make_connection (&sock, u->host, u->port); @@ -620,12 +650,14 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt) break; } #ifdef HAVE_SSL - if (u->proto==URLHTTPS) if (connect_ssl(&ssl,ssl_ctx,sock)!=0) { - logputs (LOG_VERBOSE, "\n"); - logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n")); - CLOSE (sock); - return CONSSLERR; - } + if (u->proto == URLHTTPS) + if (connect_ssl (&ssl, ssl_ctx,sock) != 0) + { + logputs (LOG_VERBOSE, "\n"); + logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n")); + CLOSE (sock); + return CONSSLERR; + } #endif /* HAVE_SSL */ } else @@ -798,23 +830,17 @@ Accept: %s\r\n\ /* Send the request to server. */ #ifdef HAVE_SSL - if (u->proto==URLHTTPS) { - num_written = ssl_iwrite (ssl, request, strlen (request)); - } else { -#endif /* HAVE_SSL */ - num_written = iwrite (sock, request, strlen (request)); -#ifdef HAVE_SSL - } + if (u->proto == URLHTTPS) + num_written = ssl_iwrite (ssl, request, strlen (request)); + else #endif /* HAVE_SSL */ + num_written = iwrite (sock, request, strlen (request)); + if (num_written < 0) { logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"), strerror (errno)); -#ifndef HAVE_SSL - CLOSE_INVALIDATE (sock); -#else - CLOSE_INVALIDATE (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_INVALIDATE (sock); return WRITEFAILED; } logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "), @@ -827,9 +853,10 @@ Accept: %s\r\n\ /* Before reading anything, initialize the rbuf. */ rbuf_initialize (&rbuf, sock); #ifdef HAVE_SSL - if (u->proto == URLHTTPS) { - rbuf.ssl=ssl; - } else { rbuf.ssl=NULL; } + if (u->proto == URLHTTPS) + rbuf.ssl = ssl; + else + rbuf.ssl = NULL; #endif /* HAVE_SSL */ all_headers = NULL; all_length = 0; @@ -865,11 +892,7 @@ Accept: %s\r\n\ FREE_MAYBE (type); FREE_MAYBE (hs->newloc); FREE_MAYBE (all_headers); -#ifndef HAVE_SSL - CLOSE_INVALIDATE (sock); -#else - CLOSE_INVALIDATE (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_INVALIDATE (sock); return HEOF; } else if (status == HG_ERROR) @@ -881,11 +904,7 @@ Accept: %s\r\n\ FREE_MAYBE (type); FREE_MAYBE (hs->newloc); FREE_MAYBE (all_headers); -#ifndef HAVE_SSL - CLOSE_INVALIDATE (sock); -#else - CLOSE_INVALIDATE (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_INVALIDATE (sock); return HERR; } @@ -1038,11 +1057,7 @@ Accept: %s\r\n\ FREE_MAYBE (type); type = NULL; FREEHSTAT (*hs); -#ifndef HAVE_SSL - CLOSE_FINISH (sock); -#else - CLOSE_FINISH (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_FINISH (sock); if (auth_tried_already) { /* If we have tried it already, then there is not point @@ -1118,11 +1133,7 @@ Accept: %s\r\n\ FREE_MAYBE (type); FREE_MAYBE (hs->newloc); FREE_MAYBE (all_headers); -#ifndef HAVE_SSL - CLOSE_INVALIDATE (sock); -#else - CLOSE_INVALIDATE (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_INVALIDATE (sock); return RANGEERR; } @@ -1152,11 +1163,7 @@ Accept: %s\r\n\ _("Location: %s%s\n"), hs->newloc ? hs->newloc : _("unspecified"), hs->newloc ? _(" [following]") : ""); -#ifndef HAVE_SSL - CLOSE_FINISH (sock); -#else - CLOSE_FINISH (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_FINISH (sock); FREE_MAYBE (type); FREE_MAYBE (all_headers); return NEWLOCATION; @@ -1197,11 +1204,7 @@ Accept: %s\r\n\ hs->res = 0; FREE_MAYBE (type); FREE_MAYBE (all_headers); -#ifndef HAVE_SSL - CLOSE_FINISH (sock); -#else - CLOSE_FINISH (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_FINISH (sock); return RETRFINISHED; } @@ -1215,11 +1218,7 @@ Accept: %s\r\n\ if (!fp) { logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno)); -#ifndef HAVE_SSL - CLOSE_FINISH (sock); -#else - CLOSE_FINISH (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_FINISH (sock); FREE_MAYBE (all_headers); return FOPENERR; } @@ -1259,11 +1258,7 @@ Accept: %s\r\n\ hs->res = -2; } FREE_MAYBE (all_headers); -#ifndef HAVE_SSL - CLOSE_FINISH (sock); -#else - CLOSE_FINISH (sock,ssl); -#endif /* HAVE_SSL */ + CLOSE_FINISH (sock); if (hs->res == -2) return FWRITEERR; return RETRFINISHED; @@ -1274,8 +1269,6 @@ Accept: %s\r\n\ uerr_t http_loop (struct urlinfo *u, char **newloc, int *dt) { - static int first_retrieval = 1; - int count; int use_ts, got_head = 0; /* time-stamping info */ char *filename_plus_orig_suffix; @@ -1388,23 +1381,7 @@ File `%s' already there, will not retrieve.\n"), u->local); { /* Increment the pass counter. */ ++count; - /* Wait before the retrieval (unless this is the very first - retrieval). - Check if we are retrying or not, wait accordingly - HEH */ - if (!first_retrieval && (opt.wait || (count && opt.waitretry))) - { - if (count) - { - if (countlocal); printwhat (count, opt.ntry); continue; break; - case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED: + case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED: + case SSLERRCTXCREATE: /* Fatal errors just return from the function. */ FREEHSTAT (hstat); xfree (filename_plus_orig_suffix); /* must precede every return! */ @@ -1585,15 +1563,25 @@ The sizes do not match (local %ld) -- retrieving.\n"), local_size); FREEHSTAT (hstat); continue; } - if (!opt.dfp - && (tmr != (time_t) (-1)) + if ((tmr != (time_t) (-1)) && !opt.spider && ((hstat.len == hstat.contlen) || ((hstat.res == 0) && ((hstat.contlen == -1) || (hstat.len >= hstat.contlen && !opt.kill_longer))))) { - touch (u->local, tmr); + /* #### This code repeats in http.c and ftp.c. Move it to a + function! */ + const char *fl = NULL; + if (opt.output_document) + { + if (opt.od_known_regular) + fl = opt.output_document; + } + else + fl = u->local; + if (fl) + touch (fl, tmr); } /* End of time-stamping section. */ @@ -1759,7 +1747,7 @@ check_end (const char *p) ++p; if (!*p || (p[0] == 'G' && p[1] == 'M' && p[2] == 'T') - || ((p[0] == '+' || p[1] == '-') && ISDIGIT (p[1]))) + || ((p[0] == '+' || p[0] == '-') && ISDIGIT (p[1]))) return 1; else return 0; @@ -1898,7 +1886,7 @@ basic_authentication_encode (const char *user, const char *passwd, sprintf (t1, "%s:%s", user, passwd); t2 = (char *)alloca (1 + len2); base64_encode (t1, t2, len1); - res = (char *)malloc (len2 + 11 + strlen (header)); + res = (char *)xmalloc (len2 + 11 + strlen (header)); sprintf (res, "%s: Basic %s\r\n", header, t2); return res;