]> sjero.net Git - wget/blob - src/http.c
[svn] Use the CONNECT method to establish passthrough over SSL traffic
[wget] / src / http.c
1 /* HTTP support.
2    Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5 This file is part of GNU Wget.
6
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Wget; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 In addition, as a special exception, the Free Software Foundation
22 gives permission to link the code of its release of Wget with the
23 OpenSSL project's "OpenSSL" library (or with modified versions of it
24 that use the same license as the "OpenSSL" library), and distribute
25 the linked executables.  You must obey the GNU General Public License
26 in all respects for all of the code used other than "OpenSSL".  If you
27 modify this file, you may extend this exception to your version of the
28 file, but you are not obligated to do so.  If you do not wish to do
29 so, delete this exception statement from your version.  */
30
31 #include <config.h>
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <sys/types.h>
36 #ifdef HAVE_STRING_H
37 # include <string.h>
38 #else
39 # include <strings.h>
40 #endif
41 #ifdef HAVE_UNISTD_H
42 # include <unistd.h>
43 #endif
44 #include <assert.h>
45 #include <errno.h>
46 #if TIME_WITH_SYS_TIME
47 # include <sys/time.h>
48 # include <time.h>
49 #else
50 # if HAVE_SYS_TIME_H
51 #  include <sys/time.h>
52 # else
53 #  include <time.h>
54 # endif
55 #endif
56 #ifndef errno
57 extern int errno;
58 #endif
59
60 #include "wget.h"
61 #include "utils.h"
62 #include "url.h"
63 #include "host.h"
64 #include "retr.h"
65 #include "connect.h"
66 #include "netrc.h"
67 #ifdef HAVE_SSL
68 # include "gen_sslfunc.h"
69 #endif /* HAVE_SSL */
70 #include "cookies.h"
71 #ifdef USE_DIGEST
72 # include "gen-md5.h"
73 #endif
74 #include "convert.h"
75
76 extern char *version_string;
77 extern LARGE_INT total_downloaded_bytes;
78
79 #ifndef MIN
80 # define MIN(x, y) ((x) > (y) ? (y) : (x))
81 #endif
82
83 \f
84 static int cookies_loaded_p;
85 struct cookie_jar *wget_cookie_jar;
86
87 #define TEXTHTML_S "text/html"
88 #define TEXTXHTML_S "application/xhtml+xml"
89 #define HTTP_ACCEPT "*/*"
90
91 /* Some status code validation macros: */
92 #define H_20X(x)        (((x) >= 200) && ((x) < 300))
93 #define H_PARTIAL(x)    ((x) == HTTP_STATUS_PARTIAL_CONTENTS)
94 #define H_REDIRECTED(x) ((x) == HTTP_STATUS_MOVED_PERMANENTLY   \
95                          || (x) == HTTP_STATUS_MOVED_TEMPORARILY \
96                          || (x) == HTTP_STATUS_TEMPORARY_REDIRECT)
97
98 /* HTTP/1.0 status codes from RFC1945, provided for reference.  */
99 /* Successful 2xx.  */
100 #define HTTP_STATUS_OK                  200
101 #define HTTP_STATUS_CREATED             201
102 #define HTTP_STATUS_ACCEPTED            202
103 #define HTTP_STATUS_NO_CONTENT          204
104 #define HTTP_STATUS_PARTIAL_CONTENTS    206
105
106 /* Redirection 3xx.  */
107 #define HTTP_STATUS_MULTIPLE_CHOICES    300
108 #define HTTP_STATUS_MOVED_PERMANENTLY   301
109 #define HTTP_STATUS_MOVED_TEMPORARILY   302
110 #define HTTP_STATUS_NOT_MODIFIED        304
111 #define HTTP_STATUS_TEMPORARY_REDIRECT  307
112
113 /* Client error 4xx.  */
114 #define HTTP_STATUS_BAD_REQUEST         400
115 #define HTTP_STATUS_UNAUTHORIZED        401
116 #define HTTP_STATUS_FORBIDDEN           403
117 #define HTTP_STATUS_NOT_FOUND           404
118
119 /* Server errors 5xx.  */
120 #define HTTP_STATUS_INTERNAL            500
121 #define HTTP_STATUS_NOT_IMPLEMENTED     501
122 #define HTTP_STATUS_BAD_GATEWAY         502
123 #define HTTP_STATUS_UNAVAILABLE         503
124
125 static const char *
126 head_terminator (const char *hunk, int oldlen, int peeklen)
127 {
128   const char *start, *end;
129
130   /* If at first peek, verify whether HUNK starts with "HTTP".  If
131      not, this is a HTTP/0.9 request and we must bail out without
132      reading anything.  */
133   if (oldlen == 0 && 0 != memcmp (hunk, "HTTP", MIN (peeklen, 4)))
134     return hunk;
135
136   if (oldlen < 4)
137     start = hunk;
138   else
139     start = hunk + oldlen - 4;
140   end = hunk + oldlen + peeklen;
141
142   for (; start < end - 1; start++)
143     if (*start == '\n')
144       {
145         if (start < end - 2
146             && start[1] == '\r'
147             && start[2] == '\n')
148           return start + 3;
149         if (start[1] == '\n')
150           return start + 2;
151       }
152   return NULL;
153 }
154
155 /* Read the HTTP request head from FD and return it.  The error
156    conditions are the same as with fd_read_hunk.
157
158    To support HTTP/0.9 responses, this function tries to make sure
159    that the data begins with "HTTP".  If this is not the case, no data
160    is read and an empty request is returned, so that the remaining
161    data can be treated as body.  */
162
163 static char *
164 fd_read_http_head (int fd)
165 {
166   return fd_read_hunk (fd, head_terminator, 512);
167 }
168
169 struct response {
170   /* The response data. */
171   const char *data;
172
173   /* The array of pointers that indicate where each header starts.
174      For example, given three headers "foo", "bar", and "baz":
175        foo: value\r\nbar: value\r\nbaz: value\r\n\r\n
176        0             1             2             3
177      I.e. headers[0] points to the beginning of foo, headers[1] points
178      to the end of foo and the beginning of bar, etc.  */
179   const char **headers;
180 };
181
182 static struct response *
183 response_new (const char *head)
184 {
185   const char *hdr;
186   int count, size;
187
188   struct response *resp = xnew0 (struct response);
189   resp->data = head;
190
191   if (*head == '\0')
192     {
193       /* Empty head means that we're dealing with a headerless
194          (HTTP/0.9) response.  In that case, don't set HEADERS at
195          all.  */
196       return resp;
197     }
198
199   /* Split HEAD into header lines, so that response_header_* functions
200      don't need to do this over and over again.  */
201
202   size = count = 0;
203   hdr = head;
204   while (1)
205     {
206       DO_REALLOC (resp->headers, size, count + 1, const char *);
207       resp->headers[count++] = hdr;
208
209       /* Break upon encountering an empty line. */
210       if (!hdr[0] || (hdr[0] == '\r' && hdr[1] == '\n') || hdr[0] == '\n')
211         break;
212
213       /* Find the end of HDR, including continuations. */
214       do
215         {
216           const char *end = strchr (hdr, '\n');
217           if (end)
218             hdr = end + 1;
219           else
220             hdr += strlen (hdr);
221         }
222       while (*hdr == ' ' || *hdr == '\t');
223     }
224   DO_REALLOC (resp->headers, size, count + 1, const char *);
225   resp->headers[count++] = NULL;
226
227   return resp;
228 }
229
230 static int
231 response_header_bounds (const struct response *resp, const char *name,
232                         const char **begptr, const char **endptr)
233 {
234   int i;
235   const char **headers = resp->headers;
236   int name_len;
237
238   if (!headers || !headers[1])
239     return 0;
240
241   name_len = strlen (name);
242
243   for (i = 1; headers[i + 1]; i++)
244     {
245       const char *b = headers[i];
246       const char *e = headers[i + 1];
247       if (e - b > name_len
248           && b[name_len] == ':'
249           && 0 == strncasecmp (b, name, name_len))
250         {
251           b += name_len + 1;
252           while (b < e && ISSPACE (*b))
253             ++b;
254           while (b < e && ISSPACE (e[-1]))
255             --e;
256           *begptr = b;
257           *endptr = e;
258           return 1;
259         }
260     }
261   return 0;
262 }
263
264 static int
265 response_header_copy (const struct response *resp, const char *name,
266                       char *buf, int bufsize)
267 {
268   const char *b, *e;
269   if (!response_header_bounds (resp, name, &b, &e))
270     return 0;
271   if (bufsize)
272     {
273       int len = MIN (e - b, bufsize);
274       strncpy (buf, b, len);
275       buf[len] = '\0';
276     }
277   return 1;
278 }
279
280 static char *
281 response_header_strdup (const struct response *resp, const char *name)
282 {
283   const char *b, *e;
284   if (!response_header_bounds (resp, name, &b, &e))
285     return NULL;
286   return strdupdelim (b, e);
287 }
288
289 /* Parse the HTTP status line, which is of format:
290
291    HTTP-Version SP Status-Code SP Reason-Phrase
292
293    The function returns the status-code, or -1 if the status line
294    appears malformed.  The pointer to "reason-phrase" message is
295    returned in *MESSAGE.  */
296
297 static int
298 response_status (const struct response *resp, char **message)
299 {
300   int status;
301   const char *p, *end;
302
303   if (!resp->headers)
304     {
305       /* For a HTTP/0.9 response, always assume 200 response. */
306       if (message)
307         *message = xstrdup ("OK");
308       return 200;
309     }
310
311   p = resp->headers[0];
312   end = resp->headers[1];
313
314   if (!end)
315     return -1;
316
317   /* "HTTP" */
318   if (end - p < 4 || 0 != strncmp (p, "HTTP", 4))
319     return -1;
320   p += 4;
321
322   /* "/x.x" (optional because some Gnutella servers have been reported
323      as not sending the "/x.x" part.  */
324   if (p < end && *p == '/')
325     {
326       ++p;
327       while (p < end && ISDIGIT (*p))
328         ++p;
329       if (p < end && *p == '.')
330         ++p; 
331       while (p < end && ISDIGIT (*p))
332         ++p;
333     }
334
335   while (p < end && ISSPACE (*p))
336     ++p;
337   if (end - p < 3 || !ISDIGIT (p[0]) || !ISDIGIT (p[1]) || !ISDIGIT (p[2]))
338     return -1;
339
340   status = 100 * (p[0] - '0') + 10 * (p[1] - '0') + (p[2] - '0');
341   p += 3;
342
343   if (message)
344     {
345       while (p < end && ISSPACE (*p))
346         ++p;
347       while (p < end && ISSPACE (end[-1]))
348         --end;
349       *message = strdupdelim (p, end);
350     }
351
352   return status;
353 }
354
355 static void
356 response_free (struct response *resp)
357 {
358   xfree_null (resp->headers);
359   xfree (resp);
360 }
361
362 static void
363 print_server_response_1 (const char *b, const char *e)
364 {
365   char *ln;
366   if (b < e && e[-1] == '\n')
367     --e;
368   if (b < e && e[-1] == '\r')
369     --e;
370   BOUNDED_TO_ALLOCA (b, e, ln);
371   logprintf (LOG_VERBOSE, "  %s\n", ln);
372 }
373
374 static void
375 print_server_response (const struct response *resp)
376 {
377   int i;
378   if (!resp->headers)
379     return;
380   for (i = 0; resp->headers[i + 1]; i++)
381     print_server_response_1 (resp->headers[i], resp->headers[i + 1]);
382 }
383
384 /* Parse the `Content-Range' header and extract the information it
385    contains.  Returns 1 if successful, -1 otherwise.  */
386 static int
387 parse_content_range (const char *hdr, long *first_byte_ptr,
388                      long *last_byte_ptr, long *entity_length_ptr)
389 {
390   long num;
391
392   /* Ancient versions of Netscape proxy server, presumably predating
393      rfc2068, sent out `Content-Range' without the "bytes"
394      specifier.  */
395   if (!strncasecmp (hdr, "bytes", 5))
396     {
397       hdr += 5;
398       /* "JavaWebServer/1.1.1" sends "bytes: x-y/z", contrary to the
399          HTTP spec. */
400       if (*hdr == ':')
401         ++hdr;
402       while (ISSPACE (*hdr))
403         ++hdr;
404       if (!*hdr)
405         return 0;
406     }
407   if (!ISDIGIT (*hdr))
408     return 0;
409   for (num = 0; ISDIGIT (*hdr); hdr++)
410     num = 10 * num + (*hdr - '0');
411   if (*hdr != '-' || !ISDIGIT (*(hdr + 1)))
412     return 0;
413   *first_byte_ptr = num;
414   ++hdr;
415   for (num = 0; ISDIGIT (*hdr); hdr++)
416     num = 10 * num + (*hdr - '0');
417   if (*hdr != '/' || !ISDIGIT (*(hdr + 1)))
418     return 0;
419   *last_byte_ptr = num;
420   ++hdr;
421   for (num = 0; ISDIGIT (*hdr); hdr++)
422     num = 10 * num + (*hdr - '0');
423   *entity_length_ptr = num;
424   return 1;
425 }
426 \f
427 /* Send the contents of FILE_NAME to SOCK/SSL.  Make sure that exactly
428    PROMISED_SIZE bytes are sent over the wire -- if the file is
429    longer, read only that much; if the file is shorter, report an error.  */
430
431 static int
432 post_file (int sock, const char *file_name, long promised_size)
433 {
434   static char chunk[8192];
435   long written = 0;
436   int write_error;
437   FILE *fp;
438
439   DEBUGP (("[writing POST file %s ... ", file_name));
440
441   fp = fopen (file_name, "rb");
442   if (!fp)
443     return -1;
444   while (!feof (fp) && written < promised_size)
445     {
446       int towrite;
447       int length = fread (chunk, 1, sizeof (chunk), fp);
448       if (length == 0)
449         break;
450       towrite = MIN (promised_size - written, length);
451       write_error = fd_write (sock, chunk, towrite, -1);
452       if (write_error < 0)
453         {
454           fclose (fp);
455           return -1;
456         }
457       written += towrite;
458     }
459   fclose (fp);
460
461   /* If we've written less than was promised, report a (probably
462      nonsensical) error rather than break the promise.  */
463   if (written < promised_size)
464     {
465       errno = EINVAL;
466       return -1;
467     }
468
469   assert (written == promised_size);
470   DEBUGP (("done]\n"));
471   return 0;
472 }
473 \f
474 /* Persistent connections.  Currently, we cache the most recently used
475    connection as persistent, provided that the HTTP server agrees to
476    make it such.  The persistence data is stored in the variables
477    below.  Ideally, it should be possible to cache an arbitrary fixed
478    number of these connections.  */
479
480 /* Whether a persistent connection is active. */
481 static int pconn_active;
482
483 static struct {
484   /* The socket of the connection.  */
485   int socket;
486
487   /* Host and port of the currently active persistent connection. */
488   char *host;
489   int port;
490
491   /* Whether a ssl handshake has occoured on this connection.  */
492   int ssl;
493 } pconn;
494
495 /* Mark the persistent connection as invalid and free the resources it
496    uses.  This is used by the CLOSE_* macros after they forcefully
497    close a registered persistent connection.  */
498
499 static void
500 invalidate_persistent (void)
501 {
502   DEBUGP (("Disabling further reuse of socket %d.\n", pconn.socket));
503   pconn_active = 0;
504   fd_close (pconn.socket);
505   xfree (pconn.host);
506   xzero (pconn);
507 }
508
509 /* Register FD, which should be a TCP/IP connection to HOST:PORT, as
510    persistent.  This will enable someone to use the same connection
511    later.  In the context of HTTP, this must be called only AFTER the
512    response has been received and the server has promised that the
513    connection will remain alive.
514
515    If a previous connection was persistent, it is closed. */
516
517 static void
518 register_persistent (const char *host, int port, int fd, int ssl)
519 {
520   if (pconn_active)
521     {
522       if (pconn.socket == fd)
523         {
524           /* The connection FD is already registered. */
525           return;
526         }
527       else
528         {
529           /* The old persistent connection is still active; close it
530              first.  This situation arises whenever a persistent
531              connection exists, but we then connect to a different
532              host, and try to register a persistent connection to that
533              one.  */
534           invalidate_persistent ();
535         }
536     }
537
538   pconn_active = 1;
539   pconn.socket = fd;
540   pconn.host = xstrdup (host);
541   pconn.port = port;
542   pconn.ssl = ssl;
543
544   DEBUGP (("Registered socket %d for persistent reuse.\n", fd));
545 }
546
547 /* Return non-zero if a persistent connection is available for
548    connecting to HOST:PORT.  */
549
550 static int
551 persistent_available_p (const char *host, int port, int ssl,
552                         int *host_lookup_failed)
553 {
554   /* First, check whether a persistent connection is active at all.  */
555   if (!pconn_active)
556     return 0;
557
558   /* If we want SSL and the last connection wasn't or vice versa,
559      don't use it.  Checking for host and port is not enough because
560      HTTP and HTTPS can apparently coexist on the same port.  */
561   if (ssl != pconn.ssl)
562     return 0;
563
564   /* If we're not connecting to the same port, we're not interested. */
565   if (port != pconn.port)
566     return 0;
567
568   /* If the host is the same, we're in business.  If not, there is
569      still hope -- read below.  */
570   if (0 != strcasecmp (host, pconn.host))
571     {
572       /* If pconn.socket is already talking to HOST, we needn't
573          reconnect.  This happens often when both sites are virtual
574          hosts distinguished only by name and served by the same
575          network interface, and hence the same web server (possibly
576          set up by the ISP and serving many different web sites).
577          This admittedly non-standard optimization does not contradict
578          HTTP and works well with popular server software.  */
579
580       int found;
581       ip_address ip;
582       struct address_list *al;
583
584       if (ssl)
585         /* Don't try to talk to two different SSL sites over the same
586            secure connection!  (Besides, it's not clear if name-based
587            virtual hosting is even possible with SSL.)  */
588         return 0;
589
590       /* If pconn.socket's peer is one of the IP addresses HOST
591          resolves to, pconn.socket is for all intents and purposes
592          already talking to HOST.  */
593
594       if (!socket_ip_address (pconn.socket, &ip, ENDPOINT_PEER))
595         {
596           /* Can't get the peer's address -- something must be very
597              wrong with the connection.  */
598           invalidate_persistent ();
599           return 0;
600         }
601       al = lookup_host (host, 0);
602       if (!al)
603         {
604           *host_lookup_failed = 1;
605           return 0;
606         }
607
608       found = address_list_contains (al, &ip);
609       address_list_release (al);
610
611       if (!found)
612         return 0;
613
614       /* The persistent connection's peer address was found among the
615          addresses HOST resolved to; therefore, pconn.sock is in fact
616          already talking to HOST -- no need to reconnect.  */
617     }
618
619   /* Finally, check whether the connection is still open.  This is
620      important because most server implement a liberal (short) timeout
621      on persistent connections.  Wget can of course always reconnect
622      if the connection doesn't work out, but it's nicer to know in
623      advance.  This test is a logical followup of the first test, but
624      is "expensive" and therefore placed at the end of the list.  */
625
626   if (!test_socket_open (pconn.socket))
627     {
628       /* Oops, the socket is no longer open.  Now that we know that,
629          let's invalidate the persistent connection before returning
630          0.  */
631       invalidate_persistent ();
632       return 0;
633     }
634
635   return 1;
636 }
637
638 /* The idea behind these two CLOSE macros is to distinguish between
639    two cases: one when the job we've been doing is finished, and we
640    want to close the connection and leave, and two when something is
641    seriously wrong and we're closing the connection as part of
642    cleanup.
643
644    In case of keep_alive, CLOSE_FINISH should leave the connection
645    open, while CLOSE_INVALIDATE should still close it.
646
647    Note that the semantics of the flag `keep_alive' is "this
648    connection *will* be reused (the server has promised not to close
649    the connection once we're done)", while the semantics of
650    `pc_active_p && (fd) == pc_last_fd' is "we're *now* using an
651    active, registered connection".  */
652
653 #define CLOSE_FINISH(fd) do {                   \
654   if (!keep_alive)                              \
655     {                                           \
656       if (pconn_active && (fd) == pconn.socket) \
657         invalidate_persistent ();               \
658       else                                      \
659         fd_close (fd);                          \
660     }                                           \
661 } while (0)
662
663 #define CLOSE_INVALIDATE(fd) do {               \
664   if (pconn_active && (fd) == pconn.socket)     \
665     invalidate_persistent ();                   \
666   else                                          \
667     fd_close (fd);                              \
668 } while (0)
669 \f
670 struct http_stat
671 {
672   long len;                     /* received length */
673   long contlen;                 /* expected length */
674   long restval;                 /* the restart value */
675   int res;                      /* the result of last read */
676   char *newloc;                 /* new location (redirection) */
677   char *remote_time;            /* remote time-stamp string */
678   char *error;                  /* textual HTTP error */
679   int statcode;                 /* status code */
680   double dltime;                /* time of the download in msecs */
681   int no_truncate;              /* whether truncating the file is
682                                    forbidden. */
683   const char *referer;          /* value of the referer header. */
684   char **local_file;            /* local file. */
685 };
686
687 static void
688 free_hstat (struct http_stat *hs)
689 {
690   xfree_null (hs->newloc);
691   xfree_null (hs->remote_time);
692   xfree_null (hs->error);
693
694   /* Guard against being called twice. */
695   hs->newloc = NULL;
696   hs->remote_time = NULL;
697   hs->error = NULL;
698 }
699
700 static char *create_authorization_line PARAMS ((const char *, const char *,
701                                                 const char *, const char *,
702                                                 const char *));
703 static char *basic_authentication_encode PARAMS ((const char *, const char *,
704                                                   const char *));
705 static int known_authentication_scheme_p PARAMS ((const char *));
706
707 time_t http_atotm PARAMS ((const char *));
708
709 #define BEGINS_WITH(line, string_constant)                              \
710   (!strncasecmp (line, string_constant, sizeof (string_constant) - 1)   \
711    && (ISSPACE (line[sizeof (string_constant) - 1])                     \
712        || !line[sizeof (string_constant) - 1]))
713
714 /* Retrieve a document through HTTP protocol.  It recognizes status
715    code, and correctly handles redirections.  It closes the network
716    socket.  If it receives an error from the functions below it, it
717    will print it if there is enough information to do so (almost
718    always), returning the error to the caller (i.e. http_loop).
719
720    Various HTTP parameters are stored to hs.
721
722    If PROXY is non-NULL, the connection will be made to the proxy
723    server, and u->url will be requested.  */
724 static uerr_t
725 gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
726 {
727   char *request, *type, *command, *full_path;
728   char *user, *passwd;
729   char *pragma_h, *referer, *useragent, *range, *wwwauth;
730   char *authenticate_h;
731   char *proxyauth;
732   char *port_maybe;
733   char *request_keep_alive;
734   int sock, statcode;
735   int write_error;
736   long contlen, contrange;
737   struct url *conn;
738   FILE *fp;
739   int auth_tried_already;
740   int using_ssl = 0;
741   char *cookies = NULL;
742
743   char *head;
744   struct response *resp;
745   char hdrval[256];
746   char *message;
747   char *set_cookie;
748
749   /* Whether this connection will be kept alive after the HTTP request
750      is done. */
751   int keep_alive;
752
753   /* Flag that detects having received a keep-alive response.  */
754   int keep_alive_confirmed;
755
756   /* Whether keep-alive should be inhibited. */
757   int inhibit_keep_alive;
758
759   /* Whether we need to print the host header with braces around host,
760      e.g. "Host: [3ffe:8100:200:2::2]:1234" instead of the usual
761      "Host: symbolic-name:1234". */
762   int squares_around_host = 0;
763
764   /* Headers sent when using POST. */
765   char *post_content_type, *post_content_length;
766   long post_data_size = 0;
767
768   int host_lookup_failed;
769
770 #ifdef HAVE_SSL
771   /* Initialize the SSL context.  After the first run, this is a
772      no-op.  */
773   switch (ssl_init ())
774     {
775     case SSLERRCTXCREATE:
776       /* this is fatal */
777       logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
778       return SSLERRCTXCREATE;
779     case SSLERRCERTFILE:
780       /* try without certfile */
781       logprintf (LOG_NOTQUIET,
782                  _("Failed to load certificates from %s\n"),
783                  opt.sslcertfile);
784       logprintf (LOG_NOTQUIET,
785                  _("Trying without the specified certificate\n"));
786       break;
787     case SSLERRCERTKEY:
788       logprintf (LOG_NOTQUIET,
789                  _("Failed to get certificate key from %s\n"),
790                  opt.sslcertkey);
791       logprintf (LOG_NOTQUIET,
792                  _("Trying without the specified certificate\n"));
793       break;
794     default:
795       break;
796     }
797 #endif /* HAVE_SSL */
798
799   if (!(*dt & HEAD_ONLY))
800     /* If we're doing a GET on the URL, as opposed to just a HEAD, we need to
801        know the local filename so we can save to it. */
802     assert (*hs->local_file != NULL);
803
804   authenticate_h = NULL;
805   auth_tried_already = 0;
806
807   inhibit_keep_alive = !opt.http_keep_alive;
808
809  again:
810   /* We need to come back here when the initial attempt to retrieve
811      without authorization header fails.  (Expected to happen at least
812      for the Digest authorization scheme.)  */
813
814   keep_alive = 0;
815   keep_alive_confirmed = 0;
816
817   post_content_type = NULL;
818   post_content_length = NULL;
819
820   /* Initialize certain elements of struct http_stat.  */
821   hs->len = 0L;
822   hs->contlen = -1;
823   hs->res = -1;
824   hs->newloc = NULL;
825   hs->remote_time = NULL;
826   hs->error = NULL;
827
828   conn = u;
829
830   proxyauth = NULL;
831   if (proxy)
832     {
833       char *proxy_user, *proxy_passwd;
834       /* For normal username and password, URL components override
835          command-line/wgetrc parameters.  With proxy
836          authentication, it's the reverse, because proxy URLs are
837          normally the "permanent" ones, so command-line args
838          should take precedence.  */
839       if (opt.proxy_user && opt.proxy_passwd)
840         {
841           proxy_user = opt.proxy_user;
842           proxy_passwd = opt.proxy_passwd;
843         }
844       else
845         {
846           proxy_user = proxy->user;
847           proxy_passwd = proxy->passwd;
848         }
849       /* #### This does not appear right.  Can't the proxy request,
850          say, `Digest' authentication?  */
851       if (proxy_user && proxy_passwd)
852         proxyauth = basic_authentication_encode (proxy_user, proxy_passwd,
853                                                  "Proxy-Authorization");
854
855       /* If we're using a proxy, we will be connecting to the proxy
856          server.  */
857       conn = proxy;
858     }
859
860   host_lookup_failed = 0;
861   sock = -1;
862
863   /* First: establish the connection.  */
864
865   if (!inhibit_keep_alive)
866     {
867       /* Look for a persistent connection to target host, unless a
868          proxy is used.  The exception is when SSL is in use, in which
869          case the proxy is nothing but a passthrough to the target
870          host, registered as a connection to the latter.  */
871       struct url *relevant = conn;
872 #ifdef HAVE_SSL
873       if (u->scheme == SCHEME_HTTPS)
874         relevant = u;
875 #endif
876
877       if (persistent_available_p (relevant->host, relevant->port,
878 #ifdef HAVE_SSL
879                                   relevant->scheme == SCHEME_HTTPS,
880 #else
881                                   0,
882 #endif
883                                   &host_lookup_failed))
884         {
885           sock = pconn.socket;
886           using_ssl = pconn.ssl;
887           logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"),
888                      pconn.host, pconn.port);
889           DEBUGP (("Reusing fd %d.\n", sock));
890         }
891     }
892
893   if (sock < 0)
894     {
895       /* In its current implementation, persistent_available_p will
896          look up conn->host in some cases.  If that lookup failed, we
897          don't need to bother with connect_to_host.  */
898       if (host_lookup_failed)
899         return HOSTERR;
900
901       sock = connect_to_host (conn->host, conn->port);
902       if (sock == E_HOST)
903         return HOSTERR;
904       else if (sock < 0)
905         return (retryable_socket_connect_error (errno)
906                 ? CONERROR : CONIMPOSSIBLE);
907
908 #ifdef HAVE_SSL
909       if (proxy && u->scheme == SCHEME_HTTPS)
910         {
911           /* When requesting SSL URLs through proxies, use the
912              CONNECT method to request passthrough.  */
913           char *connect =
914             (char *) alloca (64
915                              + strlen (u->host)
916                              + (proxyauth ? strlen (proxyauth) : 0));
917           sprintf (connect, "CONNECT %s:%d HTTP/1.0\r\n%s\r\n",
918                    u->host, u->port, proxyauth ? proxyauth : "");
919           DEBUGP (("Writing to proxy: [%s]\n", connect));
920           write_error = fd_write (sock, connect, strlen (connect), -1);
921           if (write_error < 0)
922             {
923               xfree_null (proxyauth);
924               logprintf (LOG_VERBOSE, _("Failed writing to proxy: %s.\n"),
925                          strerror (errno));
926               CLOSE_INVALIDATE (sock);
927               return WRITEFAILED;
928             }
929
930           head = fd_read_http_head (sock);
931           if (!head)
932             {
933               xfree_null (proxyauth);
934               logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
935                          strerror (errno));
936               CLOSE_INVALIDATE (sock);
937               return HERR;
938             }
939           message = NULL;
940           if (!*head)
941             {
942               xfree (head);
943               goto failed_tunnel;
944             }
945           DEBUGP (("proxy responded with: [%s]\n", head));
946
947           resp = response_new (head);
948           statcode = response_status (resp, &message);
949           response_free (resp);
950           if (statcode != 200)
951             {
952             failed_tunnel:
953               xfree_null (proxyauth);
954               logprintf (LOG_NOTQUIET, _("Proxy tunneling failed: %s"),
955                          message ? message : "?");
956               xfree_null (message);
957               return CONSSLERR;
958             }
959           xfree (message);
960
961           /* SOCK is now *really* connected to u->host, so update CONN
962              to reflect this.  That way register_persistent will
963              register SOCK as being connected to u->host:u->port.  */
964           conn = u;
965         }
966
967       if (conn->scheme == SCHEME_HTTPS)
968         {
969           if (!ssl_connect (sock))
970             {
971               fd_close (sock);
972               return CONSSLERR;
973             }
974           using_ssl = 1;
975         }
976 #endif /* HAVE_SSL */
977     }
978
979   if (*dt & HEAD_ONLY)
980     command = "HEAD";
981   else if (opt.post_file_name || opt.post_data)
982     command = "POST";
983   else
984     command = "GET";
985
986   referer = NULL;
987   if (hs->referer)
988     {
989       referer = (char *)alloca (9 + strlen (hs->referer) + 3);
990       sprintf (referer, "Referer: %s\r\n", hs->referer);
991     }
992
993   if (*dt & SEND_NOCACHE)
994     pragma_h = "Pragma: no-cache\r\n";
995   else
996     pragma_h = "";
997
998   if (hs->restval)
999     {
1000       range = (char *)alloca (13 + numdigit (hs->restval) + 4);
1001       /* Gag me!  Some servers (e.g. WebSitePro) have been known to
1002          respond to the following `Range' format by generating a
1003          multipart/x-byte-ranges MIME document!  This MIME type was
1004          present in an old draft of the byteranges specification.
1005          HTTP/1.1 specifies a multipart/byte-ranges MIME type, but
1006          only if multiple non-overlapping ranges are requested --
1007          which Wget never does.  */
1008       sprintf (range, "Range: bytes=%ld-\r\n", hs->restval);
1009     }
1010   else
1011     range = NULL;
1012   if (opt.useragent)
1013     STRDUP_ALLOCA (useragent, opt.useragent);
1014   else
1015     {
1016       useragent = (char *)alloca (10 + strlen (version_string));
1017       sprintf (useragent, "Wget/%s", version_string);
1018     }
1019   /* Construct the authentication, if userid is present.  */
1020   user = u->user;
1021   passwd = u->passwd;
1022   search_netrc (u->host, (const char **)&user, (const char **)&passwd, 0);
1023   user = user ? user : opt.http_user;
1024   passwd = passwd ? passwd : opt.http_passwd;
1025
1026   wwwauth = NULL;
1027   if (user && passwd)
1028     {
1029       if (!authenticate_h)
1030         {
1031           /* We have the username and the password, but haven't tried
1032              any authorization yet.  Let's see if the "Basic" method
1033              works.  If not, we'll come back here and construct a
1034              proper authorization method with the right challenges.
1035
1036              If we didn't employ this kind of logic, every URL that
1037              requires authorization would have to be processed twice,
1038              which is very suboptimal and generates a bunch of false
1039              "unauthorized" errors in the server log.
1040
1041              #### But this logic also has a serious problem when used
1042              with stronger authentications: we *first* transmit the
1043              username and the password in clear text, and *then*
1044              attempt a stronger authentication scheme.  That cannot be
1045              right!  We are only fortunate that almost everyone still
1046              uses the `Basic' scheme anyway.
1047
1048              There should be an option to prevent this from happening,
1049              for those who use strong authentication schemes and value
1050              their passwords.  */
1051           wwwauth = basic_authentication_encode (user, passwd, "Authorization");
1052         }
1053       else
1054         {
1055           /* Use the full path, i.e. one that includes the leading
1056              slash and the query string, but is independent of proxy
1057              setting.  */
1058           char *pth = url_full_path (u);
1059           wwwauth = create_authorization_line (authenticate_h, user, passwd,
1060                                                command, pth);
1061           xfree (pth);
1062         }
1063     }
1064
1065   /* String of the form :PORT.  Used only for non-standard ports. */
1066   port_maybe = NULL;
1067   if (u->port != scheme_default_port (u->scheme))
1068     {
1069       port_maybe = (char *)alloca (numdigit (u->port) + 2);
1070       sprintf (port_maybe, ":%d", u->port);
1071     }
1072
1073   if (!inhibit_keep_alive)
1074     request_keep_alive = "Connection: Keep-Alive\r\n";
1075   else
1076     request_keep_alive = NULL;
1077
1078   if (opt.cookies)
1079     cookies = cookie_header (wget_cookie_jar, u->host, u->port, u->path,
1080 #ifdef HAVE_SSL
1081                              u->scheme == SCHEME_HTTPS
1082 #else
1083                              0
1084 #endif
1085                              );
1086
1087   if (opt.post_data || opt.post_file_name)
1088     {
1089       post_content_type = "Content-Type: application/x-www-form-urlencoded\r\n";
1090       if (opt.post_data)
1091         post_data_size = strlen (opt.post_data);
1092       else
1093         {
1094           post_data_size = file_size (opt.post_file_name);
1095           if (post_data_size == -1)
1096             {
1097               logprintf (LOG_NOTQUIET, "POST data file missing: %s\n",
1098                          opt.post_file_name);
1099               post_data_size = 0;
1100             }
1101         }
1102       post_content_length = xmalloc (16 + numdigit (post_data_size) + 2 + 1);
1103       sprintf (post_content_length,
1104                "Content-Length: %ld\r\n", post_data_size);
1105     }
1106
1107   if (proxy)
1108     full_path = xstrdup (u->url);
1109   else
1110     /* Use the full path, i.e. one that includes the leading slash and
1111        the query string.  E.g. if u->path is "foo/bar" and u->query is
1112        "param=value", full_path will be "/foo/bar?param=value".  */
1113     full_path = url_full_path (u);
1114
1115   if (strchr (u->host, ':'))
1116     squares_around_host = 1;
1117
1118   /* Allocate the memory for the request.  */
1119   request = (char *)alloca (strlen (command)
1120                             + strlen (full_path)
1121                             + strlen (useragent)
1122                             + strlen (u->host)
1123                             + (port_maybe ? strlen (port_maybe) : 0)
1124                             + strlen (HTTP_ACCEPT)
1125                             + (request_keep_alive
1126                                ? strlen (request_keep_alive) : 0)
1127                             + (referer ? strlen (referer) : 0)
1128                             + (cookies ? strlen (cookies) : 0)
1129                             + (wwwauth ? strlen (wwwauth) : 0)
1130                             + (proxyauth ? strlen (proxyauth) : 0)
1131                             + (range ? strlen (range) : 0)
1132                             + strlen (pragma_h)
1133                             + (post_content_type
1134                                ? strlen (post_content_type) : 0)
1135                             + (post_content_length
1136                                ? strlen (post_content_length) : 0)
1137                             + (opt.user_header ? strlen (opt.user_header) : 0)
1138                             + 64);
1139   /* Construct the request.  */
1140   sprintf (request, "\
1141 %s %s HTTP/1.0\r\n\
1142 User-Agent: %s\r\n\
1143 Host: %s%s%s%s\r\n\
1144 Accept: %s\r\n\
1145 %s%s%s%s%s%s%s%s%s%s\r\n",
1146            command, full_path,
1147            useragent,
1148            squares_around_host ? "[" : "", u->host, squares_around_host ? "]" : "",
1149            port_maybe ? port_maybe : "",
1150            HTTP_ACCEPT,
1151            request_keep_alive ? request_keep_alive : "",
1152            referer ? referer : "",
1153            cookies ? cookies : "", 
1154            wwwauth ? wwwauth : "", 
1155            proxyauth ? proxyauth : "", 
1156            range ? range : "",
1157            pragma_h,
1158            post_content_type ? post_content_type : "",
1159            post_content_length ? post_content_length : "",
1160            opt.user_header ? opt.user_header : "");
1161   DEBUGP (("\n---request begin---\n%s", request));
1162
1163   /* Free the temporary memory.  */
1164   xfree_null (wwwauth);
1165   xfree_null (proxyauth);
1166   xfree_null (cookies);
1167   xfree (full_path);
1168
1169   /* Send the request to server.  */
1170   write_error = fd_write (sock, request, strlen (request), -1);
1171
1172   if (write_error >= 0)
1173     {
1174       if (opt.post_data)
1175         {
1176           DEBUGP (("[POST data: %s]\n", opt.post_data));
1177           write_error = fd_write (sock, opt.post_data, post_data_size, -1);
1178         }
1179       else if (opt.post_file_name && post_data_size != 0)
1180         write_error = post_file (sock, opt.post_file_name, post_data_size);
1181     }
1182   DEBUGP (("---request end---\n"));
1183
1184   if (write_error < 0)
1185     {
1186       logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
1187                  strerror (errno));
1188       CLOSE_INVALIDATE (sock);
1189       return WRITEFAILED;
1190     }
1191   logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "),
1192              proxy ? "Proxy" : "HTTP");
1193   contlen = contrange = -1;
1194   type = NULL;
1195   statcode = -1;
1196   *dt &= ~RETROKF;
1197
1198   head = fd_read_http_head (sock);
1199   if (!head)
1200     {
1201       logputs (LOG_VERBOSE, "\n");
1202       if (errno == 0)
1203         {
1204           logputs (LOG_NOTQUIET, _("No data received.\n"));
1205           CLOSE_INVALIDATE (sock);
1206           return HEOF;
1207         }
1208       else
1209         {
1210           logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
1211                      strerror (errno));
1212           CLOSE_INVALIDATE (sock);
1213           return HERR;
1214         }
1215     }
1216   DEBUGP (("\n---response begin---\n%s---response end---\n", head));
1217
1218   resp = response_new (head);
1219
1220   /* Check for status line.  */
1221   message = NULL;
1222   statcode = response_status (resp, &message);
1223   if (!opt.server_response)
1224     logprintf (LOG_VERBOSE, "%2d %s\n", statcode, message ? message : "");
1225   else
1226     {
1227       logprintf (LOG_VERBOSE, "\n");
1228       print_server_response (resp);
1229     }
1230
1231   hs->statcode = statcode;
1232   if (statcode == -1)
1233     hs->error = xstrdup (_("Malformed status line"));
1234   else if (!*message)
1235     hs->error = xstrdup (_("(no description)"));
1236   else
1237     hs->error = xstrdup (message);
1238
1239   if (response_header_copy (resp, "Content-Length", hdrval, sizeof (hdrval)))
1240     contlen = strtol (hdrval, NULL, 10);
1241   type = response_header_strdup (resp, "Content-Type");
1242   if (type)
1243     {
1244       char *tmp = strchr (type, ';');
1245       if (tmp)
1246         {
1247           while (tmp > type && ISSPACE (tmp[-1]))
1248             --tmp;
1249           *tmp = '\0';
1250         }
1251     }
1252   hs->newloc = response_header_strdup (resp, "Location");
1253   hs->remote_time = response_header_strdup (resp, "Last-Modified");
1254   set_cookie = response_header_strdup (resp, "Set-Cookie");
1255   if (set_cookie)
1256     {
1257       /* The jar should have been created by now. */
1258       assert (wget_cookie_jar != NULL);
1259       cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port, u->path,
1260                                 set_cookie);
1261       xfree (set_cookie);
1262     }
1263   authenticate_h = response_header_strdup (resp, "WWW-Authenticate");
1264   if (response_header_copy (resp, "Content-Range", hdrval, sizeof (hdrval)))
1265     {
1266       long first_byte_pos, last_byte_pos, entity_length;
1267       if (parse_content_range (hdrval, &first_byte_pos, &last_byte_pos,
1268                                &entity_length))
1269         contrange = first_byte_pos;
1270     }
1271
1272   /* Check for keep-alive related responses. */
1273   if (!inhibit_keep_alive && contlen != -1)
1274     {
1275       if (response_header_copy (resp, "Keep-Alive", NULL, 0))
1276         keep_alive = 1;
1277       else if (response_header_copy (resp, "Connection", hdrval,
1278                                      sizeof (hdrval)))
1279         {
1280           if (0 == strcasecmp (hdrval, "Keep-Alive"))
1281             keep_alive = 1;
1282         }
1283     }
1284   response_free (resp);
1285
1286   if (keep_alive)
1287     /* The server has promised that it will not close the connection
1288        when we're done.  This means that we can register it.  */
1289     register_persistent (conn->host, conn->port, sock, using_ssl);
1290
1291   if ((statcode == HTTP_STATUS_UNAUTHORIZED)
1292       && authenticate_h)
1293     {
1294       /* Authorization is required.  */
1295       xfree_null (type);
1296       type = NULL;
1297       free_hstat (hs);
1298       CLOSE_INVALIDATE (sock);  /* would be CLOSE_FINISH, but there
1299                                    might be more bytes in the body. */
1300       if (auth_tried_already)
1301         {
1302           /* If we have tried it already, then there is not point
1303              retrying it.  */
1304         failed:
1305           logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
1306           xfree (authenticate_h);
1307           return AUTHFAILED;
1308         }
1309       else if (!known_authentication_scheme_p (authenticate_h))
1310         {
1311           xfree (authenticate_h);
1312           logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n"));
1313           return AUTHFAILED;
1314         }
1315       else if (BEGINS_WITH (authenticate_h, "Basic"))
1316         {
1317           /* The authentication scheme is basic, the one we try by
1318              default, and it failed.  There's no sense in trying
1319              again.  */
1320           goto failed;
1321         }
1322       else
1323         {
1324           auth_tried_already = 1;
1325           goto again;
1326         }
1327     }
1328   /* We do not need this anymore.  */
1329   if (authenticate_h)
1330     {
1331       xfree (authenticate_h);
1332       authenticate_h = NULL;
1333     }
1334
1335   /* 20x responses are counted among successful by default.  */
1336   if (H_20X (statcode))
1337     *dt |= RETROKF;
1338
1339   /* Return if redirected.  */
1340   if (H_REDIRECTED (statcode) || statcode == HTTP_STATUS_MULTIPLE_CHOICES)
1341     {
1342       /* RFC2068 says that in case of the 300 (multiple choices)
1343          response, the server can output a preferred URL through
1344          `Location' header; otherwise, the request should be treated
1345          like GET.  So, if the location is set, it will be a
1346          redirection; otherwise, just proceed normally.  */
1347       if (statcode == HTTP_STATUS_MULTIPLE_CHOICES && !hs->newloc)
1348         *dt |= RETROKF;
1349       else
1350         {
1351           logprintf (LOG_VERBOSE,
1352                      _("Location: %s%s\n"),
1353                      hs->newloc ? hs->newloc : _("unspecified"),
1354                      hs->newloc ? _(" [following]") : "");
1355           CLOSE_INVALIDATE (sock);      /* would be CLOSE_FINISH, but there
1356                                            might be more bytes in the body. */
1357           xfree_null (type);
1358           return NEWLOCATION;
1359         }
1360     }
1361
1362   /* If content-type is not given, assume text/html.  This is because
1363      of the multitude of broken CGI's that "forget" to generate the
1364      content-type.  */
1365   if (!type ||
1366         0 == strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)) ||
1367         0 == strncasecmp (type, TEXTXHTML_S, strlen (TEXTXHTML_S)))
1368     *dt |= TEXTHTML;
1369   else
1370     *dt &= ~TEXTHTML;
1371
1372   if (opt.html_extension && (*dt & TEXTHTML))
1373     /* -E / --html-extension / html_extension = on was specified, and this is a
1374        text/html file.  If some case-insensitive variation on ".htm[l]" isn't
1375        already the file's suffix, tack on ".html". */
1376     {
1377       char*  last_period_in_local_filename = strrchr(*hs->local_file, '.');
1378
1379       if (last_period_in_local_filename == NULL
1380           || !(0 == strcasecmp (last_period_in_local_filename, ".htm")
1381                || 0 == strcasecmp (last_period_in_local_filename, ".html")))
1382         {
1383           size_t  local_filename_len = strlen(*hs->local_file);
1384           
1385           *hs->local_file = xrealloc(*hs->local_file,
1386                                      local_filename_len + sizeof(".html"));
1387           strcpy(*hs->local_file + local_filename_len, ".html");
1388
1389           *dt |= ADDED_HTML_EXTENSION;
1390         }
1391     }
1392
1393   if (contrange == -1)
1394     {
1395       /* We did not get a content-range header.  This means that the
1396          server did not honor our `Range' request.  Normally, this
1397          means we should reset hs->restval and continue normally.  */
1398
1399       /* However, if `-c' is used, we need to be a bit more careful:
1400
1401          1. If `-c' is specified and the file already existed when
1402          Wget was started, it would be a bad idea for us to start
1403          downloading it from scratch, effectively truncating it.  I
1404          believe this cannot happen unless `-c' was specified.
1405
1406          2. If `-c' is used on a file that is already fully
1407          downloaded, we're requesting bytes after the end of file,
1408          which can result in server not honoring `Range'.  If this is
1409          the case, `Content-Length' will be equal to the length of the
1410          file.  */
1411       if (opt.always_rest)
1412         {
1413           /* Check for condition #2. */
1414           if (hs->restval > 0               /* restart was requested. */
1415               && contlen != -1              /* we got content-length. */
1416               && hs->restval >= contlen     /* file fully downloaded
1417                                                or has shrunk.  */
1418               )
1419             {
1420               logputs (LOG_VERBOSE, _("\
1421 \n    The file is already fully retrieved; nothing to do.\n\n"));
1422               /* In case the caller inspects. */
1423               hs->len = contlen;
1424               hs->res = 0;
1425               /* Mark as successfully retrieved. */
1426               *dt |= RETROKF;
1427               xfree_null (type);
1428               CLOSE_INVALIDATE (sock);  /* would be CLOSE_FINISH, but there
1429                                            might be more bytes in the body. */
1430               return RETRUNNEEDED;
1431             }
1432
1433           /* Check for condition #1. */
1434           if (hs->no_truncate)
1435             {
1436               logprintf (LOG_NOTQUIET,
1437                          _("\
1438 \n\
1439 Continued download failed on this file, which conflicts with `-c'.\n\
1440 Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
1441               xfree_null (type);
1442               CLOSE_INVALIDATE (sock);
1443               return CONTNOTSUPPORTED;
1444             }
1445
1446           /* Fallthrough */
1447         }
1448
1449       hs->restval = 0;
1450     }
1451   else if (contrange != hs->restval ||
1452            (H_PARTIAL (statcode) && contrange == -1))
1453     {
1454       /* This means the whole request was somehow misunderstood by the
1455          server.  Bail out.  */
1456       xfree_null (type);
1457       CLOSE_INVALIDATE (sock);
1458       return RANGEERR;
1459     }
1460
1461   if (hs->restval)
1462     {
1463       if (contlen != -1)
1464         contlen += contrange;
1465       else
1466         contrange = -1;        /* If conent-length was not sent,
1467                                   content-range will be ignored.  */
1468     }
1469   hs->contlen = contlen;
1470
1471   if (opt.verbose)
1472     {
1473       if ((*dt & RETROKF) && !opt.server_response)
1474         {
1475           /* No need to print this output if the body won't be
1476              downloaded at all, or if the original server response is
1477              printed.  */
1478           logputs (LOG_VERBOSE, _("Length: "));
1479           if (contlen != -1)
1480             {
1481               logputs (LOG_VERBOSE, legible (contlen));
1482               if (contrange != -1)
1483                 logprintf (LOG_VERBOSE, _(" (%s to go)"),
1484                            legible (contlen - contrange));
1485             }
1486           else
1487             logputs (LOG_VERBOSE,
1488                      opt.ignore_length ? _("ignored") : _("unspecified"));
1489           if (type)
1490             logprintf (LOG_VERBOSE, " [%s]\n", type);
1491           else
1492             logputs (LOG_VERBOSE, "\n");
1493         }
1494     }
1495   xfree_null (type);
1496   type = NULL;                  /* We don't need it any more.  */
1497
1498   /* Return if we have no intention of further downloading.  */
1499   if (!(*dt & RETROKF) || (*dt & HEAD_ONLY))
1500     {
1501       /* In case the caller cares to look...  */
1502       hs->len = 0L;
1503       hs->res = 0;
1504       xfree_null (type);
1505       CLOSE_INVALIDATE (sock);  /* would be CLOSE_FINISH, but there
1506                                    might be more bytes in the body. */
1507       return RETRFINISHED;
1508     }
1509
1510   /* Open the local file.  */
1511   if (!opt.dfp)
1512     {
1513       mkalldirs (*hs->local_file);
1514       if (opt.backups)
1515         rotate_backups (*hs->local_file);
1516       fp = fopen (*hs->local_file, hs->restval ? "ab" : "wb");
1517       if (!fp)
1518         {
1519           logprintf (LOG_NOTQUIET, "%s: %s\n", *hs->local_file, strerror (errno));
1520           CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
1521                                       might be more bytes in the body. */
1522           return FOPENERR;
1523         }
1524     }
1525   else                          /* opt.dfp */
1526     {
1527       extern int global_download_count;
1528       fp = opt.dfp;
1529       /* To ensure that repeated "from scratch" downloads work for -O
1530          files, we rewind the file pointer, unless restval is
1531          non-zero.  (This works only when -O is used on regular files,
1532          but it's still a valuable feature.)
1533
1534          However, this loses when more than one URL is specified on
1535          the command line the second rewinds eradicates the contents
1536          of the first download.  Thus we disable the above trick for
1537          all the downloads except the very first one.
1538
1539          #### A possible solution to this would be to remember the
1540          file position in the output document and to seek to that
1541          position, instead of rewinding.
1542
1543          We don't truncate stdout, since that breaks
1544          "wget -O - [...] >> foo".
1545       */
1546       if (!hs->restval && global_download_count == 0 && opt.dfp != stdout)
1547         {
1548           /* This will silently fail for streams that don't correspond
1549              to regular files, but that's OK.  */
1550           rewind (fp);
1551           /* ftruncate is needed because opt.dfp is opened in append
1552              mode if opt.always_rest is set.  */
1553           ftruncate (fileno (fp), 0);
1554           clearerr (fp);
1555         }
1556     }
1557
1558   /* #### This confuses the code that checks for file size.  There
1559      should be some overhead information.  */
1560   if (opt.save_headers)
1561     fwrite (head, 1, strlen (head), fp);
1562
1563   /* Get the contents of the document.  */
1564   hs->res = fd_read_body (sock, fp, &hs->len, hs->restval,
1565                           (contlen != -1 ? contlen : 0),
1566                           keep_alive, &hs->dltime);
1567
1568   if (hs->res >= 0)
1569     CLOSE_FINISH (sock);
1570   else
1571     CLOSE_INVALIDATE (sock);
1572
1573   {
1574     /* Close or flush the file.  We have to be careful to check for
1575        error here.  Checking the result of fwrite() is not enough --
1576        errors could go unnoticed!  */
1577     int flush_res;
1578     if (!opt.dfp)
1579       flush_res = fclose (fp);
1580     else
1581       flush_res = fflush (fp);
1582     if (flush_res == EOF)
1583       hs->res = -2;
1584   }
1585   if (hs->res == -2)
1586     return FWRITEERR;
1587   return RETRFINISHED;
1588 }
1589
1590 /* The genuine HTTP loop!  This is the part where the retrieval is
1591    retried, and retried, and retried, and...  */
1592 uerr_t
1593 http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
1594            int *dt, struct url *proxy)
1595 {
1596   int count;
1597   int use_ts, got_head = 0;     /* time-stamping info */
1598   char *filename_plus_orig_suffix;
1599   char *local_filename = NULL;
1600   char *tms, *locf, *tmrate;
1601   uerr_t err;
1602   time_t tml = -1, tmr = -1;    /* local and remote time-stamps */
1603   long local_size = 0;          /* the size of the local file */
1604   size_t filename_len;
1605   struct http_stat hstat;       /* HTTP status */
1606   struct stat st;
1607   char *dummy = NULL;
1608
1609   /* This used to be done in main(), but it's a better idea to do it
1610      here so that we don't go through the hoops if we're just using
1611      FTP or whatever. */
1612   if (opt.cookies)
1613     {
1614       if (!wget_cookie_jar)
1615         wget_cookie_jar = cookie_jar_new ();
1616       if (opt.cookies_input && !cookies_loaded_p)
1617         {
1618           cookie_jar_load (wget_cookie_jar, opt.cookies_input);
1619           cookies_loaded_p = 1;
1620         }
1621     }
1622
1623   *newloc = NULL;
1624
1625   /* Warn on (likely bogus) wildcard usage in HTTP.  Don't use
1626      has_wildcards_p because it would also warn on `?', and we know that
1627      shows up in CGI paths a *lot*.  */
1628   if (strchr (u->url, '*'))
1629     logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
1630
1631   /* Determine the local filename.  */
1632   if (local_file && *local_file)
1633     hstat.local_file = local_file;
1634   else if (local_file)
1635     {
1636       *local_file = url_file_name (u);
1637       hstat.local_file = local_file;
1638     }
1639   else
1640     {
1641       dummy = url_file_name (u);
1642       hstat.local_file = &dummy;
1643     }
1644
1645   if (!opt.output_document)
1646     locf = *hstat.local_file;
1647   else
1648     locf = opt.output_document;
1649
1650   hstat.referer = referer;
1651
1652   filename_len = strlen (*hstat.local_file);
1653   filename_plus_orig_suffix = alloca (filename_len + sizeof (".orig"));
1654
1655   if (opt.noclobber && file_exists_p (*hstat.local_file))
1656     {
1657       /* If opt.noclobber is turned on and file already exists, do not
1658          retrieve the file */
1659       logprintf (LOG_VERBOSE, _("\
1660 File `%s' already there, will not retrieve.\n"), *hstat.local_file);
1661       /* If the file is there, we suppose it's retrieved OK.  */
1662       *dt |= RETROKF;
1663
1664       /* #### Bogusness alert.  */
1665       /* If its suffix is "html" or "htm" or similar, assume text/html.  */
1666       if (has_html_suffix_p (*hstat.local_file))
1667         *dt |= TEXTHTML;
1668
1669       xfree_null (dummy);
1670       return RETROK;
1671     }
1672
1673   use_ts = 0;
1674   if (opt.timestamping)
1675     {
1676       int local_dot_orig_file_exists = 0;
1677
1678       if (opt.backup_converted)
1679         /* If -K is specified, we'll act on the assumption that it was specified
1680            last time these files were downloaded as well, and instead of just
1681            comparing local file X against server file X, we'll compare local
1682            file X.orig (if extant, else X) against server file X.  If -K
1683            _wasn't_ specified last time, or the server contains files called
1684            *.orig, -N will be back to not operating correctly with -k. */
1685         {
1686           /* Would a single s[n]printf() call be faster?  --dan
1687
1688              Definitely not.  sprintf() is horribly slow.  It's a
1689              different question whether the difference between the two
1690              affects a program.  Usually I'd say "no", but at one
1691              point I profiled Wget, and found that a measurable and
1692              non-negligible amount of time was lost calling sprintf()
1693              in url.c.  Replacing sprintf with inline calls to
1694              strcpy() and long_to_string() made a difference.
1695              --hniksic */
1696           memcpy (filename_plus_orig_suffix, *hstat.local_file, filename_len);
1697           memcpy (filename_plus_orig_suffix + filename_len,
1698                   ".orig", sizeof (".orig"));
1699
1700           /* Try to stat() the .orig file. */
1701           if (stat (filename_plus_orig_suffix, &st) == 0)
1702             {
1703               local_dot_orig_file_exists = 1;
1704               local_filename = filename_plus_orig_suffix;
1705             }
1706         }      
1707
1708       if (!local_dot_orig_file_exists)
1709         /* Couldn't stat() <file>.orig, so try to stat() <file>. */
1710         if (stat (*hstat.local_file, &st) == 0)
1711           local_filename = *hstat.local_file;
1712
1713       if (local_filename != NULL)
1714         /* There was a local file, so we'll check later to see if the version
1715            the server has is the same version we already have, allowing us to
1716            skip a download. */
1717         {
1718           use_ts = 1;
1719           tml = st.st_mtime;
1720 #ifdef WINDOWS
1721           /* Modification time granularity is 2 seconds for Windows, so
1722              increase local time by 1 second for later comparison. */
1723           tml++;
1724 #endif
1725           local_size = st.st_size;
1726           got_head = 0;
1727         }
1728     }
1729   /* Reset the counter.  */
1730   count = 0;
1731   *dt = 0 | ACCEPTRANGES;
1732   /* THE loop */
1733   do
1734     {
1735       /* Increment the pass counter.  */
1736       ++count;
1737       sleep_between_retrievals (count);
1738       /* Get the current time string.  */
1739       tms = time_str (NULL);
1740       /* Print fetch message, if opt.verbose.  */
1741       if (opt.verbose)
1742         {
1743           char *hurl = url_string (u, 1);
1744           char tmp[15];
1745           strcpy (tmp, "        ");
1746           if (count > 1)
1747             sprintf (tmp, _("(try:%2d)"), count);
1748           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
1749                      tms, hurl, tmp, locf);
1750 #ifdef WINDOWS
1751           ws_changetitle (hurl, 1);
1752 #endif
1753           xfree (hurl);
1754         }
1755
1756       /* Default document type is empty.  However, if spider mode is
1757          on or time-stamping is employed, HEAD_ONLY commands is
1758          encoded within *dt.  */
1759       if (opt.spider || (use_ts && !got_head))
1760         *dt |= HEAD_ONLY;
1761       else
1762         *dt &= ~HEAD_ONLY;
1763       /* Assume no restarting.  */
1764       hstat.restval = 0L;
1765       /* Decide whether or not to restart.  */
1766       if (((count > 1 && (*dt & ACCEPTRANGES)) || opt.always_rest)
1767           /* #### this calls access() and then stat(); could be optimized. */
1768           && file_exists_p (locf))
1769         if (stat (locf, &st) == 0 && S_ISREG (st.st_mode))
1770           hstat.restval = st.st_size;
1771
1772       /* In `-c' is used and the file is existing and non-empty,
1773          refuse to truncate it if the server doesn't support continued
1774          downloads.  */
1775       hstat.no_truncate = 0;
1776       if (opt.always_rest && hstat.restval)
1777         hstat.no_truncate = 1;
1778
1779       /* Decide whether to send the no-cache directive.  We send it in
1780          two cases:
1781            a) we're using a proxy, and we're past our first retrieval.
1782               Some proxies are notorious for caching incomplete data, so
1783               we require a fresh get.
1784            b) caching is explicitly inhibited. */
1785       if ((proxy && count > 1)  /* a */
1786           || !opt.allow_cache   /* b */
1787           )
1788         *dt |= SEND_NOCACHE;
1789       else
1790         *dt &= ~SEND_NOCACHE;
1791
1792       /* Try fetching the document, or at least its head.  */
1793       err = gethttp (u, &hstat, dt, proxy);
1794
1795       /* It's unfortunate that wget determines the local filename before finding
1796          out the Content-Type of the file.  Barring a major restructuring of the
1797          code, we need to re-set locf here, since gethttp() may have xrealloc()d
1798          *hstat.local_file to tack on ".html". */
1799       if (!opt.output_document)
1800         locf = *hstat.local_file;
1801       else
1802         locf = opt.output_document;
1803
1804       /* Time?  */
1805       tms = time_str (NULL);
1806       /* Get the new location (with or without the redirection).  */
1807       if (hstat.newloc)
1808         *newloc = xstrdup (hstat.newloc);
1809       switch (err)
1810         {
1811         case HERR: case HEOF: case CONSOCKERR: case CONCLOSED:
1812         case CONERROR: case READERR: case WRITEFAILED:
1813         case RANGEERR:
1814           /* Non-fatal errors continue executing the loop, which will
1815              bring them to "while" statement at the end, to judge
1816              whether the number of tries was exceeded.  */
1817           free_hstat (&hstat);
1818           printwhat (count, opt.ntry);
1819           continue;
1820           break;
1821         case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case AUTHFAILED: 
1822         case SSLERRCTXCREATE: case CONTNOTSUPPORTED:
1823           /* Fatal errors just return from the function.  */
1824           free_hstat (&hstat);
1825           xfree_null (dummy);
1826           return err;
1827           break;
1828         case FWRITEERR: case FOPENERR:
1829           /* Another fatal error.  */
1830           logputs (LOG_VERBOSE, "\n");
1831           logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"),
1832                      *hstat.local_file, strerror (errno));
1833           free_hstat (&hstat);
1834           xfree_null (dummy);
1835           return err;
1836           break;
1837         case CONSSLERR:
1838           /* Another fatal error.  */
1839           logputs (LOG_VERBOSE, "\n");
1840           logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
1841           free_hstat (&hstat);
1842           xfree_null (dummy);
1843           return err;
1844           break;
1845         case NEWLOCATION:
1846           /* Return the new location to the caller.  */
1847           if (!hstat.newloc)
1848             {
1849               logprintf (LOG_NOTQUIET,
1850                          _("ERROR: Redirection (%d) without location.\n"),
1851                          hstat.statcode);
1852               free_hstat (&hstat);
1853               xfree_null (dummy);
1854               return WRONGCODE;
1855             }
1856           free_hstat (&hstat);
1857           xfree_null (dummy);
1858           return NEWLOCATION;
1859           break;
1860         case RETRUNNEEDED:
1861           /* The file was already fully retrieved. */
1862           free_hstat (&hstat);
1863           xfree_null (dummy);
1864           return RETROK;
1865           break;
1866         case RETRFINISHED:
1867           /* Deal with you later.  */
1868           break;
1869         default:
1870           /* All possibilities should have been exhausted.  */
1871           abort ();
1872         }
1873       if (!(*dt & RETROKF))
1874         {
1875           if (!opt.verbose)
1876             {
1877               /* #### Ugly ugly ugly! */
1878               char *hurl = url_string (u, 1);
1879               logprintf (LOG_NONVERBOSE, "%s:\n", hurl);
1880               xfree (hurl);
1881             }
1882           logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"),
1883                      tms, hstat.statcode, hstat.error);
1884           logputs (LOG_VERBOSE, "\n");
1885           free_hstat (&hstat);
1886           xfree_null (dummy);
1887           return WRONGCODE;
1888         }
1889
1890       /* Did we get the time-stamp?  */
1891       if (!got_head)
1892         {
1893           if (opt.timestamping && !hstat.remote_time)
1894             {
1895               logputs (LOG_NOTQUIET, _("\
1896 Last-modified header missing -- time-stamps turned off.\n"));
1897             }
1898           else if (hstat.remote_time)
1899             {
1900               /* Convert the date-string into struct tm.  */
1901               tmr = http_atotm (hstat.remote_time);
1902               if (tmr == (time_t) (-1))
1903                 logputs (LOG_VERBOSE, _("\
1904 Last-modified header invalid -- time-stamp ignored.\n"));
1905             }
1906         }
1907
1908       /* The time-stamping section.  */
1909       if (use_ts)
1910         {
1911           got_head = 1;
1912           *dt &= ~HEAD_ONLY;
1913           use_ts = 0;           /* no more time-stamping */
1914           count = 0;            /* the retrieve count for HEAD is
1915                                    reset */
1916           if (hstat.remote_time && tmr != (time_t) (-1))
1917             {
1918               /* Now time-stamping can be used validly.  Time-stamping
1919                  means that if the sizes of the local and remote file
1920                  match, and local file is newer than the remote file,
1921                  it will not be retrieved.  Otherwise, the normal
1922                  download procedure is resumed.  */
1923               if (tml >= tmr &&
1924                   (hstat.contlen == -1 || local_size == hstat.contlen))
1925                 {
1926                   logprintf (LOG_VERBOSE, _("\
1927 Server file no newer than local file `%s' -- not retrieving.\n\n"),
1928                              local_filename);
1929                   free_hstat (&hstat);
1930                   xfree_null (dummy);
1931                   return RETROK;
1932                 }
1933               else if (tml >= tmr)
1934                 logprintf (LOG_VERBOSE, _("\
1935 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1936               else
1937                 logputs (LOG_VERBOSE,
1938                          _("Remote file is newer, retrieving.\n"));
1939             }
1940           free_hstat (&hstat);
1941           continue;
1942         }
1943       if ((tmr != (time_t) (-1))
1944           && !opt.spider
1945           && ((hstat.len == hstat.contlen) ||
1946               ((hstat.res == 0) &&
1947                ((hstat.contlen == -1) ||
1948                 (hstat.len >= hstat.contlen && !opt.kill_longer)))))
1949         {
1950           /* #### This code repeats in http.c and ftp.c.  Move it to a
1951              function!  */
1952           const char *fl = NULL;
1953           if (opt.output_document)
1954             {
1955               if (opt.od_known_regular)
1956                 fl = opt.output_document;
1957             }
1958           else
1959             fl = *hstat.local_file;
1960           if (fl)
1961             touch (fl, tmr);
1962         }
1963       /* End of time-stamping section.  */
1964
1965       if (opt.spider)
1966         {
1967           logprintf (LOG_NOTQUIET, "%d %s\n\n", hstat.statcode, hstat.error);
1968           xfree_null (dummy);
1969           return RETROK;
1970         }
1971
1972       tmrate = retr_rate (hstat.len - hstat.restval, hstat.dltime, 0);
1973
1974       if (hstat.len == hstat.contlen)
1975         {
1976           if (*dt & RETROKF)
1977             {
1978               logprintf (LOG_VERBOSE,
1979                          _("%s (%s) - `%s' saved [%ld/%ld]\n\n"),
1980                          tms, tmrate, locf, hstat.len, hstat.contlen);
1981               logprintf (LOG_NONVERBOSE,
1982                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
1983                          tms, u->url, hstat.len, hstat.contlen, locf, count);
1984             }
1985           ++opt.numurls;
1986           total_downloaded_bytes += hstat.len;
1987
1988           /* Remember that we downloaded the file for later ".orig" code. */
1989           if (*dt & ADDED_HTML_EXTENSION)
1990             downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
1991           else
1992             downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1993
1994           free_hstat (&hstat);
1995           xfree_null (dummy);
1996           return RETROK;
1997         }
1998       else if (hstat.res == 0) /* No read error */
1999         {
2000           if (hstat.contlen == -1)  /* We don't know how much we were supposed
2001                                        to get, so assume we succeeded. */ 
2002             {
2003               if (*dt & RETROKF)
2004                 {
2005                   logprintf (LOG_VERBOSE,
2006                              _("%s (%s) - `%s' saved [%ld]\n\n"),
2007                              tms, tmrate, locf, hstat.len);
2008                   logprintf (LOG_NONVERBOSE,
2009                              "%s URL:%s [%ld] -> \"%s\" [%d]\n",
2010                              tms, u->url, hstat.len, locf, count);
2011                 }
2012               ++opt.numurls;
2013               total_downloaded_bytes += hstat.len;
2014
2015               /* Remember that we downloaded the file for later ".orig" code. */
2016               if (*dt & ADDED_HTML_EXTENSION)
2017                 downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
2018               else
2019                 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
2020               
2021               free_hstat (&hstat);
2022               xfree_null (dummy);
2023               return RETROK;
2024             }
2025           else if (hstat.len < hstat.contlen) /* meaning we lost the
2026                                                  connection too soon */
2027             {
2028               logprintf (LOG_VERBOSE,
2029                          _("%s (%s) - Connection closed at byte %ld. "),
2030                          tms, tmrate, hstat.len);
2031               printwhat (count, opt.ntry);
2032               free_hstat (&hstat);
2033               continue;
2034             }
2035           else if (!opt.kill_longer) /* meaning we got more than expected */
2036             {
2037               logprintf (LOG_VERBOSE,
2038                          _("%s (%s) - `%s' saved [%ld/%ld])\n\n"),
2039                          tms, tmrate, locf, hstat.len, hstat.contlen);
2040               logprintf (LOG_NONVERBOSE,
2041                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
2042                          tms, u->url, hstat.len, hstat.contlen, locf, count);
2043               ++opt.numurls;
2044               total_downloaded_bytes += hstat.len;
2045
2046               /* Remember that we downloaded the file for later ".orig" code. */
2047               if (*dt & ADDED_HTML_EXTENSION)
2048                 downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
2049               else
2050                 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
2051               
2052               free_hstat (&hstat);
2053               xfree_null (dummy);
2054               return RETROK;
2055             }
2056           else                  /* the same, but not accepted */
2057             {
2058               logprintf (LOG_VERBOSE,
2059                          _("%s (%s) - Connection closed at byte %ld/%ld. "),
2060                          tms, tmrate, hstat.len, hstat.contlen);
2061               printwhat (count, opt.ntry);
2062               free_hstat (&hstat);
2063               continue;
2064             }
2065         }
2066       else                      /* now hstat.res can only be -1 */
2067         {
2068           if (hstat.contlen == -1)
2069             {
2070               logprintf (LOG_VERBOSE,
2071                          _("%s (%s) - Read error at byte %ld (%s)."),
2072                          tms, tmrate, hstat.len, strerror (errno));
2073               printwhat (count, opt.ntry);
2074               free_hstat (&hstat);
2075               continue;
2076             }
2077           else                  /* hstat.res == -1 and contlen is given */
2078             {
2079               logprintf (LOG_VERBOSE,
2080                          _("%s (%s) - Read error at byte %ld/%ld (%s). "),
2081                          tms, tmrate, hstat.len, hstat.contlen,
2082                          strerror (errno));
2083               printwhat (count, opt.ntry);
2084               free_hstat (&hstat);
2085               continue;
2086             }
2087         }
2088       /* not reached */
2089       break;
2090     }
2091   while (!opt.ntry || (count < opt.ntry));
2092   return TRYLIMEXC;
2093 }
2094 \f
2095 /* Converts struct tm to time_t, assuming the data in tm is UTC rather
2096    than local timezone.
2097
2098    mktime is similar but assumes struct tm, also known as the
2099    "broken-down" form of time, is in local time zone.  mktime_from_utc
2100    uses mktime to make the conversion understanding that an offset
2101    will be introduced by the local time assumption.
2102
2103    mktime_from_utc then measures the introduced offset by applying
2104    gmtime to the initial result and applying mktime to the resulting
2105    "broken-down" form.  The difference between the two mktime results
2106    is the measured offset which is then subtracted from the initial
2107    mktime result to yield a calendar time which is the value returned.
2108
2109    tm_isdst in struct tm is set to 0 to force mktime to introduce a
2110    consistent offset (the non DST offset) since tm and tm+o might be
2111    on opposite sides of a DST change.
2112
2113    Some implementations of mktime return -1 for the nonexistent
2114    localtime hour at the beginning of DST.  In this event, use
2115    mktime(tm - 1hr) + 3600.
2116
2117    Schematically
2118      mktime(tm)   --> t+o
2119      gmtime(t+o)  --> tm+o
2120      mktime(tm+o) --> t+2o
2121      t+o - (t+2o - t+o) = t
2122
2123    Note that glibc contains a function of the same purpose named
2124    `timegm' (reverse of gmtime).  But obviously, it is not universally
2125    available, and unfortunately it is not straightforwardly
2126    extractable for use here.  Perhaps configure should detect timegm
2127    and use it where available.
2128
2129    Contributed by Roger Beeman <beeman@cisco.com>, with the help of
2130    Mark Baushke <mdb@cisco.com> and the rest of the Gurus at CISCO.
2131    Further improved by Roger with assistance from Edward J. Sabol
2132    based on input by Jamie Zawinski.  */
2133
2134 static time_t
2135 mktime_from_utc (struct tm *t)
2136 {
2137   time_t tl, tb;
2138   struct tm *tg;
2139
2140   tl = mktime (t);
2141   if (tl == -1)
2142     {
2143       t->tm_hour--;
2144       tl = mktime (t);
2145       if (tl == -1)
2146         return -1; /* can't deal with output from strptime */
2147       tl += 3600;
2148     }
2149   tg = gmtime (&tl);
2150   tg->tm_isdst = 0;
2151   tb = mktime (tg);
2152   if (tb == -1)
2153     {
2154       tg->tm_hour--;
2155       tb = mktime (tg);
2156       if (tb == -1)
2157         return -1; /* can't deal with output from gmtime */
2158       tb += 3600;
2159     }
2160   return (tl - (tb - tl));
2161 }
2162
2163 /* Check whether the result of strptime() indicates success.
2164    strptime() returns the pointer to how far it got to in the string.
2165    The processing has been successful if the string is at `GMT' or
2166    `+X', or at the end of the string.
2167
2168    In extended regexp parlance, the function returns 1 if P matches
2169    "^ *(GMT|[+-][0-9]|$)", 0 otherwise.  P being NULL (which strptime
2170    can return) is considered a failure and 0 is returned.  */
2171 static int
2172 check_end (const char *p)
2173 {
2174   if (!p)
2175     return 0;
2176   while (ISSPACE (*p))
2177     ++p;
2178   if (!*p
2179       || (p[0] == 'G' && p[1] == 'M' && p[2] == 'T')
2180       || ((p[0] == '+' || p[0] == '-') && ISDIGIT (p[1])))
2181     return 1;
2182   else
2183     return 0;
2184 }
2185
2186 /* Convert the textual specification of time in TIME_STRING to the
2187    number of seconds since the Epoch.
2188
2189    TIME_STRING can be in any of the three formats RFC2068 allows the
2190    HTTP servers to emit -- RFC1123-date, RFC850-date or asctime-date.
2191    Timezones are ignored, and should be GMT.
2192
2193    Return the computed time_t representation, or -1 if the conversion
2194    fails.
2195
2196    This function uses strptime with various string formats for parsing
2197    TIME_STRING.  This results in a parser that is not as lenient in
2198    interpreting TIME_STRING as I would like it to be.  Being based on
2199    strptime, it always allows shortened months, one-digit days, etc.,
2200    but due to the multitude of formats in which time can be
2201    represented, an ideal HTTP time parser would be even more
2202    forgiving.  It should completely ignore things like week days and
2203    concentrate only on the various forms of representing years,
2204    months, days, hours, minutes, and seconds.  For example, it would
2205    be nice if it accepted ISO 8601 out of the box.
2206
2207    I've investigated free and PD code for this purpose, but none was
2208    usable.  getdate was big and unwieldy, and had potential copyright
2209    issues, or so I was informed.  Dr. Marcus Hennecke's atotm(),
2210    distributed with phttpd, is excellent, but we cannot use it because
2211    it is not assigned to the FSF.  So I stuck it with strptime.  */
2212
2213 time_t
2214 http_atotm (const char *time_string)
2215 {
2216   /* NOTE: Solaris strptime man page claims that %n and %t match white
2217      space, but that's not universally available.  Instead, we simply
2218      use ` ' to mean "skip all WS", which works under all strptime
2219      implementations I've tested.  */
2220
2221   static const char *time_formats[] = {
2222     "%a, %d %b %Y %T",          /* RFC1123: Thu, 29 Jan 1998 22:12:57 */
2223     "%A, %d-%b-%y %T",          /* RFC850:  Thursday, 29-Jan-98 22:12:57 */
2224     "%a, %d-%b-%Y %T",          /* pseudo-RFC850:  Thu, 29-Jan-1998 22:12:57
2225                                    (google.com uses this for their cookies.) */
2226     "%a %b %d %T %Y"            /* asctime: Thu Jan 29 22:12:57 1998 */
2227   };
2228
2229   int i;
2230   struct tm t;
2231
2232   /* According to Roger Beeman, we need to initialize tm_isdst, since
2233      strptime won't do it.  */
2234   t.tm_isdst = 0;
2235
2236   /* Note that under foreign locales Solaris strptime() fails to
2237      recognize English dates, which renders this function useless.  We
2238      solve this by being careful not to affect LC_TIME when
2239      initializing locale.
2240
2241      Another solution would be to temporarily set locale to C, invoke
2242      strptime(), and restore it back.  This is slow and dirty,
2243      however, and locale support other than LC_MESSAGES can mess other
2244      things, so I rather chose to stick with just setting LC_MESSAGES.
2245
2246      GNU strptime does not have this problem because it recognizes
2247      both international and local dates.  */
2248
2249   for (i = 0; i < countof (time_formats); i++)
2250     if (check_end (strptime (time_string, time_formats[i], &t)))
2251       return mktime_from_utc (&t);
2252
2253   /* All formats have failed.  */
2254   return -1;
2255 }
2256 \f
2257 /* Authorization support: We support two authorization schemes:
2258
2259    * `Basic' scheme, consisting of base64-ing USER:PASSWORD string;
2260
2261    * `Digest' scheme, added by Junio Hamano <junio@twinsun.com>,
2262    consisting of answering to the server's challenge with the proper
2263    MD5 digests.  */
2264
2265 /* How many bytes it will take to store LEN bytes in base64.  */
2266 #define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
2267
2268 /* Encode the string S of length LENGTH to base64 format and place it
2269    to STORE.  STORE will be 0-terminated, and must point to a writable
2270    buffer of at least 1+BASE64_LENGTH(length) bytes.  */
2271 static void
2272 base64_encode (const char *s, char *store, int length)
2273 {
2274   /* Conversion table.  */
2275   static char tbl[64] = {
2276     'A','B','C','D','E','F','G','H',
2277     'I','J','K','L','M','N','O','P',
2278     'Q','R','S','T','U','V','W','X',
2279     'Y','Z','a','b','c','d','e','f',
2280     'g','h','i','j','k','l','m','n',
2281     'o','p','q','r','s','t','u','v',
2282     'w','x','y','z','0','1','2','3',
2283     '4','5','6','7','8','9','+','/'
2284   };
2285   int i;
2286   unsigned char *p = (unsigned char *)store;
2287
2288   /* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
2289   for (i = 0; i < length; i += 3)
2290     {
2291       *p++ = tbl[s[0] >> 2];
2292       *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
2293       *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
2294       *p++ = tbl[s[2] & 0x3f];
2295       s += 3;
2296     }
2297   /* Pad the result if necessary...  */
2298   if (i == length + 1)
2299     *(p - 1) = '=';
2300   else if (i == length + 2)
2301     *(p - 1) = *(p - 2) = '=';
2302   /* ...and zero-terminate it.  */
2303   *p = '\0';
2304 }
2305
2306 /* Create the authentication header contents for the `Basic' scheme.
2307    This is done by encoding the string `USER:PASS' in base64 and
2308    prepending `HEADER: Basic ' to it.  */
2309 static char *
2310 basic_authentication_encode (const char *user, const char *passwd,
2311                              const char *header)
2312 {
2313   char *t1, *t2, *res;
2314   int len1 = strlen (user) + 1 + strlen (passwd);
2315   int len2 = BASE64_LENGTH (len1);
2316
2317   t1 = (char *)alloca (len1 + 1);
2318   sprintf (t1, "%s:%s", user, passwd);
2319   t2 = (char *)alloca (1 + len2);
2320   base64_encode (t1, t2, len1);
2321   res = (char *)xmalloc (len2 + 11 + strlen (header));
2322   sprintf (res, "%s: Basic %s\r\n", header, t2);
2323
2324   return res;
2325 }
2326
2327 #define SKIP_WS(x) do {                         \
2328   while (ISSPACE (*(x)))                        \
2329     ++(x);                                      \
2330 } while (0)
2331
2332 #ifdef USE_DIGEST
2333 /* Parse HTTP `WWW-Authenticate:' header.  AU points to the beginning
2334    of a field in such a header.  If the field is the one specified by
2335    ATTR_NAME ("realm", "opaque", and "nonce" are used by the current
2336    digest authorization code), extract its value in the (char*)
2337    variable pointed by RET.  Returns negative on a malformed header,
2338    or number of bytes that have been parsed by this call.  */
2339 static int
2340 extract_header_attr (const char *au, const char *attr_name, char **ret)
2341 {
2342   const char *cp, *ep;
2343
2344   ep = cp = au;
2345
2346   if (strncmp (cp, attr_name, strlen (attr_name)) == 0)
2347     {
2348       cp += strlen (attr_name);
2349       if (!*cp)
2350         return -1;
2351       SKIP_WS (cp);
2352       if (*cp != '=')
2353         return -1;
2354       if (!*++cp)
2355         return -1;
2356       SKIP_WS (cp);
2357       if (*cp != '\"')
2358         return -1;
2359       if (!*++cp)
2360         return -1;
2361       for (ep = cp; *ep && *ep != '\"'; ep++)
2362         ;
2363       if (!*ep)
2364         return -1;
2365       xfree_null (*ret);
2366       *ret = strdupdelim (cp, ep);
2367       return ep - au + 1;
2368     }
2369   else
2370     return 0;
2371 }
2372
2373 /* Dump the hexadecimal representation of HASH to BUF.  HASH should be
2374    an array of 16 bytes containing the hash keys, and BUF should be a
2375    buffer of 33 writable characters (32 for hex digits plus one for
2376    zero termination).  */
2377 static void
2378 dump_hash (unsigned char *buf, const unsigned char *hash)
2379 {
2380   int i;
2381
2382   for (i = 0; i < MD5_HASHLEN; i++, hash++)
2383     {
2384       *buf++ = XNUM_TO_digit (*hash >> 4);
2385       *buf++ = XNUM_TO_digit (*hash & 0xf);
2386     }
2387   *buf = '\0';
2388 }
2389
2390 /* Take the line apart to find the challenge, and compose a digest
2391    authorization header.  See RFC2069 section 2.1.2.  */
2392 static char *
2393 digest_authentication_encode (const char *au, const char *user,
2394                               const char *passwd, const char *method,
2395                               const char *path)
2396 {
2397   static char *realm, *opaque, *nonce;
2398   static struct {
2399     const char *name;
2400     char **variable;
2401   } options[] = {
2402     { "realm", &realm },
2403     { "opaque", &opaque },
2404     { "nonce", &nonce }
2405   };
2406   char *res;
2407
2408   realm = opaque = nonce = NULL;
2409
2410   au += 6;                      /* skip over `Digest' */
2411   while (*au)
2412     {
2413       int i;
2414
2415       SKIP_WS (au);
2416       for (i = 0; i < countof (options); i++)
2417         {
2418           int skip = extract_header_attr (au, options[i].name,
2419                                           options[i].variable);
2420           if (skip < 0)
2421             {
2422               xfree_null (realm);
2423               xfree_null (opaque);
2424               xfree_null (nonce);
2425               return NULL;
2426             }
2427           else if (skip)
2428             {
2429               au += skip;
2430               break;
2431             }
2432         }
2433       if (i == countof (options))
2434         {
2435           while (*au && *au != '=')
2436             au++;
2437           if (*au && *++au)
2438             {
2439               SKIP_WS (au);
2440               if (*au == '\"')
2441                 {
2442                   au++;
2443                   while (*au && *au != '\"')
2444                     au++;
2445                   if (*au)
2446                     au++;
2447                 }
2448             }
2449         }
2450       while (*au && *au != ',')
2451         au++;
2452       if (*au)
2453         au++;
2454     }
2455   if (!realm || !nonce || !user || !passwd || !path || !method)
2456     {
2457       xfree_null (realm);
2458       xfree_null (opaque);
2459       xfree_null (nonce);
2460       return NULL;
2461     }
2462
2463   /* Calculate the digest value.  */
2464   {
2465     ALLOCA_MD5_CONTEXT (ctx);
2466     unsigned char hash[MD5_HASHLEN];
2467     unsigned char a1buf[MD5_HASHLEN * 2 + 1], a2buf[MD5_HASHLEN * 2 + 1];
2468     unsigned char response_digest[MD5_HASHLEN * 2 + 1];
2469
2470     /* A1BUF = H(user ":" realm ":" password) */
2471     gen_md5_init (ctx);
2472     gen_md5_update ((unsigned char *)user, strlen (user), ctx);
2473     gen_md5_update ((unsigned char *)":", 1, ctx);
2474     gen_md5_update ((unsigned char *)realm, strlen (realm), ctx);
2475     gen_md5_update ((unsigned char *)":", 1, ctx);
2476     gen_md5_update ((unsigned char *)passwd, strlen (passwd), ctx);
2477     gen_md5_finish (ctx, hash);
2478     dump_hash (a1buf, hash);
2479
2480     /* A2BUF = H(method ":" path) */
2481     gen_md5_init (ctx);
2482     gen_md5_update ((unsigned char *)method, strlen (method), ctx);
2483     gen_md5_update ((unsigned char *)":", 1, ctx);
2484     gen_md5_update ((unsigned char *)path, strlen (path), ctx);
2485     gen_md5_finish (ctx, hash);
2486     dump_hash (a2buf, hash);
2487
2488     /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */
2489     gen_md5_init (ctx);
2490     gen_md5_update (a1buf, MD5_HASHLEN * 2, ctx);
2491     gen_md5_update ((unsigned char *)":", 1, ctx);
2492     gen_md5_update ((unsigned char *)nonce, strlen (nonce), ctx);
2493     gen_md5_update ((unsigned char *)":", 1, ctx);
2494     gen_md5_update (a2buf, MD5_HASHLEN * 2, ctx);
2495     gen_md5_finish (ctx, hash);
2496     dump_hash (response_digest, hash);
2497
2498     res = (char*) xmalloc (strlen (user)
2499                            + strlen (user)
2500                            + strlen (realm)
2501                            + strlen (nonce)
2502                            + strlen (path)
2503                            + 2 * MD5_HASHLEN /*strlen (response_digest)*/
2504                            + (opaque ? strlen (opaque) : 0)
2505                            + 128);
2506     sprintf (res, "Authorization: Digest \
2507 username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
2508              user, realm, nonce, path, response_digest);
2509     if (opaque)
2510       {
2511         char *p = res + strlen (res);
2512         strcat (p, ", opaque=\"");
2513         strcat (p, opaque);
2514         strcat (p, "\"");
2515       }
2516     strcat (res, "\r\n");
2517   }
2518   return res;
2519 }
2520 #endif /* USE_DIGEST */
2521
2522
2523 #define BEGINS_WITH(line, string_constant)                              \
2524   (!strncasecmp (line, string_constant, sizeof (string_constant) - 1)   \
2525    && (ISSPACE (line[sizeof (string_constant) - 1])                     \
2526        || !line[sizeof (string_constant) - 1]))
2527
2528 static int
2529 known_authentication_scheme_p (const char *au)
2530 {
2531   return BEGINS_WITH (au, "Basic")
2532     || BEGINS_WITH (au, "Digest")
2533     || BEGINS_WITH (au, "NTLM");
2534 }
2535
2536 #undef BEGINS_WITH
2537
2538 /* Create the HTTP authorization request header.  When the
2539    `WWW-Authenticate' response header is seen, according to the
2540    authorization scheme specified in that header (`Basic' and `Digest'
2541    are supported by the current implementation), produce an
2542    appropriate HTTP authorization request header.  */
2543 static char *
2544 create_authorization_line (const char *au, const char *user,
2545                            const char *passwd, const char *method,
2546                            const char *path)
2547 {
2548   char *wwwauth = NULL;
2549
2550   if (!strncasecmp (au, "Basic", 5))
2551     wwwauth = basic_authentication_encode (user, passwd, "Authorization");
2552   if (!strncasecmp (au, "NTLM", 4))
2553     wwwauth = basic_authentication_encode (user, passwd, "Authorization");
2554 #ifdef USE_DIGEST
2555   else if (!strncasecmp (au, "Digest", 6))
2556     wwwauth = digest_authentication_encode (au, user, passwd, method, path);
2557 #endif /* USE_DIGEST */
2558   return wwwauth;
2559 }
2560 \f
2561 void
2562 http_cleanup (void)
2563 {
2564 }