]> sjero.net Git - wget/blob - src/http.c
ba445c4116ba4bf87ac18e1d1d4ec49c5ce49363
[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           /* Now that PROXYAUTH is part of the CONNECT request, zero
920              it out so we don't send proxy authorization with the
921              regular request below.  */
922           proxyauth = NULL;
923
924           DEBUGP (("Writing to proxy: [%s]\n", connect));
925           write_error = fd_write (sock, connect, strlen (connect), -1);
926           if (write_error < 0)
927             {
928               logprintf (LOG_VERBOSE, _("Failed writing to proxy: %s.\n"),
929                          strerror (errno));
930               CLOSE_INVALIDATE (sock);
931               return WRITEFAILED;
932             }
933
934           head = fd_read_http_head (sock);
935           if (!head)
936             {
937               logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
938                          strerror (errno));
939               CLOSE_INVALIDATE (sock);
940               return HERR;
941             }
942           message = NULL;
943           if (!*head)
944             {
945               xfree (head);
946               goto failed_tunnel;
947             }
948           DEBUGP (("proxy responded with: [%s]\n", head));
949
950           resp = response_new (head);
951           statcode = response_status (resp, &message);
952           response_free (resp);
953           if (statcode != 200)
954             {
955             failed_tunnel:
956               logprintf (LOG_NOTQUIET, _("Proxy tunneling failed: %s"),
957                          message ? message : "?");
958               xfree_null (message);
959               return CONSSLERR;
960             }
961           xfree (message);
962
963           /* SOCK is now *really* connected to u->host, so update CONN
964              to reflect this.  That way register_persistent will
965              register SOCK as being connected to u->host:u->port.  */
966           conn = u;
967         }
968
969       if (conn->scheme == SCHEME_HTTPS)
970         {
971           if (!ssl_connect (sock))
972             {
973               fd_close (sock);
974               return CONSSLERR;
975             }
976           using_ssl = 1;
977         }
978 #endif /* HAVE_SSL */
979     }
980
981   if (*dt & HEAD_ONLY)
982     command = "HEAD";
983   else if (opt.post_file_name || opt.post_data)
984     command = "POST";
985   else
986     command = "GET";
987
988   referer = NULL;
989   if (hs->referer)
990     {
991       referer = (char *)alloca (9 + strlen (hs->referer) + 3);
992       sprintf (referer, "Referer: %s\r\n", hs->referer);
993     }
994
995   if (*dt & SEND_NOCACHE)
996     pragma_h = "Pragma: no-cache\r\n";
997   else
998     pragma_h = "";
999
1000   if (hs->restval)
1001     {
1002       range = (char *)alloca (13 + numdigit (hs->restval) + 4);
1003       /* Gag me!  Some servers (e.g. WebSitePro) have been known to
1004          respond to the following `Range' format by generating a
1005          multipart/x-byte-ranges MIME document!  This MIME type was
1006          present in an old draft of the byteranges specification.
1007          HTTP/1.1 specifies a multipart/byte-ranges MIME type, but
1008          only if multiple non-overlapping ranges are requested --
1009          which Wget never does.  */
1010       sprintf (range, "Range: bytes=%ld-\r\n", hs->restval);
1011     }
1012   else
1013     range = NULL;
1014   if (opt.useragent)
1015     STRDUP_ALLOCA (useragent, opt.useragent);
1016   else
1017     {
1018       useragent = (char *)alloca (10 + strlen (version_string));
1019       sprintf (useragent, "Wget/%s", version_string);
1020     }
1021   /* Construct the authentication, if userid is present.  */
1022   user = u->user;
1023   passwd = u->passwd;
1024   search_netrc (u->host, (const char **)&user, (const char **)&passwd, 0);
1025   user = user ? user : opt.http_user;
1026   passwd = passwd ? passwd : opt.http_passwd;
1027
1028   wwwauth = NULL;
1029   if (user && passwd)
1030     {
1031       if (!authenticate_h)
1032         {
1033           /* We have the username and the password, but haven't tried
1034              any authorization yet.  Let's see if the "Basic" method
1035              works.  If not, we'll come back here and construct a
1036              proper authorization method with the right challenges.
1037
1038              If we didn't employ this kind of logic, every URL that
1039              requires authorization would have to be processed twice,
1040              which is very suboptimal and generates a bunch of false
1041              "unauthorized" errors in the server log.
1042
1043              #### But this logic also has a serious problem when used
1044              with stronger authentications: we *first* transmit the
1045              username and the password in clear text, and *then*
1046              attempt a stronger authentication scheme.  That cannot be
1047              right!  We are only fortunate that almost everyone still
1048              uses the `Basic' scheme anyway.
1049
1050              There should be an option to prevent this from happening,
1051              for those who use strong authentication schemes and value
1052              their passwords.  */
1053           wwwauth = basic_authentication_encode (user, passwd, "Authorization");
1054         }
1055       else
1056         {
1057           /* Use the full path, i.e. one that includes the leading
1058              slash and the query string, but is independent of proxy
1059              setting.  */
1060           char *pth = url_full_path (u);
1061           wwwauth = create_authorization_line (authenticate_h, user, passwd,
1062                                                command, pth);
1063           xfree (pth);
1064         }
1065     }
1066
1067   /* String of the form :PORT.  Used only for non-standard ports. */
1068   port_maybe = NULL;
1069   if (u->port != scheme_default_port (u->scheme))
1070     {
1071       port_maybe = (char *)alloca (numdigit (u->port) + 2);
1072       sprintf (port_maybe, ":%d", u->port);
1073     }
1074
1075   if (!inhibit_keep_alive)
1076     request_keep_alive = "Connection: Keep-Alive\r\n";
1077   else
1078     request_keep_alive = NULL;
1079
1080   if (opt.cookies)
1081     cookies = cookie_header (wget_cookie_jar, u->host, u->port, u->path,
1082 #ifdef HAVE_SSL
1083                              u->scheme == SCHEME_HTTPS
1084 #else
1085                              0
1086 #endif
1087                              );
1088
1089   if (opt.post_data || opt.post_file_name)
1090     {
1091       post_content_type = "Content-Type: application/x-www-form-urlencoded\r\n";
1092       if (opt.post_data)
1093         post_data_size = strlen (opt.post_data);
1094       else
1095         {
1096           post_data_size = file_size (opt.post_file_name);
1097           if (post_data_size == -1)
1098             {
1099               logprintf (LOG_NOTQUIET, "POST data file missing: %s\n",
1100                          opt.post_file_name);
1101               post_data_size = 0;
1102             }
1103         }
1104       post_content_length = xmalloc (16 + numdigit (post_data_size) + 2 + 1);
1105       sprintf (post_content_length,
1106                "Content-Length: %ld\r\n", post_data_size);
1107     }
1108
1109   if (proxy)
1110     full_path = xstrdup (u->url);
1111   else
1112     /* Use the full path, i.e. one that includes the leading slash and
1113        the query string.  E.g. if u->path is "foo/bar" and u->query is
1114        "param=value", full_path will be "/foo/bar?param=value".  */
1115     full_path = url_full_path (u);
1116
1117   if (strchr (u->host, ':'))
1118     squares_around_host = 1;
1119
1120   /* Allocate the memory for the request.  */
1121   request = (char *)alloca (strlen (command)
1122                             + strlen (full_path)
1123                             + strlen (useragent)
1124                             + strlen (u->host)
1125                             + (port_maybe ? strlen (port_maybe) : 0)
1126                             + strlen (HTTP_ACCEPT)
1127                             + (request_keep_alive
1128                                ? strlen (request_keep_alive) : 0)
1129                             + (referer ? strlen (referer) : 0)
1130                             + (cookies ? strlen (cookies) : 0)
1131                             + (wwwauth ? strlen (wwwauth) : 0)
1132                             + (proxyauth ? strlen (proxyauth) : 0)
1133                             + (range ? strlen (range) : 0)
1134                             + strlen (pragma_h)
1135                             + (post_content_type
1136                                ? strlen (post_content_type) : 0)
1137                             + (post_content_length
1138                                ? strlen (post_content_length) : 0)
1139                             + (opt.user_header ? strlen (opt.user_header) : 0)
1140                             + 64);
1141   /* Construct the request.  */
1142   sprintf (request, "\
1143 %s %s HTTP/1.0\r\n\
1144 User-Agent: %s\r\n\
1145 Host: %s%s%s%s\r\n\
1146 Accept: %s\r\n\
1147 %s%s%s%s%s%s%s%s%s%s\r\n",
1148            command, full_path,
1149            useragent,
1150            squares_around_host ? "[" : "", u->host, squares_around_host ? "]" : "",
1151            port_maybe ? port_maybe : "",
1152            HTTP_ACCEPT,
1153            request_keep_alive ? request_keep_alive : "",
1154            referer ? referer : "",
1155            cookies ? cookies : "", 
1156            wwwauth ? wwwauth : "", 
1157            proxyauth ? proxyauth : "", 
1158            range ? range : "",
1159            pragma_h,
1160            post_content_type ? post_content_type : "",
1161            post_content_length ? post_content_length : "",
1162            opt.user_header ? opt.user_header : "");
1163   DEBUGP (("\n---request begin---\n%s", request));
1164
1165   /* Free the temporary memory.  */
1166   xfree_null (wwwauth);
1167   xfree_null (proxyauth);
1168   xfree_null (cookies);
1169   xfree (full_path);
1170
1171   /* Send the request to server.  */
1172   write_error = fd_write (sock, request, strlen (request), -1);
1173
1174   if (write_error >= 0)
1175     {
1176       if (opt.post_data)
1177         {
1178           DEBUGP (("[POST data: %s]\n", opt.post_data));
1179           write_error = fd_write (sock, opt.post_data, post_data_size, -1);
1180         }
1181       else if (opt.post_file_name && post_data_size != 0)
1182         write_error = post_file (sock, opt.post_file_name, post_data_size);
1183     }
1184   DEBUGP (("---request end---\n"));
1185
1186   if (write_error < 0)
1187     {
1188       logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
1189                  strerror (errno));
1190       CLOSE_INVALIDATE (sock);
1191       return WRITEFAILED;
1192     }
1193   logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "),
1194              proxy ? "Proxy" : "HTTP");
1195   contlen = contrange = -1;
1196   type = NULL;
1197   statcode = -1;
1198   *dt &= ~RETROKF;
1199
1200   head = fd_read_http_head (sock);
1201   if (!head)
1202     {
1203       logputs (LOG_VERBOSE, "\n");
1204       if (errno == 0)
1205         {
1206           logputs (LOG_NOTQUIET, _("No data received.\n"));
1207           CLOSE_INVALIDATE (sock);
1208           return HEOF;
1209         }
1210       else
1211         {
1212           logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
1213                      strerror (errno));
1214           CLOSE_INVALIDATE (sock);
1215           return HERR;
1216         }
1217     }
1218   DEBUGP (("\n---response begin---\n%s---response end---\n", head));
1219
1220   resp = response_new (head);
1221
1222   /* Check for status line.  */
1223   message = NULL;
1224   statcode = response_status (resp, &message);
1225   if (!opt.server_response)
1226     logprintf (LOG_VERBOSE, "%2d %s\n", statcode, message ? message : "");
1227   else
1228     {
1229       logprintf (LOG_VERBOSE, "\n");
1230       print_server_response (resp);
1231     }
1232
1233   hs->statcode = statcode;
1234   if (statcode == -1)
1235     hs->error = xstrdup (_("Malformed status line"));
1236   else if (!*message)
1237     hs->error = xstrdup (_("(no description)"));
1238   else
1239     hs->error = xstrdup (message);
1240
1241   if (response_header_copy (resp, "Content-Length", hdrval, sizeof (hdrval)))
1242     contlen = strtol (hdrval, NULL, 10);
1243   type = response_header_strdup (resp, "Content-Type");
1244   if (type)
1245     {
1246       char *tmp = strchr (type, ';');
1247       if (tmp)
1248         {
1249           while (tmp > type && ISSPACE (tmp[-1]))
1250             --tmp;
1251           *tmp = '\0';
1252         }
1253     }
1254   hs->newloc = response_header_strdup (resp, "Location");
1255   hs->remote_time = response_header_strdup (resp, "Last-Modified");
1256   set_cookie = response_header_strdup (resp, "Set-Cookie");
1257   if (set_cookie)
1258     {
1259       /* The jar should have been created by now. */
1260       assert (wget_cookie_jar != NULL);
1261       cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port, u->path,
1262                                 set_cookie);
1263       xfree (set_cookie);
1264     }
1265   authenticate_h = response_header_strdup (resp, "WWW-Authenticate");
1266   if (response_header_copy (resp, "Content-Range", hdrval, sizeof (hdrval)))
1267     {
1268       long first_byte_pos, last_byte_pos, entity_length;
1269       if (parse_content_range (hdrval, &first_byte_pos, &last_byte_pos,
1270                                &entity_length))
1271         contrange = first_byte_pos;
1272     }
1273
1274   /* Check for keep-alive related responses. */
1275   if (!inhibit_keep_alive && contlen != -1)
1276     {
1277       if (response_header_copy (resp, "Keep-Alive", NULL, 0))
1278         keep_alive = 1;
1279       else if (response_header_copy (resp, "Connection", hdrval,
1280                                      sizeof (hdrval)))
1281         {
1282           if (0 == strcasecmp (hdrval, "Keep-Alive"))
1283             keep_alive = 1;
1284         }
1285     }
1286   response_free (resp);
1287
1288   if (keep_alive)
1289     /* The server has promised that it will not close the connection
1290        when we're done.  This means that we can register it.  */
1291     register_persistent (conn->host, conn->port, sock, using_ssl);
1292
1293   if ((statcode == HTTP_STATUS_UNAUTHORIZED)
1294       && authenticate_h)
1295     {
1296       /* Authorization is required.  */
1297       xfree_null (type);
1298       type = NULL;
1299       free_hstat (hs);
1300       CLOSE_INVALIDATE (sock);  /* would be CLOSE_FINISH, but there
1301                                    might be more bytes in the body. */
1302       if (auth_tried_already)
1303         {
1304           /* If we have tried it already, then there is not point
1305              retrying it.  */
1306         failed:
1307           logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
1308           xfree (authenticate_h);
1309           return AUTHFAILED;
1310         }
1311       else if (!known_authentication_scheme_p (authenticate_h))
1312         {
1313           xfree (authenticate_h);
1314           logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n"));
1315           return AUTHFAILED;
1316         }
1317       else if (BEGINS_WITH (authenticate_h, "Basic"))
1318         {
1319           /* The authentication scheme is basic, the one we try by
1320              default, and it failed.  There's no sense in trying
1321              again.  */
1322           goto failed;
1323         }
1324       else
1325         {
1326           auth_tried_already = 1;
1327           goto again;
1328         }
1329     }
1330   /* We do not need this anymore.  */
1331   if (authenticate_h)
1332     {
1333       xfree (authenticate_h);
1334       authenticate_h = NULL;
1335     }
1336
1337   /* 20x responses are counted among successful by default.  */
1338   if (H_20X (statcode))
1339     *dt |= RETROKF;
1340
1341   /* Return if redirected.  */
1342   if (H_REDIRECTED (statcode) || statcode == HTTP_STATUS_MULTIPLE_CHOICES)
1343     {
1344       /* RFC2068 says that in case of the 300 (multiple choices)
1345          response, the server can output a preferred URL through
1346          `Location' header; otherwise, the request should be treated
1347          like GET.  So, if the location is set, it will be a
1348          redirection; otherwise, just proceed normally.  */
1349       if (statcode == HTTP_STATUS_MULTIPLE_CHOICES && !hs->newloc)
1350         *dt |= RETROKF;
1351       else
1352         {
1353           logprintf (LOG_VERBOSE,
1354                      _("Location: %s%s\n"),
1355                      hs->newloc ? hs->newloc : _("unspecified"),
1356                      hs->newloc ? _(" [following]") : "");
1357           CLOSE_INVALIDATE (sock);      /* would be CLOSE_FINISH, but there
1358                                            might be more bytes in the body. */
1359           xfree_null (type);
1360           return NEWLOCATION;
1361         }
1362     }
1363
1364   /* If content-type is not given, assume text/html.  This is because
1365      of the multitude of broken CGI's that "forget" to generate the
1366      content-type.  */
1367   if (!type ||
1368         0 == strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)) ||
1369         0 == strncasecmp (type, TEXTXHTML_S, strlen (TEXTXHTML_S)))
1370     *dt |= TEXTHTML;
1371   else
1372     *dt &= ~TEXTHTML;
1373
1374   if (opt.html_extension && (*dt & TEXTHTML))
1375     /* -E / --html-extension / html_extension = on was specified, and this is a
1376        text/html file.  If some case-insensitive variation on ".htm[l]" isn't
1377        already the file's suffix, tack on ".html". */
1378     {
1379       char*  last_period_in_local_filename = strrchr(*hs->local_file, '.');
1380
1381       if (last_period_in_local_filename == NULL
1382           || !(0 == strcasecmp (last_period_in_local_filename, ".htm")
1383                || 0 == strcasecmp (last_period_in_local_filename, ".html")))
1384         {
1385           size_t  local_filename_len = strlen(*hs->local_file);
1386           
1387           *hs->local_file = xrealloc(*hs->local_file,
1388                                      local_filename_len + sizeof(".html"));
1389           strcpy(*hs->local_file + local_filename_len, ".html");
1390
1391           *dt |= ADDED_HTML_EXTENSION;
1392         }
1393     }
1394
1395   if (contrange == -1)
1396     {
1397       /* We did not get a content-range header.  This means that the
1398          server did not honor our `Range' request.  Normally, this
1399          means we should reset hs->restval and continue normally.  */
1400
1401       /* However, if `-c' is used, we need to be a bit more careful:
1402
1403          1. If `-c' is specified and the file already existed when
1404          Wget was started, it would be a bad idea for us to start
1405          downloading it from scratch, effectively truncating it.  I
1406          believe this cannot happen unless `-c' was specified.
1407
1408          2. If `-c' is used on a file that is already fully
1409          downloaded, we're requesting bytes after the end of file,
1410          which can result in server not honoring `Range'.  If this is
1411          the case, `Content-Length' will be equal to the length of the
1412          file.  */
1413       if (opt.always_rest)
1414         {
1415           /* Check for condition #2. */
1416           if (hs->restval > 0               /* restart was requested. */
1417               && contlen != -1              /* we got content-length. */
1418               && hs->restval >= contlen     /* file fully downloaded
1419                                                or has shrunk.  */
1420               )
1421             {
1422               logputs (LOG_VERBOSE, _("\
1423 \n    The file is already fully retrieved; nothing to do.\n\n"));
1424               /* In case the caller inspects. */
1425               hs->len = contlen;
1426               hs->res = 0;
1427               /* Mark as successfully retrieved. */
1428               *dt |= RETROKF;
1429               xfree_null (type);
1430               CLOSE_INVALIDATE (sock);  /* would be CLOSE_FINISH, but there
1431                                            might be more bytes in the body. */
1432               return RETRUNNEEDED;
1433             }
1434
1435           /* Check for condition #1. */
1436           if (hs->no_truncate)
1437             {
1438               logprintf (LOG_NOTQUIET,
1439                          _("\
1440 \n\
1441 Continued download failed on this file, which conflicts with `-c'.\n\
1442 Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
1443               xfree_null (type);
1444               CLOSE_INVALIDATE (sock);
1445               return CONTNOTSUPPORTED;
1446             }
1447
1448           /* Fallthrough */
1449         }
1450
1451       hs->restval = 0;
1452     }
1453   else if (contrange != hs->restval ||
1454            (H_PARTIAL (statcode) && contrange == -1))
1455     {
1456       /* This means the whole request was somehow misunderstood by the
1457          server.  Bail out.  */
1458       xfree_null (type);
1459       CLOSE_INVALIDATE (sock);
1460       return RANGEERR;
1461     }
1462
1463   if (hs->restval)
1464     {
1465       if (contlen != -1)
1466         contlen += contrange;
1467       else
1468         contrange = -1;        /* If conent-length was not sent,
1469                                   content-range will be ignored.  */
1470     }
1471   hs->contlen = contlen;
1472
1473   if (opt.verbose)
1474     {
1475       if ((*dt & RETROKF) && !opt.server_response)
1476         {
1477           /* No need to print this output if the body won't be
1478              downloaded at all, or if the original server response is
1479              printed.  */
1480           logputs (LOG_VERBOSE, _("Length: "));
1481           if (contlen != -1)
1482             {
1483               logputs (LOG_VERBOSE, legible (contlen));
1484               if (contrange != -1)
1485                 logprintf (LOG_VERBOSE, _(" (%s to go)"),
1486                            legible (contlen - contrange));
1487             }
1488           else
1489             logputs (LOG_VERBOSE,
1490                      opt.ignore_length ? _("ignored") : _("unspecified"));
1491           if (type)
1492             logprintf (LOG_VERBOSE, " [%s]\n", type);
1493           else
1494             logputs (LOG_VERBOSE, "\n");
1495         }
1496     }
1497   xfree_null (type);
1498   type = NULL;                  /* We don't need it any more.  */
1499
1500   /* Return if we have no intention of further downloading.  */
1501   if (!(*dt & RETROKF) || (*dt & HEAD_ONLY))
1502     {
1503       /* In case the caller cares to look...  */
1504       hs->len = 0L;
1505       hs->res = 0;
1506       xfree_null (type);
1507       CLOSE_INVALIDATE (sock);  /* would be CLOSE_FINISH, but there
1508                                    might be more bytes in the body. */
1509       return RETRFINISHED;
1510     }
1511
1512   /* Open the local file.  */
1513   if (!opt.dfp)
1514     {
1515       mkalldirs (*hs->local_file);
1516       if (opt.backups)
1517         rotate_backups (*hs->local_file);
1518       fp = fopen (*hs->local_file, hs->restval ? "ab" : "wb");
1519       if (!fp)
1520         {
1521           logprintf (LOG_NOTQUIET, "%s: %s\n", *hs->local_file, strerror (errno));
1522           CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
1523                                       might be more bytes in the body. */
1524           return FOPENERR;
1525         }
1526     }
1527   else                          /* opt.dfp */
1528     {
1529       extern int global_download_count;
1530       fp = opt.dfp;
1531       /* To ensure that repeated "from scratch" downloads work for -O
1532          files, we rewind the file pointer, unless restval is
1533          non-zero.  (This works only when -O is used on regular files,
1534          but it's still a valuable feature.)
1535
1536          However, this loses when more than one URL is specified on
1537          the command line the second rewinds eradicates the contents
1538          of the first download.  Thus we disable the above trick for
1539          all the downloads except the very first one.
1540
1541          #### A possible solution to this would be to remember the
1542          file position in the output document and to seek to that
1543          position, instead of rewinding.
1544
1545          We don't truncate stdout, since that breaks
1546          "wget -O - [...] >> foo".
1547       */
1548       if (!hs->restval && global_download_count == 0 && opt.dfp != stdout)
1549         {
1550           /* This will silently fail for streams that don't correspond
1551              to regular files, but that's OK.  */
1552           rewind (fp);
1553           /* ftruncate is needed because opt.dfp is opened in append
1554              mode if opt.always_rest is set.  */
1555           ftruncate (fileno (fp), 0);
1556           clearerr (fp);
1557         }
1558     }
1559
1560   /* #### This confuses the code that checks for file size.  There
1561      should be some overhead information.  */
1562   if (opt.save_headers)
1563     fwrite (head, 1, strlen (head), fp);
1564
1565   /* Get the contents of the document.  */
1566   hs->res = fd_read_body (sock, fp, &hs->len, hs->restval,
1567                           (contlen != -1 ? contlen : 0),
1568                           keep_alive, &hs->dltime);
1569
1570   if (hs->res >= 0)
1571     CLOSE_FINISH (sock);
1572   else
1573     CLOSE_INVALIDATE (sock);
1574
1575   {
1576     /* Close or flush the file.  We have to be careful to check for
1577        error here.  Checking the result of fwrite() is not enough --
1578        errors could go unnoticed!  */
1579     int flush_res;
1580     if (!opt.dfp)
1581       flush_res = fclose (fp);
1582     else
1583       flush_res = fflush (fp);
1584     if (flush_res == EOF)
1585       hs->res = -2;
1586   }
1587   if (hs->res == -2)
1588     return FWRITEERR;
1589   return RETRFINISHED;
1590 }
1591
1592 /* The genuine HTTP loop!  This is the part where the retrieval is
1593    retried, and retried, and retried, and...  */
1594 uerr_t
1595 http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
1596            int *dt, struct url *proxy)
1597 {
1598   int count;
1599   int use_ts, got_head = 0;     /* time-stamping info */
1600   char *filename_plus_orig_suffix;
1601   char *local_filename = NULL;
1602   char *tms, *locf, *tmrate;
1603   uerr_t err;
1604   time_t tml = -1, tmr = -1;    /* local and remote time-stamps */
1605   long local_size = 0;          /* the size of the local file */
1606   size_t filename_len;
1607   struct http_stat hstat;       /* HTTP status */
1608   struct stat st;
1609   char *dummy = NULL;
1610
1611   /* This used to be done in main(), but it's a better idea to do it
1612      here so that we don't go through the hoops if we're just using
1613      FTP or whatever. */
1614   if (opt.cookies)
1615     {
1616       if (!wget_cookie_jar)
1617         wget_cookie_jar = cookie_jar_new ();
1618       if (opt.cookies_input && !cookies_loaded_p)
1619         {
1620           cookie_jar_load (wget_cookie_jar, opt.cookies_input);
1621           cookies_loaded_p = 1;
1622         }
1623     }
1624
1625   *newloc = NULL;
1626
1627   /* Warn on (likely bogus) wildcard usage in HTTP.  Don't use
1628      has_wildcards_p because it would also warn on `?', and we know that
1629      shows up in CGI paths a *lot*.  */
1630   if (strchr (u->url, '*'))
1631     logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
1632
1633   /* Determine the local filename.  */
1634   if (local_file && *local_file)
1635     hstat.local_file = local_file;
1636   else if (local_file)
1637     {
1638       *local_file = url_file_name (u);
1639       hstat.local_file = local_file;
1640     }
1641   else
1642     {
1643       dummy = url_file_name (u);
1644       hstat.local_file = &dummy;
1645     }
1646
1647   if (!opt.output_document)
1648     locf = *hstat.local_file;
1649   else
1650     locf = opt.output_document;
1651
1652   hstat.referer = referer;
1653
1654   filename_len = strlen (*hstat.local_file);
1655   filename_plus_orig_suffix = alloca (filename_len + sizeof (".orig"));
1656
1657   if (opt.noclobber && file_exists_p (*hstat.local_file))
1658     {
1659       /* If opt.noclobber is turned on and file already exists, do not
1660          retrieve the file */
1661       logprintf (LOG_VERBOSE, _("\
1662 File `%s' already there, will not retrieve.\n"), *hstat.local_file);
1663       /* If the file is there, we suppose it's retrieved OK.  */
1664       *dt |= RETROKF;
1665
1666       /* #### Bogusness alert.  */
1667       /* If its suffix is "html" or "htm" or similar, assume text/html.  */
1668       if (has_html_suffix_p (*hstat.local_file))
1669         *dt |= TEXTHTML;
1670
1671       xfree_null (dummy);
1672       return RETROK;
1673     }
1674
1675   use_ts = 0;
1676   if (opt.timestamping)
1677     {
1678       int local_dot_orig_file_exists = 0;
1679
1680       if (opt.backup_converted)
1681         /* If -K is specified, we'll act on the assumption that it was specified
1682            last time these files were downloaded as well, and instead of just
1683            comparing local file X against server file X, we'll compare local
1684            file X.orig (if extant, else X) against server file X.  If -K
1685            _wasn't_ specified last time, or the server contains files called
1686            *.orig, -N will be back to not operating correctly with -k. */
1687         {
1688           /* Would a single s[n]printf() call be faster?  --dan
1689
1690              Definitely not.  sprintf() is horribly slow.  It's a
1691              different question whether the difference between the two
1692              affects a program.  Usually I'd say "no", but at one
1693              point I profiled Wget, and found that a measurable and
1694              non-negligible amount of time was lost calling sprintf()
1695              in url.c.  Replacing sprintf with inline calls to
1696              strcpy() and long_to_string() made a difference.
1697              --hniksic */
1698           memcpy (filename_plus_orig_suffix, *hstat.local_file, filename_len);
1699           memcpy (filename_plus_orig_suffix + filename_len,
1700                   ".orig", sizeof (".orig"));
1701
1702           /* Try to stat() the .orig file. */
1703           if (stat (filename_plus_orig_suffix, &st) == 0)
1704             {
1705               local_dot_orig_file_exists = 1;
1706               local_filename = filename_plus_orig_suffix;
1707             }
1708         }      
1709
1710       if (!local_dot_orig_file_exists)
1711         /* Couldn't stat() <file>.orig, so try to stat() <file>. */
1712         if (stat (*hstat.local_file, &st) == 0)
1713           local_filename = *hstat.local_file;
1714
1715       if (local_filename != NULL)
1716         /* There was a local file, so we'll check later to see if the version
1717            the server has is the same version we already have, allowing us to
1718            skip a download. */
1719         {
1720           use_ts = 1;
1721           tml = st.st_mtime;
1722 #ifdef WINDOWS
1723           /* Modification time granularity is 2 seconds for Windows, so
1724              increase local time by 1 second for later comparison. */
1725           tml++;
1726 #endif
1727           local_size = st.st_size;
1728           got_head = 0;
1729         }
1730     }
1731   /* Reset the counter.  */
1732   count = 0;
1733   *dt = 0 | ACCEPTRANGES;
1734   /* THE loop */
1735   do
1736     {
1737       /* Increment the pass counter.  */
1738       ++count;
1739       sleep_between_retrievals (count);
1740       /* Get the current time string.  */
1741       tms = time_str (NULL);
1742       /* Print fetch message, if opt.verbose.  */
1743       if (opt.verbose)
1744         {
1745           char *hurl = url_string (u, 1);
1746           char tmp[15];
1747           strcpy (tmp, "        ");
1748           if (count > 1)
1749             sprintf (tmp, _("(try:%2d)"), count);
1750           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
1751                      tms, hurl, tmp, locf);
1752 #ifdef WINDOWS
1753           ws_changetitle (hurl, 1);
1754 #endif
1755           xfree (hurl);
1756         }
1757
1758       /* Default document type is empty.  However, if spider mode is
1759          on or time-stamping is employed, HEAD_ONLY commands is
1760          encoded within *dt.  */
1761       if (opt.spider || (use_ts && !got_head))
1762         *dt |= HEAD_ONLY;
1763       else
1764         *dt &= ~HEAD_ONLY;
1765       /* Assume no restarting.  */
1766       hstat.restval = 0L;
1767       /* Decide whether or not to restart.  */
1768       if (((count > 1 && (*dt & ACCEPTRANGES)) || opt.always_rest)
1769           /* #### this calls access() and then stat(); could be optimized. */
1770           && file_exists_p (locf))
1771         if (stat (locf, &st) == 0 && S_ISREG (st.st_mode))
1772           hstat.restval = st.st_size;
1773
1774       /* In `-c' is used and the file is existing and non-empty,
1775          refuse to truncate it if the server doesn't support continued
1776          downloads.  */
1777       hstat.no_truncate = 0;
1778       if (opt.always_rest && hstat.restval)
1779         hstat.no_truncate = 1;
1780
1781       /* Decide whether to send the no-cache directive.  We send it in
1782          two cases:
1783            a) we're using a proxy, and we're past our first retrieval.
1784               Some proxies are notorious for caching incomplete data, so
1785               we require a fresh get.
1786            b) caching is explicitly inhibited. */
1787       if ((proxy && count > 1)  /* a */
1788           || !opt.allow_cache   /* b */
1789           )
1790         *dt |= SEND_NOCACHE;
1791       else
1792         *dt &= ~SEND_NOCACHE;
1793
1794       /* Try fetching the document, or at least its head.  */
1795       err = gethttp (u, &hstat, dt, proxy);
1796
1797       /* It's unfortunate that wget determines the local filename before finding
1798          out the Content-Type of the file.  Barring a major restructuring of the
1799          code, we need to re-set locf here, since gethttp() may have xrealloc()d
1800          *hstat.local_file to tack on ".html". */
1801       if (!opt.output_document)
1802         locf = *hstat.local_file;
1803       else
1804         locf = opt.output_document;
1805
1806       /* Time?  */
1807       tms = time_str (NULL);
1808       /* Get the new location (with or without the redirection).  */
1809       if (hstat.newloc)
1810         *newloc = xstrdup (hstat.newloc);
1811       switch (err)
1812         {
1813         case HERR: case HEOF: case CONSOCKERR: case CONCLOSED:
1814         case CONERROR: case READERR: case WRITEFAILED:
1815         case RANGEERR:
1816           /* Non-fatal errors continue executing the loop, which will
1817              bring them to "while" statement at the end, to judge
1818              whether the number of tries was exceeded.  */
1819           free_hstat (&hstat);
1820           printwhat (count, opt.ntry);
1821           continue;
1822           break;
1823         case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case AUTHFAILED: 
1824         case SSLERRCTXCREATE: case CONTNOTSUPPORTED:
1825           /* Fatal errors just return from the function.  */
1826           free_hstat (&hstat);
1827           xfree_null (dummy);
1828           return err;
1829           break;
1830         case FWRITEERR: case FOPENERR:
1831           /* Another fatal error.  */
1832           logputs (LOG_VERBOSE, "\n");
1833           logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"),
1834                      *hstat.local_file, strerror (errno));
1835           free_hstat (&hstat);
1836           xfree_null (dummy);
1837           return err;
1838           break;
1839         case CONSSLERR:
1840           /* Another fatal error.  */
1841           logputs (LOG_VERBOSE, "\n");
1842           logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
1843           free_hstat (&hstat);
1844           xfree_null (dummy);
1845           return err;
1846           break;
1847         case NEWLOCATION:
1848           /* Return the new location to the caller.  */
1849           if (!hstat.newloc)
1850             {
1851               logprintf (LOG_NOTQUIET,
1852                          _("ERROR: Redirection (%d) without location.\n"),
1853                          hstat.statcode);
1854               free_hstat (&hstat);
1855               xfree_null (dummy);
1856               return WRONGCODE;
1857             }
1858           free_hstat (&hstat);
1859           xfree_null (dummy);
1860           return NEWLOCATION;
1861           break;
1862         case RETRUNNEEDED:
1863           /* The file was already fully retrieved. */
1864           free_hstat (&hstat);
1865           xfree_null (dummy);
1866           return RETROK;
1867           break;
1868         case RETRFINISHED:
1869           /* Deal with you later.  */
1870           break;
1871         default:
1872           /* All possibilities should have been exhausted.  */
1873           abort ();
1874         }
1875       if (!(*dt & RETROKF))
1876         {
1877           if (!opt.verbose)
1878             {
1879               /* #### Ugly ugly ugly! */
1880               char *hurl = url_string (u, 1);
1881               logprintf (LOG_NONVERBOSE, "%s:\n", hurl);
1882               xfree (hurl);
1883             }
1884           logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"),
1885                      tms, hstat.statcode, hstat.error);
1886           logputs (LOG_VERBOSE, "\n");
1887           free_hstat (&hstat);
1888           xfree_null (dummy);
1889           return WRONGCODE;
1890         }
1891
1892       /* Did we get the time-stamp?  */
1893       if (!got_head)
1894         {
1895           if (opt.timestamping && !hstat.remote_time)
1896             {
1897               logputs (LOG_NOTQUIET, _("\
1898 Last-modified header missing -- time-stamps turned off.\n"));
1899             }
1900           else if (hstat.remote_time)
1901             {
1902               /* Convert the date-string into struct tm.  */
1903               tmr = http_atotm (hstat.remote_time);
1904               if (tmr == (time_t) (-1))
1905                 logputs (LOG_VERBOSE, _("\
1906 Last-modified header invalid -- time-stamp ignored.\n"));
1907             }
1908         }
1909
1910       /* The time-stamping section.  */
1911       if (use_ts)
1912         {
1913           got_head = 1;
1914           *dt &= ~HEAD_ONLY;
1915           use_ts = 0;           /* no more time-stamping */
1916           count = 0;            /* the retrieve count for HEAD is
1917                                    reset */
1918           if (hstat.remote_time && tmr != (time_t) (-1))
1919             {
1920               /* Now time-stamping can be used validly.  Time-stamping
1921                  means that if the sizes of the local and remote file
1922                  match, and local file is newer than the remote file,
1923                  it will not be retrieved.  Otherwise, the normal
1924                  download procedure is resumed.  */
1925               if (tml >= tmr &&
1926                   (hstat.contlen == -1 || local_size == hstat.contlen))
1927                 {
1928                   logprintf (LOG_VERBOSE, _("\
1929 Server file no newer than local file `%s' -- not retrieving.\n\n"),
1930                              local_filename);
1931                   free_hstat (&hstat);
1932                   xfree_null (dummy);
1933                   return RETROK;
1934                 }
1935               else if (tml >= tmr)
1936                 logprintf (LOG_VERBOSE, _("\
1937 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1938               else
1939                 logputs (LOG_VERBOSE,
1940                          _("Remote file is newer, retrieving.\n"));
1941             }
1942           free_hstat (&hstat);
1943           continue;
1944         }
1945       if ((tmr != (time_t) (-1))
1946           && !opt.spider
1947           && ((hstat.len == hstat.contlen) ||
1948               ((hstat.res == 0) &&
1949                ((hstat.contlen == -1) ||
1950                 (hstat.len >= hstat.contlen && !opt.kill_longer)))))
1951         {
1952           /* #### This code repeats in http.c and ftp.c.  Move it to a
1953              function!  */
1954           const char *fl = NULL;
1955           if (opt.output_document)
1956             {
1957               if (opt.od_known_regular)
1958                 fl = opt.output_document;
1959             }
1960           else
1961             fl = *hstat.local_file;
1962           if (fl)
1963             touch (fl, tmr);
1964         }
1965       /* End of time-stamping section.  */
1966
1967       if (opt.spider)
1968         {
1969           logprintf (LOG_NOTQUIET, "%d %s\n\n", hstat.statcode, hstat.error);
1970           xfree_null (dummy);
1971           return RETROK;
1972         }
1973
1974       tmrate = retr_rate (hstat.len - hstat.restval, hstat.dltime, 0);
1975
1976       if (hstat.len == hstat.contlen)
1977         {
1978           if (*dt & RETROKF)
1979             {
1980               logprintf (LOG_VERBOSE,
1981                          _("%s (%s) - `%s' saved [%ld/%ld]\n\n"),
1982                          tms, tmrate, locf, hstat.len, hstat.contlen);
1983               logprintf (LOG_NONVERBOSE,
1984                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
1985                          tms, u->url, hstat.len, hstat.contlen, locf, count);
1986             }
1987           ++opt.numurls;
1988           total_downloaded_bytes += hstat.len;
1989
1990           /* Remember that we downloaded the file for later ".orig" code. */
1991           if (*dt & ADDED_HTML_EXTENSION)
1992             downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
1993           else
1994             downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1995
1996           free_hstat (&hstat);
1997           xfree_null (dummy);
1998           return RETROK;
1999         }
2000       else if (hstat.res == 0) /* No read error */
2001         {
2002           if (hstat.contlen == -1)  /* We don't know how much we were supposed
2003                                        to get, so assume we succeeded. */ 
2004             {
2005               if (*dt & RETROKF)
2006                 {
2007                   logprintf (LOG_VERBOSE,
2008                              _("%s (%s) - `%s' saved [%ld]\n\n"),
2009                              tms, tmrate, locf, hstat.len);
2010                   logprintf (LOG_NONVERBOSE,
2011                              "%s URL:%s [%ld] -> \"%s\" [%d]\n",
2012                              tms, u->url, hstat.len, locf, count);
2013                 }
2014               ++opt.numurls;
2015               total_downloaded_bytes += hstat.len;
2016
2017               /* Remember that we downloaded the file for later ".orig" code. */
2018               if (*dt & ADDED_HTML_EXTENSION)
2019                 downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
2020               else
2021                 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
2022               
2023               free_hstat (&hstat);
2024               xfree_null (dummy);
2025               return RETROK;
2026             }
2027           else if (hstat.len < hstat.contlen) /* meaning we lost the
2028                                                  connection too soon */
2029             {
2030               logprintf (LOG_VERBOSE,
2031                          _("%s (%s) - Connection closed at byte %ld. "),
2032                          tms, tmrate, hstat.len);
2033               printwhat (count, opt.ntry);
2034               free_hstat (&hstat);
2035               continue;
2036             }
2037           else if (!opt.kill_longer) /* meaning we got more than expected */
2038             {
2039               logprintf (LOG_VERBOSE,
2040                          _("%s (%s) - `%s' saved [%ld/%ld])\n\n"),
2041                          tms, tmrate, locf, hstat.len, hstat.contlen);
2042               logprintf (LOG_NONVERBOSE,
2043                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
2044                          tms, u->url, hstat.len, hstat.contlen, locf, count);
2045               ++opt.numurls;
2046               total_downloaded_bytes += hstat.len;
2047
2048               /* Remember that we downloaded the file for later ".orig" code. */
2049               if (*dt & ADDED_HTML_EXTENSION)
2050                 downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
2051               else
2052                 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
2053               
2054               free_hstat (&hstat);
2055               xfree_null (dummy);
2056               return RETROK;
2057             }
2058           else                  /* the same, but not accepted */
2059             {
2060               logprintf (LOG_VERBOSE,
2061                          _("%s (%s) - Connection closed at byte %ld/%ld. "),
2062                          tms, tmrate, hstat.len, hstat.contlen);
2063               printwhat (count, opt.ntry);
2064               free_hstat (&hstat);
2065               continue;
2066             }
2067         }
2068       else                      /* now hstat.res can only be -1 */
2069         {
2070           if (hstat.contlen == -1)
2071             {
2072               logprintf (LOG_VERBOSE,
2073                          _("%s (%s) - Read error at byte %ld (%s)."),
2074                          tms, tmrate, hstat.len, strerror (errno));
2075               printwhat (count, opt.ntry);
2076               free_hstat (&hstat);
2077               continue;
2078             }
2079           else                  /* hstat.res == -1 and contlen is given */
2080             {
2081               logprintf (LOG_VERBOSE,
2082                          _("%s (%s) - Read error at byte %ld/%ld (%s). "),
2083                          tms, tmrate, hstat.len, hstat.contlen,
2084                          strerror (errno));
2085               printwhat (count, opt.ntry);
2086               free_hstat (&hstat);
2087               continue;
2088             }
2089         }
2090       /* not reached */
2091       break;
2092     }
2093   while (!opt.ntry || (count < opt.ntry));
2094   return TRYLIMEXC;
2095 }
2096 \f
2097 /* Converts struct tm to time_t, assuming the data in tm is UTC rather
2098    than local timezone.
2099
2100    mktime is similar but assumes struct tm, also known as the
2101    "broken-down" form of time, is in local time zone.  mktime_from_utc
2102    uses mktime to make the conversion understanding that an offset
2103    will be introduced by the local time assumption.
2104
2105    mktime_from_utc then measures the introduced offset by applying
2106    gmtime to the initial result and applying mktime to the resulting
2107    "broken-down" form.  The difference between the two mktime results
2108    is the measured offset which is then subtracted from the initial
2109    mktime result to yield a calendar time which is the value returned.
2110
2111    tm_isdst in struct tm is set to 0 to force mktime to introduce a
2112    consistent offset (the non DST offset) since tm and tm+o might be
2113    on opposite sides of a DST change.
2114
2115    Some implementations of mktime return -1 for the nonexistent
2116    localtime hour at the beginning of DST.  In this event, use
2117    mktime(tm - 1hr) + 3600.
2118
2119    Schematically
2120      mktime(tm)   --> t+o
2121      gmtime(t+o)  --> tm+o
2122      mktime(tm+o) --> t+2o
2123      t+o - (t+2o - t+o) = t
2124
2125    Note that glibc contains a function of the same purpose named
2126    `timegm' (reverse of gmtime).  But obviously, it is not universally
2127    available, and unfortunately it is not straightforwardly
2128    extractable for use here.  Perhaps configure should detect timegm
2129    and use it where available.
2130
2131    Contributed by Roger Beeman <beeman@cisco.com>, with the help of
2132    Mark Baushke <mdb@cisco.com> and the rest of the Gurus at CISCO.
2133    Further improved by Roger with assistance from Edward J. Sabol
2134    based on input by Jamie Zawinski.  */
2135
2136 static time_t
2137 mktime_from_utc (struct tm *t)
2138 {
2139   time_t tl, tb;
2140   struct tm *tg;
2141
2142   tl = mktime (t);
2143   if (tl == -1)
2144     {
2145       t->tm_hour--;
2146       tl = mktime (t);
2147       if (tl == -1)
2148         return -1; /* can't deal with output from strptime */
2149       tl += 3600;
2150     }
2151   tg = gmtime (&tl);
2152   tg->tm_isdst = 0;
2153   tb = mktime (tg);
2154   if (tb == -1)
2155     {
2156       tg->tm_hour--;
2157       tb = mktime (tg);
2158       if (tb == -1)
2159         return -1; /* can't deal with output from gmtime */
2160       tb += 3600;
2161     }
2162   return (tl - (tb - tl));
2163 }
2164
2165 /* Check whether the result of strptime() indicates success.
2166    strptime() returns the pointer to how far it got to in the string.
2167    The processing has been successful if the string is at `GMT' or
2168    `+X', or at the end of the string.
2169
2170    In extended regexp parlance, the function returns 1 if P matches
2171    "^ *(GMT|[+-][0-9]|$)", 0 otherwise.  P being NULL (which strptime
2172    can return) is considered a failure and 0 is returned.  */
2173 static int
2174 check_end (const char *p)
2175 {
2176   if (!p)
2177     return 0;
2178   while (ISSPACE (*p))
2179     ++p;
2180   if (!*p
2181       || (p[0] == 'G' && p[1] == 'M' && p[2] == 'T')
2182       || ((p[0] == '+' || p[0] == '-') && ISDIGIT (p[1])))
2183     return 1;
2184   else
2185     return 0;
2186 }
2187
2188 /* Convert the textual specification of time in TIME_STRING to the
2189    number of seconds since the Epoch.
2190
2191    TIME_STRING can be in any of the three formats RFC2068 allows the
2192    HTTP servers to emit -- RFC1123-date, RFC850-date or asctime-date.
2193    Timezones are ignored, and should be GMT.
2194
2195    Return the computed time_t representation, or -1 if the conversion
2196    fails.
2197
2198    This function uses strptime with various string formats for parsing
2199    TIME_STRING.  This results in a parser that is not as lenient in
2200    interpreting TIME_STRING as I would like it to be.  Being based on
2201    strptime, it always allows shortened months, one-digit days, etc.,
2202    but due to the multitude of formats in which time can be
2203    represented, an ideal HTTP time parser would be even more
2204    forgiving.  It should completely ignore things like week days and
2205    concentrate only on the various forms of representing years,
2206    months, days, hours, minutes, and seconds.  For example, it would
2207    be nice if it accepted ISO 8601 out of the box.
2208
2209    I've investigated free and PD code for this purpose, but none was
2210    usable.  getdate was big and unwieldy, and had potential copyright
2211    issues, or so I was informed.  Dr. Marcus Hennecke's atotm(),
2212    distributed with phttpd, is excellent, but we cannot use it because
2213    it is not assigned to the FSF.  So I stuck it with strptime.  */
2214
2215 time_t
2216 http_atotm (const char *time_string)
2217 {
2218   /* NOTE: Solaris strptime man page claims that %n and %t match white
2219      space, but that's not universally available.  Instead, we simply
2220      use ` ' to mean "skip all WS", which works under all strptime
2221      implementations I've tested.  */
2222
2223   static const char *time_formats[] = {
2224     "%a, %d %b %Y %T",          /* RFC1123: Thu, 29 Jan 1998 22:12:57 */
2225     "%A, %d-%b-%y %T",          /* RFC850:  Thursday, 29-Jan-98 22:12:57 */
2226     "%a, %d-%b-%Y %T",          /* pseudo-RFC850:  Thu, 29-Jan-1998 22:12:57
2227                                    (google.com uses this for their cookies.) */
2228     "%a %b %d %T %Y"            /* asctime: Thu Jan 29 22:12:57 1998 */
2229   };
2230
2231   int i;
2232   struct tm t;
2233
2234   /* According to Roger Beeman, we need to initialize tm_isdst, since
2235      strptime won't do it.  */
2236   t.tm_isdst = 0;
2237
2238   /* Note that under foreign locales Solaris strptime() fails to
2239      recognize English dates, which renders this function useless.  We
2240      solve this by being careful not to affect LC_TIME when
2241      initializing locale.
2242
2243      Another solution would be to temporarily set locale to C, invoke
2244      strptime(), and restore it back.  This is slow and dirty,
2245      however, and locale support other than LC_MESSAGES can mess other
2246      things, so I rather chose to stick with just setting LC_MESSAGES.
2247
2248      GNU strptime does not have this problem because it recognizes
2249      both international and local dates.  */
2250
2251   for (i = 0; i < countof (time_formats); i++)
2252     if (check_end (strptime (time_string, time_formats[i], &t)))
2253       return mktime_from_utc (&t);
2254
2255   /* All formats have failed.  */
2256   return -1;
2257 }
2258 \f
2259 /* Authorization support: We support two authorization schemes:
2260
2261    * `Basic' scheme, consisting of base64-ing USER:PASSWORD string;
2262
2263    * `Digest' scheme, added by Junio Hamano <junio@twinsun.com>,
2264    consisting of answering to the server's challenge with the proper
2265    MD5 digests.  */
2266
2267 /* How many bytes it will take to store LEN bytes in base64.  */
2268 #define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
2269
2270 /* Encode the string S of length LENGTH to base64 format and place it
2271    to STORE.  STORE will be 0-terminated, and must point to a writable
2272    buffer of at least 1+BASE64_LENGTH(length) bytes.  */
2273 static void
2274 base64_encode (const char *s, char *store, int length)
2275 {
2276   /* Conversion table.  */
2277   static char tbl[64] = {
2278     'A','B','C','D','E','F','G','H',
2279     'I','J','K','L','M','N','O','P',
2280     'Q','R','S','T','U','V','W','X',
2281     'Y','Z','a','b','c','d','e','f',
2282     'g','h','i','j','k','l','m','n',
2283     'o','p','q','r','s','t','u','v',
2284     'w','x','y','z','0','1','2','3',
2285     '4','5','6','7','8','9','+','/'
2286   };
2287   int i;
2288   unsigned char *p = (unsigned char *)store;
2289
2290   /* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
2291   for (i = 0; i < length; i += 3)
2292     {
2293       *p++ = tbl[s[0] >> 2];
2294       *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
2295       *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
2296       *p++ = tbl[s[2] & 0x3f];
2297       s += 3;
2298     }
2299   /* Pad the result if necessary...  */
2300   if (i == length + 1)
2301     *(p - 1) = '=';
2302   else if (i == length + 2)
2303     *(p - 1) = *(p - 2) = '=';
2304   /* ...and zero-terminate it.  */
2305   *p = '\0';
2306 }
2307
2308 /* Create the authentication header contents for the `Basic' scheme.
2309    This is done by encoding the string `USER:PASS' in base64 and
2310    prepending `HEADER: Basic ' to it.  */
2311 static char *
2312 basic_authentication_encode (const char *user, const char *passwd,
2313                              const char *header)
2314 {
2315   char *t1, *t2, *res;
2316   int len1 = strlen (user) + 1 + strlen (passwd);
2317   int len2 = BASE64_LENGTH (len1);
2318
2319   t1 = (char *)alloca (len1 + 1);
2320   sprintf (t1, "%s:%s", user, passwd);
2321   t2 = (char *)alloca (1 + len2);
2322   base64_encode (t1, t2, len1);
2323   res = (char *)xmalloc (len2 + 11 + strlen (header));
2324   sprintf (res, "%s: Basic %s\r\n", header, t2);
2325
2326   return res;
2327 }
2328
2329 #define SKIP_WS(x) do {                         \
2330   while (ISSPACE (*(x)))                        \
2331     ++(x);                                      \
2332 } while (0)
2333
2334 #ifdef USE_DIGEST
2335 /* Parse HTTP `WWW-Authenticate:' header.  AU points to the beginning
2336    of a field in such a header.  If the field is the one specified by
2337    ATTR_NAME ("realm", "opaque", and "nonce" are used by the current
2338    digest authorization code), extract its value in the (char*)
2339    variable pointed by RET.  Returns negative on a malformed header,
2340    or number of bytes that have been parsed by this call.  */
2341 static int
2342 extract_header_attr (const char *au, const char *attr_name, char **ret)
2343 {
2344   const char *cp, *ep;
2345
2346   ep = cp = au;
2347
2348   if (strncmp (cp, attr_name, strlen (attr_name)) == 0)
2349     {
2350       cp += strlen (attr_name);
2351       if (!*cp)
2352         return -1;
2353       SKIP_WS (cp);
2354       if (*cp != '=')
2355         return -1;
2356       if (!*++cp)
2357         return -1;
2358       SKIP_WS (cp);
2359       if (*cp != '\"')
2360         return -1;
2361       if (!*++cp)
2362         return -1;
2363       for (ep = cp; *ep && *ep != '\"'; ep++)
2364         ;
2365       if (!*ep)
2366         return -1;
2367       xfree_null (*ret);
2368       *ret = strdupdelim (cp, ep);
2369       return ep - au + 1;
2370     }
2371   else
2372     return 0;
2373 }
2374
2375 /* Dump the hexadecimal representation of HASH to BUF.  HASH should be
2376    an array of 16 bytes containing the hash keys, and BUF should be a
2377    buffer of 33 writable characters (32 for hex digits plus one for
2378    zero termination).  */
2379 static void
2380 dump_hash (unsigned char *buf, const unsigned char *hash)
2381 {
2382   int i;
2383
2384   for (i = 0; i < MD5_HASHLEN; i++, hash++)
2385     {
2386       *buf++ = XNUM_TO_digit (*hash >> 4);
2387       *buf++ = XNUM_TO_digit (*hash & 0xf);
2388     }
2389   *buf = '\0';
2390 }
2391
2392 /* Take the line apart to find the challenge, and compose a digest
2393    authorization header.  See RFC2069 section 2.1.2.  */
2394 static char *
2395 digest_authentication_encode (const char *au, const char *user,
2396                               const char *passwd, const char *method,
2397                               const char *path)
2398 {
2399   static char *realm, *opaque, *nonce;
2400   static struct {
2401     const char *name;
2402     char **variable;
2403   } options[] = {
2404     { "realm", &realm },
2405     { "opaque", &opaque },
2406     { "nonce", &nonce }
2407   };
2408   char *res;
2409
2410   realm = opaque = nonce = NULL;
2411
2412   au += 6;                      /* skip over `Digest' */
2413   while (*au)
2414     {
2415       int i;
2416
2417       SKIP_WS (au);
2418       for (i = 0; i < countof (options); i++)
2419         {
2420           int skip = extract_header_attr (au, options[i].name,
2421                                           options[i].variable);
2422           if (skip < 0)
2423             {
2424               xfree_null (realm);
2425               xfree_null (opaque);
2426               xfree_null (nonce);
2427               return NULL;
2428             }
2429           else if (skip)
2430             {
2431               au += skip;
2432               break;
2433             }
2434         }
2435       if (i == countof (options))
2436         {
2437           while (*au && *au != '=')
2438             au++;
2439           if (*au && *++au)
2440             {
2441               SKIP_WS (au);
2442               if (*au == '\"')
2443                 {
2444                   au++;
2445                   while (*au && *au != '\"')
2446                     au++;
2447                   if (*au)
2448                     au++;
2449                 }
2450             }
2451         }
2452       while (*au && *au != ',')
2453         au++;
2454       if (*au)
2455         au++;
2456     }
2457   if (!realm || !nonce || !user || !passwd || !path || !method)
2458     {
2459       xfree_null (realm);
2460       xfree_null (opaque);
2461       xfree_null (nonce);
2462       return NULL;
2463     }
2464
2465   /* Calculate the digest value.  */
2466   {
2467     ALLOCA_MD5_CONTEXT (ctx);
2468     unsigned char hash[MD5_HASHLEN];
2469     unsigned char a1buf[MD5_HASHLEN * 2 + 1], a2buf[MD5_HASHLEN * 2 + 1];
2470     unsigned char response_digest[MD5_HASHLEN * 2 + 1];
2471
2472     /* A1BUF = H(user ":" realm ":" password) */
2473     gen_md5_init (ctx);
2474     gen_md5_update ((unsigned char *)user, strlen (user), ctx);
2475     gen_md5_update ((unsigned char *)":", 1, ctx);
2476     gen_md5_update ((unsigned char *)realm, strlen (realm), ctx);
2477     gen_md5_update ((unsigned char *)":", 1, ctx);
2478     gen_md5_update ((unsigned char *)passwd, strlen (passwd), ctx);
2479     gen_md5_finish (ctx, hash);
2480     dump_hash (a1buf, hash);
2481
2482     /* A2BUF = H(method ":" path) */
2483     gen_md5_init (ctx);
2484     gen_md5_update ((unsigned char *)method, strlen (method), ctx);
2485     gen_md5_update ((unsigned char *)":", 1, ctx);
2486     gen_md5_update ((unsigned char *)path, strlen (path), ctx);
2487     gen_md5_finish (ctx, hash);
2488     dump_hash (a2buf, hash);
2489
2490     /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */
2491     gen_md5_init (ctx);
2492     gen_md5_update (a1buf, MD5_HASHLEN * 2, ctx);
2493     gen_md5_update ((unsigned char *)":", 1, ctx);
2494     gen_md5_update ((unsigned char *)nonce, strlen (nonce), ctx);
2495     gen_md5_update ((unsigned char *)":", 1, ctx);
2496     gen_md5_update (a2buf, MD5_HASHLEN * 2, ctx);
2497     gen_md5_finish (ctx, hash);
2498     dump_hash (response_digest, hash);
2499
2500     res = (char*) xmalloc (strlen (user)
2501                            + strlen (user)
2502                            + strlen (realm)
2503                            + strlen (nonce)
2504                            + strlen (path)
2505                            + 2 * MD5_HASHLEN /*strlen (response_digest)*/
2506                            + (opaque ? strlen (opaque) : 0)
2507                            + 128);
2508     sprintf (res, "Authorization: Digest \
2509 username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
2510              user, realm, nonce, path, response_digest);
2511     if (opaque)
2512       {
2513         char *p = res + strlen (res);
2514         strcat (p, ", opaque=\"");
2515         strcat (p, opaque);
2516         strcat (p, "\"");
2517       }
2518     strcat (res, "\r\n");
2519   }
2520   return res;
2521 }
2522 #endif /* USE_DIGEST */
2523
2524
2525 #define BEGINS_WITH(line, string_constant)                              \
2526   (!strncasecmp (line, string_constant, sizeof (string_constant) - 1)   \
2527    && (ISSPACE (line[sizeof (string_constant) - 1])                     \
2528        || !line[sizeof (string_constant) - 1]))
2529
2530 static int
2531 known_authentication_scheme_p (const char *au)
2532 {
2533   return BEGINS_WITH (au, "Basic")
2534     || BEGINS_WITH (au, "Digest")
2535     || BEGINS_WITH (au, "NTLM");
2536 }
2537
2538 #undef BEGINS_WITH
2539
2540 /* Create the HTTP authorization request header.  When the
2541    `WWW-Authenticate' response header is seen, according to the
2542    authorization scheme specified in that header (`Basic' and `Digest'
2543    are supported by the current implementation), produce an
2544    appropriate HTTP authorization request header.  */
2545 static char *
2546 create_authorization_line (const char *au, const char *user,
2547                            const char *passwd, const char *method,
2548                            const char *path)
2549 {
2550   char *wwwauth = NULL;
2551
2552   if (!strncasecmp (au, "Basic", 5))
2553     wwwauth = basic_authentication_encode (user, passwd, "Authorization");
2554   if (!strncasecmp (au, "NTLM", 4))
2555     wwwauth = basic_authentication_encode (user, passwd, "Authorization");
2556 #ifdef USE_DIGEST
2557   else if (!strncasecmp (au, "Digest", 6))
2558     wwwauth = digest_authentication_encode (au, user, passwd, method, path);
2559 #endif /* USE_DIGEST */
2560   return wwwauth;
2561 }
2562 \f
2563 void
2564 http_cleanup (void)
2565 {
2566 }