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