]> sjero.net Git - wget/blob - src/http.c
[svn] A bunch of new features:
[wget] / src / http.c
1 /* HTTP support.
2    Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
3
4 This file is part of Wget.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/types.h>
25 #ifdef HAVE_STRING_H
26 # include <string.h>
27 #else
28 # include <strings.h>
29 #endif
30 #include <ctype.h>
31 #ifdef HAVE_UNISTD_H
32 # include <unistd.h>
33 #endif
34 #include <assert.h>
35 #include <errno.h>
36 #if TIME_WITH_SYS_TIME
37 # include <sys/time.h>
38 # include <time.h>
39 #else
40 # if HAVE_SYS_TIME_H
41 #  include <sys/time.h>
42 # else
43 #  include <time.h>
44 # endif
45 #endif
46
47 #ifdef WINDOWS
48 # include <winsock.h>
49 #endif
50
51 #include "wget.h"
52 #include "utils.h"
53 #include "url.h"
54 #include "host.h"
55 #include "rbuf.h"
56 #include "retr.h"
57 #include "headers.h"
58 #include "connect.h"
59 #include "fnmatch.h"
60 #include "netrc.h"
61 #if USE_DIGEST
62 # include "md5.h"
63 #endif
64
65 extern char *version_string;
66
67 #ifndef errno
68 extern int errno;
69 #endif
70 #ifndef h_errno
71 extern int h_errno;
72 #endif
73 \f
74
75 #define TEXTHTML_S "text/html"
76 #define HTTP_ACCEPT "*/*"
77
78 /* Some status code validation macros: */
79 #define H_20X(x)        (((x) >= 200) && ((x) < 300))
80 #define H_PARTIAL(x)    ((x) == HTTP_STATUS_PARTIAL_CONTENTS)
81 #define H_REDIRECTED(x) (((x) == HTTP_STATUS_MOVED_PERMANENTLY) \
82                          || ((x) == HTTP_STATUS_MOVED_TEMPORARILY))
83
84 /* HTTP/1.0 status codes from RFC1945, provided for reference.  */
85 /* Successful 2xx.  */
86 #define HTTP_STATUS_OK                  200
87 #define HTTP_STATUS_CREATED             201
88 #define HTTP_STATUS_ACCEPTED            202
89 #define HTTP_STATUS_NO_CONTENT          204
90 #define HTTP_STATUS_PARTIAL_CONTENTS    206
91
92 /* Redirection 3xx.  */
93 #define HTTP_STATUS_MULTIPLE_CHOICES    300
94 #define HTTP_STATUS_MOVED_PERMANENTLY   301
95 #define HTTP_STATUS_MOVED_TEMPORARILY   302
96 #define HTTP_STATUS_NOT_MODIFIED        304
97
98 /* Client error 4xx.  */
99 #define HTTP_STATUS_BAD_REQUEST         400
100 #define HTTP_STATUS_UNAUTHORIZED        401
101 #define HTTP_STATUS_FORBIDDEN           403
102 #define HTTP_STATUS_NOT_FOUND           404
103
104 /* Server errors 5xx.  */
105 #define HTTP_STATUS_INTERNAL            500
106 #define HTTP_STATUS_NOT_IMPLEMENTED     501
107 #define HTTP_STATUS_BAD_GATEWAY         502
108 #define HTTP_STATUS_UNAVAILABLE         503
109
110 \f
111 /* Parse the HTTP status line, which is of format:
112
113    HTTP-Version SP Status-Code SP Reason-Phrase
114
115    The function returns the status-code, or -1 if the status line is
116    malformed.  The pointer to reason-phrase is returned in RP.  */
117 static int
118 parse_http_status_line (const char *line, const char **reason_phrase_ptr)
119 {
120   /* (the variables must not be named `major' and `minor', because
121      that breaks compilation with SunOS4 cc.)  */
122   int mjr, mnr, statcode;
123   const char *p;
124
125   *reason_phrase_ptr = NULL;
126
127   /* The standard format of HTTP-Version is: `HTTP/X.Y', where X is
128      major version, and Y is minor version.  */
129   if (strncmp (line, "HTTP/", 5) != 0)
130     return -1;
131   line += 5;
132
133   /* Calculate major HTTP version.  */
134   p = line;
135   for (mjr = 0; ISDIGIT (*line); line++)
136     mjr = 10 * mjr + (*line - '0');
137   if (*line != '.' || p == line)
138     return -1;
139   ++line;
140
141   /* Calculate minor HTTP version.  */
142   p = line;
143   for (mnr = 0; ISDIGIT (*line); line++)
144     mnr = 10 * mnr + (*line - '0');
145   if (*line != ' ' || p == line)
146     return -1;
147   /* Wget will accept only 1.0 and higher HTTP-versions.  The value of
148      minor version can be safely ignored.  */
149   if (mjr < 1)
150     return -1;
151   ++line;
152
153   /* Calculate status code.  */
154   if (!(ISDIGIT (*line) && ISDIGIT (line[1]) && ISDIGIT (line[2])))
155     return -1;
156   statcode = 100 * (*line - '0') + 10 * (line[1] - '0') + (line[2] - '0');
157
158   /* Set up the reason phrase pointer.  */
159   line += 3;
160   /* RFC2068 requires SPC here, but we allow the string to finish
161      here, in case no reason-phrase is present.  */
162   if (*line != ' ')
163     {
164       if (!*line)
165         *reason_phrase_ptr = line;
166       else
167         return -1;
168     }
169   else
170     *reason_phrase_ptr = line + 1;
171
172   return statcode;
173 }
174 \f
175 /* Functions to be used as arguments to header_process(): */
176
177 struct http_process_range_closure {
178   long first_byte_pos;
179   long last_byte_pos;
180   long entity_length;
181 };
182
183 /* Parse the `Content-Range' header and extract the information it
184    contains.  Returns 1 if successful, -1 otherwise.  */
185 static int
186 http_process_range (const char *hdr, void *arg)
187 {
188   struct http_process_range_closure *closure
189     = (struct http_process_range_closure *)arg;
190   long num;
191
192   /* Certain versions of Nutscape proxy server send out
193      `Content-Length' without "bytes" specifier, which is a breach of
194      RFC2068 (as well as the HTTP/1.1 draft which was current at the
195      time).  But hell, I must support it...  */
196   if (!strncasecmp (hdr, "bytes", 5))
197     {
198       hdr += 5;
199       hdr += skip_lws (hdr);
200       if (!*hdr)
201         return 0;
202     }
203   if (!ISDIGIT (*hdr))
204     return 0;
205   for (num = 0; ISDIGIT (*hdr); hdr++)
206     num = 10 * num + (*hdr - '0');
207   if (*hdr != '-' || !ISDIGIT (*(hdr + 1)))
208     return 0;
209   closure->first_byte_pos = num;
210   ++hdr;
211   for (num = 0; ISDIGIT (*hdr); hdr++)
212     num = 10 * num + (*hdr - '0');
213   if (*hdr != '/' || !ISDIGIT (*(hdr + 1)))
214     return 0;
215   closure->last_byte_pos = num;
216   ++hdr;
217   for (num = 0; ISDIGIT (*hdr); hdr++)
218     num = 10 * num + (*hdr - '0');
219   closure->entity_length = num;
220   return 1;
221 }
222
223 /* Place 1 to ARG if the HDR contains the word "none", 0 otherwise.
224    Used for `Accept-Ranges'.  */
225 static int
226 http_process_none (const char *hdr, void *arg)
227 {
228   int *where = (int *)arg;
229
230   if (strstr (hdr, "none"))
231     *where = 1;
232   else
233     *where = 0;
234   return 1;
235 }
236
237 /* Place the malloc-ed copy of HDR hdr, to the first `;' to ARG.  */
238 static int
239 http_process_type (const char *hdr, void *arg)
240 {
241   char **result = (char **)arg;
242   char *p;
243
244   p = strrchr (hdr, ';');
245   if (p)
246     {
247       int len = p - hdr;
248       *result = (char *)xmalloc (len + 1);
249       memcpy (*result, hdr, len);
250       (*result)[len] = '\0';
251     }
252   else
253     *result = xstrdup (hdr);
254   return 1;
255 }
256
257 /* Check whether the `Connection' header is set to "keep-alive". */
258 static int
259 http_process_connection (const char *hdr, void *arg)
260 {
261   int *flag = (int *)arg;
262   if (!strcasecmp (hdr, "Keep-Alive"))
263     *flag = 1;
264   return 1;
265 }
266 \f
267 /* Persistent connections (pc). */
268
269 static unsigned char pc_last_host[4];
270 static unsigned short pc_last_port;
271 static int pc_last_fd;
272
273 static void
274 register_persistent (const char *host, unsigned short port, int fd)
275 {
276   if (!store_hostaddress (pc_last_host, host))
277     return;
278   pc_last_port = port;
279   pc_last_fd = fd;
280 }
281
282 static void
283 invalidate_persistent (void)
284 {
285   pc_last_port = 0;
286 }
287
288 static int
289 persistent_available_p (const char *host, unsigned short port)
290 {
291   unsigned char this_host[4];
292   if (port != pc_last_port)
293     return 0;
294   if (!store_hostaddress (this_host, host))
295     return 0;
296   if (memcmp (pc_last_host, this_host, 4))
297     return 0;
298   if (!test_socket_open (pc_last_fd))
299     {
300       invalidate_persistent ();
301       return 0;
302     }
303   return 1;
304 }
305
306 /* The idea behind these two CLOSE macros is to distinguish between
307    two cases: one when the job we've been doing is finished, and we
308    want to close the connection and leave, and two when something is
309    seriously wrong and we're closing the connection as part of
310    cleanup.
311
312    In case of keep_alive, CLOSE_FINISH should leave the connection
313    open, while CLOSE_INVALIDATE should still close it.
314
315    The semantic difference between the flags `keep_alive' and
316    `reused_connection' is that keep_alive defines the state of HTTP:
317    whether the connection *will* be preservable.  reused_connection,
318    on the other hand, reflects the present: whether the *current*
319    connection is the result of preserving.  */
320
321 #define CLOSE_FINISH(fd) do {                   \
322   if (!keep_alive)                              \
323     {                                           \
324       CLOSE (fd);                               \
325       if (reused_connection)                    \
326         invalidate_persistent ();               \
327     }                                           \
328 } while (0)
329
330 #define CLOSE_INVALIDATE(fd) do {               \
331   CLOSE (fd);                                   \
332   if (reused_connection)                        \
333     invalidate_persistent ();                   \
334 } while (0)
335
336 \f
337 struct http_stat
338 {
339   long len;                     /* received length */
340   long contlen;                 /* expected length */
341   long restval;                 /* the restart value */
342   int res;                      /* the result of last read */
343   char *newloc;                 /* new location (redirection) */
344   char *remote_time;            /* remote time-stamp string */
345   char *error;                  /* textual HTTP error */
346   int statcode;                 /* status code */
347   long dltime;                  /* time of the download */
348 };
349
350 /* Free the elements of hstat X.  */
351 #define FREEHSTAT(x) do                                 \
352 {                                                       \
353   FREE_MAYBE ((x).newloc);                              \
354   FREE_MAYBE ((x).remote_time);                         \
355   FREE_MAYBE ((x).error);                               \
356   (x).newloc = (x).remote_time = (x).error = NULL;      \
357 } while (0)
358
359 static char *create_authorization_line PARAMS ((const char *, const char *,
360                                                 const char *, const char *,
361                                                 const char *));
362 static char *basic_authentication_encode PARAMS ((const char *, const char *,
363                                                   const char *));
364 static int known_authentication_scheme_p PARAMS ((const char *));
365
366 static time_t http_atotm PARAMS ((char *));
367
368 /* Retrieve a document through HTTP protocol.  It recognizes status
369    code, and correctly handles redirections.  It closes the network
370    socket.  If it receives an error from the functions below it, it
371    will print it if there is enough information to do so (almost
372    always), returning the error to the caller (i.e. http_loop).
373
374    Various HTTP parameters are stored to hs.  Although it parses the
375    response code correctly, it is not used in a sane way.  The caller
376    can do that, though.
377
378    If u->proxy is non-NULL, the URL u will be taken as a proxy URL,
379    and u->proxy->url will be given to the proxy server (bad naming,
380    I'm afraid).  */
381 static uerr_t
382 gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
383 {
384   char *request, *type, *command, *path;
385   char *user, *passwd;
386   char *pragma_h, *referer, *useragent, *range, *wwwauth, *remhost;
387   char *authenticate_h;
388   char *proxyauth;
389   char *all_headers;
390   char *host_port;
391   int host_port_len;
392   int sock, hcount, num_written, all_length, remport, statcode;
393   long contlen, contrange;
394   struct urlinfo *ou;
395   uerr_t err;
396   FILE *fp;
397   int auth_tried_already;
398   struct rbuf rbuf;
399   int keep_alive, http_keep_alive_1, http_keep_alive_2;
400   int reused_connection;
401
402   if (!(*dt & HEAD_ONLY))
403     /* If we're doing a GET on the URL, as opposed to just a HEAD, we need to
404        know the local filename so we can save to it. */
405     assert (u->local != NULL);
406
407   authenticate_h = 0;
408   auth_tried_already = 0;
409
410  again:
411   /* We need to come back here when the initial attempt to retrieve
412      without authorization header fails.  */
413   keep_alive = 0;
414   http_keep_alive_1 = http_keep_alive_2 = 0;
415   reused_connection = 0;
416
417   /* Initialize certain elements of struct http_stat.  */
418   hs->len = 0L;
419   hs->contlen = -1;
420   hs->res = -1;
421   hs->newloc = NULL;
422   hs->remote_time = NULL;
423   hs->error = NULL;
424
425   /* Which structure to use to retrieve the original URL data.  */
426   if (u->proxy)
427     ou = u->proxy;
428   else
429     ou = u;
430
431   /* First: establish the connection.  */
432   if (u->proxy || !persistent_available_p (u->host, u->port))
433     {
434       logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
435       err = make_connection (&sock, u->host, u->port);
436       switch (err)
437         {
438         case HOSTERR:
439           logputs (LOG_VERBOSE, "\n");
440           logprintf (LOG_NOTQUIET, "%s: %s.\n", u->host, herrmsg (h_errno));
441           return HOSTERR;
442           break;
443         case CONSOCKERR:
444           logputs (LOG_VERBOSE, "\n");
445           logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
446           return CONSOCKERR;
447           break;
448         case CONREFUSED:
449           logputs (LOG_VERBOSE, "\n");
450           logprintf (LOG_NOTQUIET,
451                      _("Connection to %s:%hu refused.\n"), u->host, u->port);
452           CLOSE (sock);
453           return CONREFUSED;
454         case CONERROR:
455           logputs (LOG_VERBOSE, "\n");
456           logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
457           CLOSE (sock);
458           return CONERROR;
459           break;
460         case NOCONERROR:
461           /* Everything is fine!  */
462           logputs (LOG_VERBOSE, _("connected!\n"));
463           break;
464         default:
465           abort ();
466           break;
467         }
468     }
469   else
470     {
471       logprintf (LOG_VERBOSE, _("Reusing connection to %s:%hu.\n"), u->host, u->port);
472       sock = pc_last_fd;
473       reused_connection = 1;
474     }
475
476   if (u->proxy)
477     path = u->proxy->url;
478   else
479     path = u->path;
480   
481   command = (*dt & HEAD_ONLY) ? "HEAD" : "GET";
482   referer = NULL;
483   if (ou->referer)
484     {
485       referer = (char *)alloca (9 + strlen (ou->referer) + 3);
486       sprintf (referer, "Referer: %s\r\n", ou->referer);
487     }
488   if (*dt & SEND_NOCACHE)
489     pragma_h = "Pragma: no-cache\r\n";
490   else
491     pragma_h = "";
492   if (hs->restval)
493     {
494       range = (char *)alloca (13 + numdigit (hs->restval) + 4);
495       /* #### Gag me!  Some servers (e.g. WebSitePro) have been known
496          to misinterpret the following `Range' format, and return the
497          document as multipart/x-byte-ranges MIME type!
498
499          #### TODO: Interpret MIME types, recognize bullshits similar
500          the one described above, and deal with them!  */
501       sprintf (range, "Range: bytes=%ld-\r\n", hs->restval);
502     }
503   else
504     range = NULL;
505   if (opt.useragent)
506     STRDUP_ALLOCA (useragent, opt.useragent);
507   else
508     {
509       useragent = (char *)alloca (10 + strlen (version_string));
510       sprintf (useragent, "Wget/%s", version_string);
511     }
512   /* Construct the authentication, if userid is present.  */
513   user = ou->user;
514   passwd = ou->passwd;
515   search_netrc (u->host, (const char **)&user, (const char **)&passwd, 0);
516   user = user ? user : opt.http_user;
517   passwd = passwd ? passwd : opt.http_passwd;
518
519   wwwauth = NULL;
520   if (authenticate_h && user && passwd)
521     {
522       wwwauth = create_authorization_line (authenticate_h, user, passwd,
523                                            command, ou->path);
524     }
525
526   proxyauth = NULL;
527   if (u->proxy)
528     {
529       char *proxy_user, *proxy_passwd;
530       /* For normal username and password, URL components override
531          command-line/wgetrc parameters.  With proxy authentication,
532          it's the reverse, because proxy URLs are normally the
533          "permanent" ones, so command-line args should take
534          precedence.  */
535       if (opt.proxy_user && opt.proxy_passwd)
536         {
537           proxy_user = opt.proxy_user;
538           proxy_passwd = opt.proxy_passwd;
539         }
540       else
541         {
542           proxy_user = u->user;
543           proxy_passwd = u->passwd;
544         }
545       /* #### This is junky.  Can't the proxy request, say, `Digest'
546          authentication?  */
547       if (proxy_user && proxy_passwd)
548         proxyauth = basic_authentication_encode (proxy_user, proxy_passwd,
549                                                  "Proxy-Authorization");
550     }
551   remhost = ou->host;
552   remport = ou->port;
553
554   if (remport == 80)
555     {
556       host_port = NULL;
557       host_port_len = 0;
558     }
559   else
560     {
561       host_port = (char *)alloca (numdigit (remport) + 2);
562       host_port_len = sprintf (host_port, ":%d", remport);
563     }
564
565   /* Allocate the memory for the request.  */
566   request = (char *)alloca (strlen (command) + strlen (path)
567                             + strlen (useragent)
568                             + strlen (remhost) + host_port_len
569                             + strlen (HTTP_ACCEPT)
570                             + (referer ? strlen (referer) : 0)
571                             + (wwwauth ? strlen (wwwauth) : 0)
572                             + (proxyauth ? strlen (proxyauth) : 0)
573                             + (range ? strlen (range) : 0)
574                             + strlen (pragma_h)
575                             + (opt.user_header ? strlen (opt.user_header) : 0)
576                             + 64);
577   /* Construct the request.  */
578   sprintf (request, "\
579 %s %s HTTP/1.0\r\n\
580 User-Agent: %s\r\n\
581 Host: %s%s\r\n\
582 Accept: %s\r\n\
583 Connection: Keep-Alive\r\n\
584 %s%s%s%s%s%s\r\n",
585            command, path, useragent, remhost,
586            host_port ? host_port : "",
587            HTTP_ACCEPT, referer ? referer : "",
588            wwwauth ? wwwauth : "", 
589            proxyauth ? proxyauth : "", 
590            range ? range : "",
591            pragma_h, 
592            opt.user_header ? opt.user_header : "");
593   DEBUGP (("---request begin---\n%s---request end---\n", request));
594    /* Free the temporary memory.  */
595   FREE_MAYBE (wwwauth);
596   FREE_MAYBE (proxyauth);
597
598   /* Send the request to server.  */
599   num_written = iwrite (sock, request, strlen (request));
600   if (num_written < 0)
601     {
602       logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
603                  strerror (errno));
604       CLOSE_INVALIDATE (sock);
605       return WRITEFAILED;
606     }
607   logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "),
608              u->proxy ? "Proxy" : "HTTP");
609   contlen = contrange = -1;
610   type = NULL;
611   statcode = -1;
612   *dt &= ~RETROKF;
613
614   /* Before reading anything, initialize the rbuf.  */
615   rbuf_initialize (&rbuf, sock);
616
617   all_headers = NULL;
618   all_length = 0;
619   /* Header-fetching loop.  */
620   hcount = 0;
621   while (1)
622     {
623       char *hdr;
624       int status;
625
626       ++hcount;
627       /* Get the header.  */
628       status = header_get (&rbuf, &hdr,
629                            /* Disallow continuations for status line.  */
630                            (hcount == 1 ? HG_NO_CONTINUATIONS : HG_NONE));
631
632       /* Check for errors.  */
633       if (status == HG_EOF && *hdr)
634         {
635           /* This used to be an unconditional error, but that was
636              somewhat controversial, because of a large number of
637              broken CGI's that happily "forget" to send the second EOL
638              before closing the connection of a HEAD request.
639
640              So, the deal is to check whether the header is empty
641              (*hdr is zero if it is); if yes, it means that the
642              previous header was fully retrieved, and that -- most
643              probably -- the request is complete.  "...be liberal in
644              what you accept."  Oh boy.  */
645           logputs (LOG_VERBOSE, "\n");
646           logputs (LOG_NOTQUIET, _("End of file while parsing headers.\n"));
647           free (hdr);
648           FREE_MAYBE (type);
649           FREE_MAYBE (hs->newloc);
650           FREE_MAYBE (all_headers);
651           CLOSE_INVALIDATE (sock);
652           return HEOF;
653         }
654       else if (status == HG_ERROR)
655         {
656           logputs (LOG_VERBOSE, "\n");
657           logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
658                      strerror (errno));
659           free (hdr);
660           FREE_MAYBE (type);
661           FREE_MAYBE (hs->newloc);
662           FREE_MAYBE (all_headers);
663           CLOSE_INVALIDATE (sock);
664           return HERR;
665         }
666
667       /* If the headers are to be saved to a file later, save them to
668          memory now.  */
669       if (opt.save_headers)
670         {
671           int lh = strlen (hdr);
672           all_headers = (char *)xrealloc (all_headers, all_length + lh + 2);
673           memcpy (all_headers + all_length, hdr, lh);
674           all_length += lh;
675           all_headers[all_length++] = '\n';
676           all_headers[all_length] = '\0';
677         }
678
679       /* Print the header if requested.  */
680       if (opt.server_response && hcount != 1)
681         logprintf (LOG_VERBOSE, "\n%d %s", hcount, hdr);
682
683       /* Check for status line.  */
684       if (hcount == 1)
685         {
686           const char *error;
687           /* Parse the first line of server response.  */
688           statcode = parse_http_status_line (hdr, &error);
689           hs->statcode = statcode;
690           /* Store the descriptive response.  */
691           if (statcode == -1) /* malformed response */
692             {
693               /* A common reason for "malformed response" error is the
694                  case when no data was actually received.  Handle this
695                  special case.  */
696               if (!*hdr)
697                 hs->error = xstrdup (_("No data received"));
698               else
699                 hs->error = xstrdup (_("Malformed status line"));
700               free (hdr);
701               break;
702             }
703           else if (!*error)
704             hs->error = xstrdup (_("(no description)"));
705           else
706             hs->error = xstrdup (error);
707
708           if ((statcode != -1)
709 #ifdef DEBUG
710               && !opt.debug
711 #endif
712               )
713             logprintf (LOG_VERBOSE, "%d %s", statcode, error);
714
715           goto done_header;
716         }
717
718       /* Exit on empty header.  */
719       if (!*hdr)
720         {
721           free (hdr);
722           break;
723         }
724
725       /* Try getting content-length.  */
726       if (contlen == -1 && !opt.ignore_length)
727         if (header_process (hdr, "Content-Length", header_extract_number,
728                             &contlen))
729           goto done_header;
730       /* Try getting content-type.  */
731       if (!type)
732         if (header_process (hdr, "Content-Type", http_process_type, &type))
733           goto done_header;
734       /* Try getting location.  */
735       if (!hs->newloc)
736         if (header_process (hdr, "Location", header_strdup, &hs->newloc))
737           goto done_header;
738       /* Try getting last-modified.  */
739       if (!hs->remote_time)
740         if (header_process (hdr, "Last-Modified", header_strdup,
741                             &hs->remote_time))
742           goto done_header;
743       /* Try getting www-authentication.  */
744       if (!authenticate_h)
745         if (header_process (hdr, "WWW-Authenticate", header_strdup,
746                             &authenticate_h))
747           goto done_header;
748       /* Check for accept-ranges header.  If it contains the word
749          `none', disable the ranges.  */
750       if (*dt & ACCEPTRANGES)
751         {
752           int nonep;
753           if (header_process (hdr, "Accept-Ranges", http_process_none, &nonep))
754             {
755               if (nonep)
756                 *dt &= ~ACCEPTRANGES;
757               goto done_header;
758             }
759         }
760       /* Try getting content-range.  */
761       if (contrange == -1)
762         {
763           struct http_process_range_closure closure;
764           if (header_process (hdr, "Content-Range", http_process_range, &closure))
765             {
766               contrange = closure.first_byte_pos;
767               goto done_header;
768             }
769         }
770       /* Check for the `Keep-Alive' header. */
771       if (!http_keep_alive_1)
772         {
773           if (header_process (hdr, "Keep-Alive", header_exists,
774                               &http_keep_alive_1))
775             goto done_header;
776         }
777       /* Check for `Connection: Keep-Alive'. */
778       if (!http_keep_alive_2)
779         {
780           if (header_process (hdr, "Connection", http_process_connection,
781                               &http_keep_alive_2))
782             goto done_header;
783         }
784     done_header:
785       free (hdr);
786     }
787
788   logputs (LOG_VERBOSE, "\n");
789
790   if (contlen != -1
791       && (http_keep_alive_1 || http_keep_alive_2))
792     keep_alive = 1;
793   if (keep_alive && !reused_connection)
794     register_persistent (u->host, u->port, sock);
795
796   if ((statcode == HTTP_STATUS_UNAUTHORIZED)
797       && authenticate_h)
798     {
799       /* Authorization is required.  */
800       FREE_MAYBE (type);
801       type = NULL;
802       FREEHSTAT (*hs);
803       CLOSE_FINISH (sock);
804       if (auth_tried_already)
805         {
806           /* If we have tried it already, then there is not point
807              retrying it.  */
808           logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
809           free (authenticate_h);
810           return AUTHFAILED;
811         }
812       else if (!known_authentication_scheme_p (authenticate_h))
813         {
814           free (authenticate_h);
815           logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n"));
816           return AUTHFAILED;
817         }
818       else
819         {
820           auth_tried_already = 1;
821           goto again;
822         }
823     }
824   /* We do not need this anymore.  */
825   if (authenticate_h)
826     {
827       free (authenticate_h);
828       authenticate_h = NULL;
829     }
830
831   /* 20x responses are counted among successful by default.  */
832   if (H_20X (statcode))
833     *dt |= RETROKF;
834
835   if (type && !strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)))
836     *dt |= TEXTHTML;
837   else
838     /* We don't assume text/html by default.  */
839     *dt &= ~TEXTHTML;
840
841   if (opt.html_extension && (*dt & TEXTHTML))
842     /* -E / --html-extension / html_extension = on was specified, and this is a
843        text/html file.  If some case-insensitive variation on ".htm[l]" isn't
844        already the file's suffix, tack on ".html". */
845     {
846       char*  last_period_in_local_filename = strrchr(u->local, '.');
847
848       if (last_period_in_local_filename == NULL ||
849           !(strcasecmp(last_period_in_local_filename, ".htm") == EQ ||
850             strcasecmp(last_period_in_local_filename, ".html") == EQ))
851         {
852           size_t  local_filename_len = strlen(u->local);
853           
854           u->local = xrealloc(u->local, local_filename_len + sizeof(".html"));
855           strcpy(u->local + local_filename_len, ".html");
856
857           *dt |= ADDED_HTML_EXTENSION;
858         }
859     }
860
861   if (contrange == -1)
862     hs->restval = 0;
863   else if (contrange != hs->restval ||
864            (H_PARTIAL (statcode) && contrange == -1))
865     {
866       /* This means the whole request was somehow misunderstood by the
867          server.  Bail out.  */
868       FREE_MAYBE (type);
869       FREE_MAYBE (hs->newloc);
870       FREE_MAYBE (all_headers);
871       CLOSE_INVALIDATE (sock);
872       return RANGEERR;
873     }
874
875   if (hs->restval)
876     {
877       if (contlen != -1)
878         contlen += contrange;
879       else
880         contrange = -1;        /* If conent-length was not sent,
881                                   content-range will be ignored.  */
882     }
883   hs->contlen = contlen;
884
885   /* Return if redirected.  */
886   if (H_REDIRECTED (statcode) || statcode == HTTP_STATUS_MULTIPLE_CHOICES)
887     {
888       /* RFC2068 says that in case of the 300 (multiple choices)
889          response, the server can output a preferred URL through
890          `Location' header; otherwise, the request should be treated
891          like GET.  So, if the location is set, it will be a
892          redirection; otherwise, just proceed normally.  */
893       if (statcode == HTTP_STATUS_MULTIPLE_CHOICES && !hs->newloc)
894         *dt |= RETROKF;
895       else
896         {
897           logprintf (LOG_VERBOSE,
898                      _("Location: %s%s\n"),
899                      hs->newloc ? hs->newloc : _("unspecified"),
900                      hs->newloc ? _(" [following]") : "");
901           CLOSE_FINISH (sock);
902           FREE_MAYBE (type);
903           FREE_MAYBE (all_headers);
904           return NEWLOCATION;
905         }
906     }
907   if (opt.verbose)
908     {
909       if ((*dt & RETROKF) && !opt.server_response)
910         {
911           /* No need to print this output if the body won't be
912              downloaded at all, or if the original server response is
913              printed.  */
914           logputs (LOG_VERBOSE, _("Length: "));
915           if (contlen != -1)
916             {
917               logputs (LOG_VERBOSE, legible (contlen));
918               if (contrange != -1)
919                 logprintf (LOG_VERBOSE, _(" (%s to go)"),
920                            legible (contlen - contrange));
921             }
922           else
923             logputs (LOG_VERBOSE,
924                      opt.ignore_length ? _("ignored") : _("unspecified"));
925           if (type)
926             logprintf (LOG_VERBOSE, " [%s]\n", type);
927           else
928             logputs (LOG_VERBOSE, "\n");
929         }
930     }
931   FREE_MAYBE (type);
932   type = NULL;                  /* We don't need it any more.  */
933
934   /* Return if we have no intention of further downloading.  */
935   if (!(*dt & RETROKF) || (*dt & HEAD_ONLY))
936     {
937       /* In case someone cares to look...  */
938       hs->len = 0L;
939       hs->res = 0;
940       FREE_MAYBE (type);
941       FREE_MAYBE (all_headers);
942       CLOSE_FINISH (sock);
943       return RETRFINISHED;
944     }
945
946   /* Open the local file.  */
947   if (!opt.dfp)
948     {
949       mkalldirs (u->local);
950       if (opt.backups)
951         rotate_backups (u->local);
952       fp = fopen (u->local, hs->restval ? "ab" : "wb");
953       if (!fp)
954         {
955           logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
956           CLOSE_FINISH (sock);
957           FREE_MAYBE (all_headers);
958           return FOPENERR;
959         }
960     }
961   else                          /* opt.dfp */
962     {
963       fp = opt.dfp;
964       if (!hs->restval)
965         {
966           /* This will silently fail for streams that don't correspond
967              to regular files, but that's OK.  */
968           rewind (fp);
969           clearerr (fp);
970         }
971     }
972
973   /* #### This confuses the code that checks for file size.  There
974      should be some overhead information.  */
975   if (opt.save_headers)
976     fwrite (all_headers, 1, all_length, fp);
977   reset_timer ();
978   /* Get the contents of the document.  */
979   hs->res = get_contents (sock, fp, &hs->len, hs->restval,
980                           (contlen != -1 ? contlen : 0),
981                           &rbuf, keep_alive);
982   hs->dltime = elapsed_time ();
983   {
984     /* Close or flush the file.  We have to be careful to check for
985        error here.  Checking the result of fwrite() is not enough --
986        errors could go unnoticed!  */
987     int flush_res;
988     if (!opt.dfp)
989       flush_res = fclose (fp);
990     else
991       flush_res = fflush (fp);
992     if (flush_res == EOF)
993       hs->res = -2;
994   }
995   FREE_MAYBE (all_headers);
996   CLOSE_FINISH (sock);
997   if (hs->res == -2)
998     return FWRITEERR;
999   return RETRFINISHED;
1000 }
1001
1002 /* The genuine HTTP loop!  This is the part where the retrieval is
1003    retried, and retried, and retried, and...  */
1004 uerr_t
1005 http_loop (struct urlinfo *u, char **newloc, int *dt)
1006 {
1007   static int first_retrieval = 1;
1008
1009   int count;
1010   int use_ts, got_head = 0;     /* time-stamping info */
1011   char *filename_plus_orig_suffix;
1012   char *local_filename = NULL;
1013   char *tms, *suf, *locf, *tmrate;
1014   uerr_t err;
1015   time_t tml = -1, tmr = -1;    /* local and remote time-stamps */
1016   long local_size = 0;          /* the size of the local file */
1017   size_t filename_len;
1018   struct http_stat hstat;       /* HTTP status */
1019   struct stat st;
1020
1021   *newloc = NULL;
1022
1023   /* Warn on (likely bogus) wildcard usage in HTTP.  Don't use
1024      has_wildcards_p because it would also warn on `?', and we know that
1025      shows up in CGI paths a *lot*.  */
1026   if (strchr (u->url, '*'))
1027     logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
1028
1029   /* Determine the local filename.  */
1030   if (!u->local)
1031     u->local = url_filename (u->proxy ? u->proxy : u);
1032
1033   if (!opt.output_document)
1034     locf = u->local;
1035   else
1036     locf = opt.output_document;
1037
1038   /* Yuck.  Multiple returns suck.  We need to remember to free() the space we
1039      xmalloc() here before EACH return.  This is one reason it's better to set
1040      flags that influence flow control and then return once at the end. */
1041   filename_len = strlen(u->local);
1042   filename_plus_orig_suffix = xmalloc(filename_len + sizeof(".orig"));
1043
1044   if (opt.noclobber && file_exists_p (u->local))
1045     {
1046       /* If opt.noclobber is turned on and file already exists, do not
1047          retrieve the file */
1048       logprintf (LOG_VERBOSE, _("\
1049 File `%s' already there, will not retrieve.\n"), u->local);
1050       /* If the file is there, we suppose it's retrieved OK.  */
1051       *dt |= RETROKF;
1052
1053       /* #### Bogusness alert.  */
1054       /* If its suffix is "html" or (yuck!) "htm", we suppose it's
1055          text/html, a harmless lie.  */
1056       if (((suf = suffix (u->local)) != NULL)
1057           && (!strcmp (suf, "html") || !strcmp (suf, "htm")))
1058         *dt |= TEXTHTML;
1059       free (suf);
1060       free(filename_plus_orig_suffix);  /* must precede every return! */
1061       /* Another harmless lie: */
1062       return RETROK;
1063     }
1064
1065   use_ts = 0;
1066   if (opt.timestamping)
1067     {
1068       boolean  local_dot_orig_file_exists = FALSE;
1069
1070       if (opt.backup_converted)
1071         /* If -K is specified, we'll act on the assumption that it was specified
1072            last time these files were downloaded as well, and instead of just
1073            comparing local file X against server file X, we'll compare local
1074            file X.orig (if extant, else X) against server file X.  If -K
1075            _wasn't_ specified last time, or the server contains files called
1076            *.orig, -N will be back to not operating correctly with -k. */
1077         {
1078           /* Would a single s[n]printf() call be faster?  --dan
1079
1080              It wouldn't.  sprintf() is horribly slow.  At one point I
1081              profiled Wget, and found that a measurable and
1082              non-negligible amount of time was lost calling sprintf()
1083              in url.c.  Replacing sprintf with inline calls to
1084              strcpy() and long_to_string() made a difference.
1085              --hniksic */
1086           strcpy(filename_plus_orig_suffix, u->local);
1087           strcpy(filename_plus_orig_suffix + filename_len, ".orig");
1088
1089           /* Try to stat() the .orig file. */
1090           if (stat(filename_plus_orig_suffix, &st) == 0)
1091             {
1092               local_dot_orig_file_exists = TRUE;
1093               local_filename = filename_plus_orig_suffix;
1094             }
1095         }      
1096
1097       if (!local_dot_orig_file_exists)
1098         /* Couldn't stat() <file>.orig, so try to stat() <file>. */
1099         if (stat (u->local, &st) == 0)
1100           local_filename = u->local;
1101
1102       if (local_filename != NULL)
1103         /* There was a local file, so we'll check later to see if the version
1104            the server has is the same version we already have, allowing us to
1105            skip a download. */
1106         {
1107           use_ts = 1;
1108           tml = st.st_mtime;
1109           local_size = st.st_size;
1110           got_head = 0;
1111         }
1112     }
1113   /* Reset the counter.  */
1114   count = 0;
1115   *dt = 0 | ACCEPTRANGES;
1116   /* THE loop */
1117   do
1118     {
1119       /* Increment the pass counter.  */
1120       ++count;
1121       /* Wait before the retrieval (unless this is the very first
1122          retrieval).
1123          Check if we are retrying or not, wait accordingly - HEH */
1124       if (!first_retrieval && (opt.wait || (count && opt.waitretry)))
1125         {
1126           if (count)
1127             {
1128               if (count<opt.waitretry)
1129                 sleep(count);
1130               else
1131                 sleep(opt.waitretry);
1132             }
1133           else
1134             sleep (opt.wait);
1135         }
1136       if (first_retrieval)
1137         first_retrieval = 0;
1138       /* Get the current time string.  */
1139       tms = time_str (NULL);
1140       /* Print fetch message, if opt.verbose.  */
1141       if (opt.verbose)
1142         {
1143           char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1144           char tmp[15];
1145           strcpy (tmp, "        ");
1146           if (count > 1)
1147             sprintf (tmp, _("(try:%2d)"), count);
1148           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
1149                      tms, hurl, tmp, locf);
1150 #ifdef WINDOWS
1151           ws_changetitle (hurl, 1);
1152 #endif
1153           free (hurl);
1154         }
1155
1156       /* Default document type is empty.  However, if spider mode is
1157          on or time-stamping is employed, HEAD_ONLY commands is
1158          encoded within *dt.  */
1159       if (opt.spider || (use_ts && !got_head))
1160         *dt |= HEAD_ONLY;
1161       else
1162         *dt &= ~HEAD_ONLY;
1163       /* Assume no restarting.  */
1164       hstat.restval = 0L;
1165       /* Decide whether or not to restart.  */
1166       if (((count > 1 && (*dt & ACCEPTRANGES)) || opt.always_rest)
1167           && file_exists_p (u->local))
1168         if (stat (u->local, &st) == 0)
1169           hstat.restval = st.st_size;
1170       /* Decide whether to send the no-cache directive.  */
1171       if (u->proxy && (count > 1 || (opt.proxy_cache == 0)))
1172         *dt |= SEND_NOCACHE;
1173       else
1174         *dt &= ~SEND_NOCACHE;
1175
1176       /* Try fetching the document, or at least its head.  :-) */
1177       err = gethttp (u, &hstat, dt);
1178
1179       /* It's unfortunate that wget determines the local filename before finding
1180          out the Content-Type of the file.  Barring a major restructuring of the
1181          code, we need to re-set locf here, since gethttp() may have xrealloc()d
1182          u->local to tack on ".html". */
1183       if (!opt.output_document)
1184         locf = u->local;
1185       else
1186         locf = opt.output_document;
1187
1188       /* Time?  */
1189       tms = time_str (NULL);
1190       /* Get the new location (with or without the redirection).  */
1191       if (hstat.newloc)
1192         *newloc = xstrdup (hstat.newloc);
1193       switch (err)
1194         {
1195         case HERR: case HEOF: case CONSOCKERR: case CONCLOSED:
1196         case CONERROR: case READERR: case WRITEFAILED:
1197         case RANGEERR:
1198           /* Non-fatal errors continue executing the loop, which will
1199              bring them to "while" statement at the end, to judge
1200              whether the number of tries was exceeded.  */
1201           FREEHSTAT (hstat);
1202           printwhat (count, opt.ntry);
1203           continue;
1204           break;
1205         case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED:
1206           /* Fatal errors just return from the function.  */
1207           FREEHSTAT (hstat);
1208           free(filename_plus_orig_suffix);  /* must precede every return! */
1209           return err;
1210           break;
1211         case FWRITEERR: case FOPENERR:
1212           /* Another fatal error.  */
1213           logputs (LOG_VERBOSE, "\n");
1214           logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"),
1215                      u->local, strerror (errno));
1216           FREEHSTAT (hstat);
1217           free(filename_plus_orig_suffix);  /* must precede every return! */
1218           return err;
1219           break;
1220         case NEWLOCATION:
1221           /* Return the new location to the caller.  */
1222           if (!hstat.newloc)
1223             {
1224               logprintf (LOG_NOTQUIET,
1225                          _("ERROR: Redirection (%d) without location.\n"),
1226                          hstat.statcode);
1227               free(filename_plus_orig_suffix);  /* must precede every return! */
1228               return WRONGCODE;
1229             }
1230           FREEHSTAT (hstat);
1231           free(filename_plus_orig_suffix);  /* must precede every return! */
1232           return NEWLOCATION;
1233           break;
1234         case RETRFINISHED:
1235           /* Deal with you later.  */
1236           break;
1237         default:
1238           /* All possibilities should have been exhausted.  */
1239           abort ();
1240         }
1241       if (!(*dt & RETROKF))
1242         {
1243           if (!opt.verbose)
1244             {
1245               /* #### Ugly ugly ugly! */
1246               char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1247               logprintf (LOG_NONVERBOSE, "%s:\n", hurl);
1248               free (hurl);
1249             }
1250           logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"),
1251                      tms, hstat.statcode, hstat.error);
1252           logputs (LOG_VERBOSE, "\n");
1253           FREEHSTAT (hstat);
1254           free(filename_plus_orig_suffix);  /* must precede every return! */
1255           return WRONGCODE;
1256         }
1257
1258       /* Did we get the time-stamp?  */
1259       if (!got_head)
1260         {
1261           if (opt.timestamping && !hstat.remote_time)
1262             {
1263               logputs (LOG_NOTQUIET, _("\
1264 Last-modified header missing -- time-stamps turned off.\n"));
1265             }
1266           else if (hstat.remote_time)
1267             {
1268               /* Convert the date-string into struct tm.  */
1269               tmr = http_atotm (hstat.remote_time);
1270               if (tmr == (time_t) (-1))
1271                 logputs (LOG_VERBOSE, _("\
1272 Last-modified header invalid -- time-stamp ignored.\n"));
1273             }
1274         }
1275
1276       /* The time-stamping section.  */
1277       if (use_ts)
1278         {
1279           got_head = 1;
1280           *dt &= ~HEAD_ONLY;
1281           use_ts = 0;           /* no more time-stamping */
1282           count = 0;            /* the retrieve count for HEAD is
1283                                    reset */
1284           if (hstat.remote_time && tmr != (time_t) (-1))
1285             {
1286               /* Now time-stamping can be used validly.  Time-stamping
1287                  means that if the sizes of the local and remote file
1288                  match, and local file is newer than the remote file,
1289                  it will not be retrieved.  Otherwise, the normal
1290                  download procedure is resumed.  */
1291               if (tml >= tmr &&
1292                   (hstat.contlen == -1 || local_size == hstat.contlen))
1293                 {
1294                   logprintf (LOG_VERBOSE, _("\
1295 Server file no newer than local file `%s' -- not retrieving.\n\n"),
1296                              local_filename);
1297                   FREEHSTAT (hstat);
1298                   free(filename_plus_orig_suffix);/*must precede every return!*/
1299                   return RETROK;
1300                 }
1301               else if (tml >= tmr)
1302                 logprintf (LOG_VERBOSE, _("\
1303 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1304               else
1305                 logputs (LOG_VERBOSE,
1306                          _("Remote file is newer, retrieving.\n"));
1307             }
1308           FREEHSTAT (hstat);
1309           continue;
1310         }
1311       if (!opt.dfp
1312           && (tmr != (time_t) (-1))
1313           && !opt.spider
1314           && ((hstat.len == hstat.contlen) ||
1315               ((hstat.res == 0) &&
1316                ((hstat.contlen == -1) ||
1317                 (hstat.len >= hstat.contlen && !opt.kill_longer)))))
1318         {
1319           touch (u->local, tmr);
1320         }
1321       /* End of time-stamping section.  */
1322
1323       if (opt.spider)
1324         {
1325           logprintf (LOG_NOTQUIET, "%d %s\n\n", hstat.statcode, hstat.error);
1326           free(filename_plus_orig_suffix);  /* must precede every return! */
1327           return RETROK;
1328         }
1329
1330       /* It is now safe to free the remainder of hstat, since the
1331          strings within it will no longer be used.  */
1332       FREEHSTAT (hstat);
1333
1334       tmrate = rate (hstat.len - hstat.restval, hstat.dltime);
1335
1336       if (hstat.len == hstat.contlen)
1337         {
1338           if (*dt & RETROKF)
1339             {
1340               logprintf (LOG_VERBOSE,
1341                          _("%s (%s) - `%s' saved [%ld/%ld]\n\n"),
1342                          tms, tmrate, locf, hstat.len, hstat.contlen);
1343               logprintf (LOG_NONVERBOSE,
1344                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
1345                          tms, u->url, hstat.len, hstat.contlen, locf, count);
1346             }
1347           ++opt.numurls;
1348           downloaded_increase (hstat.len);
1349
1350           /* Remember that we downloaded the file for later ".orig" code. */
1351           if (*dt & ADDED_HTML_EXTENSION)
1352             downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
1353           else
1354             downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1355
1356           free(filename_plus_orig_suffix);  /* must precede every return! */
1357           return RETROK;
1358         }
1359       else if (hstat.res == 0) /* No read error */
1360         {
1361           if (hstat.contlen == -1)  /* We don't know how much we were supposed
1362                                        to get, so assume we succeeded. */ 
1363             {
1364               if (*dt & RETROKF)
1365                 {
1366                   logprintf (LOG_VERBOSE,
1367                              _("%s (%s) - `%s' saved [%ld]\n\n"),
1368                              tms, tmrate, locf, hstat.len);
1369                   logprintf (LOG_NONVERBOSE,
1370                              "%s URL:%s [%ld] -> \"%s\" [%d]\n",
1371                              tms, u->url, hstat.len, locf, count);
1372                 }
1373               ++opt.numurls;
1374               downloaded_increase (hstat.len);
1375
1376               /* Remember that we downloaded the file for later ".orig" code. */
1377               if (*dt & ADDED_HTML_EXTENSION)
1378                 downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
1379               else
1380                 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1381               
1382               free(filename_plus_orig_suffix);  /* must precede every return! */
1383               return RETROK;
1384             }
1385           else if (hstat.len < hstat.contlen) /* meaning we lost the
1386                                                  connection too soon */
1387             {
1388               logprintf (LOG_VERBOSE,
1389                          _("%s (%s) - Connection closed at byte %ld. "),
1390                          tms, tmrate, hstat.len);
1391               printwhat (count, opt.ntry);
1392               continue;
1393             }
1394           else if (!opt.kill_longer) /* meaning we got more than expected */
1395             {
1396               logprintf (LOG_VERBOSE,
1397                          _("%s (%s) - `%s' saved [%ld/%ld])\n\n"),
1398                          tms, tmrate, locf, hstat.len, hstat.contlen);
1399               logprintf (LOG_NONVERBOSE,
1400                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
1401                          tms, u->url, hstat.len, hstat.contlen, locf, count);
1402               ++opt.numurls;
1403               downloaded_increase (hstat.len);
1404
1405               /* Remember that we downloaded the file for later ".orig" code. */
1406               if (*dt & ADDED_HTML_EXTENSION)
1407                 downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, locf);
1408               else
1409                 downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
1410               
1411               free(filename_plus_orig_suffix);  /* must precede every return! */
1412               return RETROK;
1413             }
1414           else                  /* the same, but not accepted */
1415             {
1416               logprintf (LOG_VERBOSE,
1417                          _("%s (%s) - Connection closed at byte %ld/%ld. "),
1418                          tms, tmrate, hstat.len, hstat.contlen);
1419               printwhat (count, opt.ntry);
1420               continue;
1421             }
1422         }
1423       else                      /* now hstat.res can only be -1 */
1424         {
1425           if (hstat.contlen == -1)
1426             {
1427               logprintf (LOG_VERBOSE,
1428                          _("%s (%s) - Read error at byte %ld (%s)."),
1429                          tms, tmrate, hstat.len, strerror (errno));
1430               printwhat (count, opt.ntry);
1431               continue;
1432             }
1433           else                  /* hstat.res == -1 and contlen is given */
1434             {
1435               logprintf (LOG_VERBOSE,
1436                          _("%s (%s) - Read error at byte %ld/%ld (%s). "),
1437                          tms, tmrate, hstat.len, hstat.contlen,
1438                          strerror (errno));
1439               printwhat (count, opt.ntry);
1440               continue;
1441             }
1442         }
1443       /* not reached */
1444       break;
1445     }
1446   while (!opt.ntry || (count < opt.ntry));
1447   free(filename_plus_orig_suffix);  /* must precede every return! */
1448   return TRYLIMEXC;
1449 }
1450 \f
1451 /* Converts struct tm to time_t, assuming the data in tm is UTC rather
1452    than local timezone (mktime assumes the latter).
1453
1454    Contributed by Roger Beeman <beeman@cisco.com>, with the help of
1455    Mark Baushke <mdb@cisco.com> and the rest of the Gurus at CISCO.  */
1456 static time_t
1457 mktime_from_utc (struct tm *t)
1458 {
1459   time_t tl, tb;
1460
1461   tl = mktime (t);
1462   if (tl == -1)
1463     return -1;
1464   tb = mktime (gmtime (&tl));
1465   return (tl <= tb ? (tl + (tl - tb)) : (tl - (tb - tl)));
1466 }
1467
1468 /* Check whether the result of strptime() indicates success.
1469    strptime() returns the pointer to how far it got to in the string.
1470    The processing has been successful if the string is at `GMT' or
1471    `+X', or at the end of the string.
1472
1473    In extended regexp parlance, the function returns 1 if P matches
1474    "^ *(GMT|[+-][0-9]|$)", 0 otherwise.  P being NULL (a valid result of
1475    strptime()) is considered a failure and 0 is returned.  */
1476 static int
1477 check_end (char *p)
1478 {
1479   if (!p)
1480     return 0;
1481   while (ISSPACE (*p))
1482     ++p;
1483   if (!*p
1484       || (p[0] == 'G' && p[1] == 'M' && p[2] == 'T')
1485       || ((p[0] == '+' || p[1] == '-') && ISDIGIT (p[1])))
1486     return 1;
1487   else
1488     return 0;
1489 }
1490
1491 /* Convert TIME_STRING time to time_t.  TIME_STRING can be in any of
1492    the three formats RFC2068 allows the HTTP servers to emit --
1493    RFC1123-date, RFC850-date or asctime-date.  Timezones are ignored,
1494    and should be GMT.
1495
1496    We use strptime() to recognize various dates, which makes it a
1497    little bit slacker than the RFC1123/RFC850/asctime (e.g. it always
1498    allows shortened dates and months, one-digit days, etc.).  It also
1499    allows more than one space anywhere where the specs require one SP.
1500    The routine should probably be even more forgiving (as recommended
1501    by RFC2068), but I do not have the time to write one.
1502
1503    Return the computed time_t representation, or -1 if all the
1504    schemes fail.
1505
1506    Needless to say, what we *really* need here is something like
1507    Marcus Hennecke's atotm(), which is forgiving, fast, to-the-point,
1508    and does not use strptime().  atotm() is to be found in the sources
1509    of `phttpd', a little-known HTTP server written by Peter Erikson.  */
1510 static time_t
1511 http_atotm (char *time_string)
1512 {
1513   struct tm t;
1514
1515   /* Roger Beeman says: "This function dynamically allocates struct tm
1516      t, but does no initialization.  The only field that actually
1517      needs initialization is tm_isdst, since the others will be set by
1518      strptime.  Since strptime does not set tm_isdst, it will return
1519      the data structure with whatever data was in tm_isdst to begin
1520      with.  For those of us in timezones where DST can occur, there
1521      can be a one hour shift depending on the previous contents of the
1522      data area where the data structure is allocated."  */
1523   t.tm_isdst = -1;
1524
1525   /* Note that under foreign locales Solaris strptime() fails to
1526      recognize English dates, which renders this function useless.  I
1527      assume that other non-GNU strptime's are plagued by the same
1528      disease.  We solve this by setting only LC_MESSAGES in
1529      i18n_initialize(), instead of LC_ALL.
1530
1531      Another solution could be to temporarily set locale to C, invoke
1532      strptime(), and restore it back.  This is slow and dirty,
1533      however, and locale support other than LC_MESSAGES can mess other
1534      things, so I rather chose to stick with just setting LC_MESSAGES.
1535
1536      Also note that none of this is necessary under GNU strptime(),
1537      because it recognizes both international and local dates.  */
1538
1539   /* NOTE: We don't use `%n' for white space, as OSF's strptime uses
1540      it to eat all white space up to (and including) a newline, and
1541      the function fails if there is no newline (!).
1542
1543      Let's hope all strptime() implementations use ` ' to skip *all*
1544      whitespace instead of just one (it works that way on all the
1545      systems I've tested it on).  */
1546
1547   /* RFC1123: Thu, 29 Jan 1998 22:12:57 */
1548   if (check_end (strptime (time_string, "%a, %d %b %Y %T", &t)))
1549     return mktime_from_utc (&t);
1550   /* RFC850:  Thu, 29-Jan-98 22:12:57 */
1551   if (check_end (strptime (time_string, "%a, %d-%b-%y %T", &t)))
1552     return mktime_from_utc (&t);
1553   /* asctime: Thu Jan 29 22:12:57 1998 */
1554   if (check_end (strptime (time_string, "%a %b %d %T %Y", &t)))
1555     return mktime_from_utc (&t);
1556   /* Failure.  */
1557   return -1;
1558 }
1559 \f
1560 /* Authorization support: We support two authorization schemes:
1561
1562    * `Basic' scheme, consisting of base64-ing USER:PASSWORD string;
1563
1564    * `Digest' scheme, added by Junio Hamano <junio@twinsun.com>,
1565    consisting of answering to the server's challenge with the proper
1566    MD5 digests.  */
1567
1568 /* How many bytes it will take to store LEN bytes in base64.  */
1569 #define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
1570
1571 /* Encode the string S of length LENGTH to base64 format and place it
1572    to STORE.  STORE will be 0-terminated, and must point to a writable
1573    buffer of at least 1+BASE64_LENGTH(length) bytes.  */
1574 static void
1575 base64_encode (const char *s, char *store, int length)
1576 {
1577   /* Conversion table.  */
1578   static char tbl[64] = {
1579     'A','B','C','D','E','F','G','H',
1580     'I','J','K','L','M','N','O','P',
1581     'Q','R','S','T','U','V','W','X',
1582     'Y','Z','a','b','c','d','e','f',
1583     'g','h','i','j','k','l','m','n',
1584     'o','p','q','r','s','t','u','v',
1585     'w','x','y','z','0','1','2','3',
1586     '4','5','6','7','8','9','+','/'
1587   };
1588   int i;
1589   unsigned char *p = (unsigned char *)store;
1590
1591   /* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
1592   for (i = 0; i < length; i += 3)
1593     {
1594       *p++ = tbl[s[0] >> 2];
1595       *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
1596       *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
1597       *p++ = tbl[s[2] & 0x3f];
1598       s += 3;
1599     }
1600   /* Pad the result if necessary...  */
1601   if (i == length + 1)
1602     *(p - 1) = '=';
1603   else if (i == length + 2)
1604     *(p - 1) = *(p - 2) = '=';
1605   /* ...and zero-terminate it.  */
1606   *p = '\0';
1607 }
1608
1609 /* Create the authentication header contents for the `Basic' scheme.
1610    This is done by encoding the string `USER:PASS' in base64 and
1611    prepending `HEADER: Basic ' to it.  */
1612 static char *
1613 basic_authentication_encode (const char *user, const char *passwd,
1614                              const char *header)
1615 {
1616   char *t1, *t2, *res;
1617   int len1 = strlen (user) + 1 + strlen (passwd);
1618   int len2 = BASE64_LENGTH (len1);
1619
1620   t1 = (char *)alloca (len1 + 1);
1621   sprintf (t1, "%s:%s", user, passwd);
1622   t2 = (char *)alloca (1 + len2);
1623   base64_encode (t1, t2, len1);
1624   res = (char *)malloc (len2 + 11 + strlen (header));
1625   sprintf (res, "%s: Basic %s\r\n", header, t2);
1626
1627   return res;
1628 }
1629
1630 #ifdef USE_DIGEST
1631 /* Parse HTTP `WWW-Authenticate:' header.  AU points to the beginning
1632    of a field in such a header.  If the field is the one specified by
1633    ATTR_NAME ("realm", "opaque", and "nonce" are used by the current
1634    digest authorization code), extract its value in the (char*)
1635    variable pointed by RET.  Returns negative on a malformed header,
1636    or number of bytes that have been parsed by this call.  */
1637 static int
1638 extract_header_attr (const char *au, const char *attr_name, char **ret)
1639 {
1640   const char *cp, *ep;
1641
1642   ep = cp = au;
1643
1644   if (strncmp (cp, attr_name, strlen (attr_name)) == 0)
1645     {
1646       cp += strlen (attr_name);
1647       if (!*cp)
1648         return -1;
1649       cp += skip_lws (cp);
1650       if (*cp != '=')
1651         return -1;
1652       if (!*++cp)
1653         return -1;
1654       cp += skip_lws (cp);
1655       if (*cp != '\"')
1656         return -1;
1657       if (!*++cp)
1658         return -1;
1659       for (ep = cp; *ep && *ep != '\"'; ep++)
1660         ;
1661       if (!*ep)
1662         return -1;
1663       FREE_MAYBE (*ret);
1664       *ret = strdupdelim (cp, ep);
1665       return ep - au + 1;
1666     }
1667   else
1668     return 0;
1669 }
1670
1671 /* Response value needs to be in lowercase, so we cannot use HEXD2ASC
1672    from url.h.  See RFC 2069 2.1.2 for the syntax of response-digest.  */
1673 #define HEXD2asc(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'a'))
1674
1675 /* Dump the hexadecimal representation of HASH to BUF.  HASH should be
1676    an array of 16 bytes containing the hash keys, and BUF should be a
1677    buffer of 33 writable characters (32 for hex digits plus one for
1678    zero termination).  */
1679 static void
1680 dump_hash (unsigned char *buf, const unsigned char *hash)
1681 {
1682   int i;
1683
1684   for (i = 0; i < MD5_HASHLEN; i++, hash++)
1685     {
1686       *buf++ = HEXD2asc (*hash >> 4);
1687       *buf++ = HEXD2asc (*hash & 0xf);
1688     }
1689   *buf = '\0';
1690 }
1691
1692 /* Take the line apart to find the challenge, and compose a digest
1693    authorization header.  See RFC2069 section 2.1.2.  */
1694 char *
1695 digest_authentication_encode (const char *au, const char *user,
1696                               const char *passwd, const char *method,
1697                               const char *path)
1698 {
1699   static char *realm, *opaque, *nonce;
1700   static struct {
1701     const char *name;
1702     char **variable;
1703   } options[] = {
1704     { "realm", &realm },
1705     { "opaque", &opaque },
1706     { "nonce", &nonce }
1707   };
1708   char *res;
1709
1710   realm = opaque = nonce = NULL;
1711
1712   au += 6;                      /* skip over `Digest' */
1713   while (*au)
1714     {
1715       int i;
1716
1717       au += skip_lws (au);
1718       for (i = 0; i < ARRAY_SIZE (options); i++)
1719         {
1720           int skip = extract_header_attr (au, options[i].name,
1721                                           options[i].variable);
1722           if (skip < 0)
1723             {
1724               FREE_MAYBE (realm);
1725               FREE_MAYBE (opaque);
1726               FREE_MAYBE (nonce);
1727               return NULL;
1728             }
1729           else if (skip)
1730             {
1731               au += skip;
1732               break;
1733             }
1734         }
1735       if (i == ARRAY_SIZE (options))
1736         {
1737           while (*au && *au != '=')
1738             au++;
1739           if (*au && *++au)
1740             {
1741               au += skip_lws (au);
1742               if (*au == '\"')
1743                 {
1744                   au++;
1745                   while (*au && *au != '\"')
1746                     au++;
1747                   if (*au)
1748                     au++;
1749                 }
1750             }
1751         }
1752       while (*au && *au != ',')
1753         au++;
1754       if (*au)
1755         au++;
1756     }
1757   if (!realm || !nonce || !user || !passwd || !path || !method)
1758     {
1759       FREE_MAYBE (realm);
1760       FREE_MAYBE (opaque);
1761       FREE_MAYBE (nonce);
1762       return NULL;
1763     }
1764
1765   /* Calculate the digest value.  */
1766   {
1767     struct md5_ctx ctx;
1768     unsigned char hash[MD5_HASHLEN];
1769     unsigned char a1buf[MD5_HASHLEN * 2 + 1], a2buf[MD5_HASHLEN * 2 + 1];
1770     unsigned char response_digest[MD5_HASHLEN * 2 + 1];
1771
1772     /* A1BUF = H(user ":" realm ":" password) */
1773     md5_init_ctx (&ctx);
1774     md5_process_bytes (user, strlen (user), &ctx);
1775     md5_process_bytes (":", 1, &ctx);
1776     md5_process_bytes (realm, strlen (realm), &ctx);
1777     md5_process_bytes (":", 1, &ctx);
1778     md5_process_bytes (passwd, strlen (passwd), &ctx);
1779     md5_finish_ctx (&ctx, hash);
1780     dump_hash (a1buf, hash);
1781
1782     /* A2BUF = H(method ":" path) */
1783     md5_init_ctx (&ctx);
1784     md5_process_bytes (method, strlen (method), &ctx);
1785     md5_process_bytes (":", 1, &ctx);
1786     md5_process_bytes (path, strlen (path), &ctx);
1787     md5_finish_ctx (&ctx, hash);
1788     dump_hash (a2buf, hash);
1789
1790     /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */
1791     md5_init_ctx (&ctx);
1792     md5_process_bytes (a1buf, MD5_HASHLEN * 2, &ctx);
1793     md5_process_bytes (":", 1, &ctx);
1794     md5_process_bytes (nonce, strlen (nonce), &ctx);
1795     md5_process_bytes (":", 1, &ctx);
1796     md5_process_bytes (a2buf, MD5_HASHLEN * 2, &ctx);
1797     md5_finish_ctx (&ctx, hash);
1798     dump_hash (response_digest, hash);
1799
1800     res = (char*) xmalloc (strlen (user)
1801                            + strlen (user)
1802                            + strlen (realm)
1803                            + strlen (nonce)
1804                            + strlen (path)
1805                            + 2 * MD5_HASHLEN /*strlen (response_digest)*/
1806                            + (opaque ? strlen (opaque) : 0)
1807                            + 128);
1808     sprintf (res, "Authorization: Digest \
1809 username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
1810              user, realm, nonce, path, response_digest);
1811     if (opaque)
1812       {
1813         char *p = res + strlen (res);
1814         strcat (p, ", opaque=\"");
1815         strcat (p, opaque);
1816         strcat (p, "\"");
1817       }
1818     strcat (res, "\r\n");
1819   }
1820   return res;
1821 }
1822 #endif /* USE_DIGEST */
1823
1824
1825 #define HACK_O_MATIC(line, string_constant)                             \
1826   (!strncasecmp (line, string_constant, sizeof (string_constant) - 1)   \
1827    && (ISSPACE (line[sizeof (string_constant) - 1])                     \
1828        || !line[sizeof (string_constant) - 1]))
1829
1830 static int
1831 known_authentication_scheme_p (const char *au)
1832 {
1833   return HACK_O_MATIC (au, "Basic")
1834     || HACK_O_MATIC (au, "Digest")
1835     || HACK_O_MATIC (au, "NTLM");
1836 }
1837
1838 #undef HACK_O_MATIC
1839
1840 /* Create the HTTP authorization request header.  When the
1841    `WWW-Authenticate' response header is seen, according to the
1842    authorization scheme specified in that header (`Basic' and `Digest'
1843    are supported by the current implementation), produce an
1844    appropriate HTTP authorization request header.  */
1845 static char *
1846 create_authorization_line (const char *au, const char *user,
1847                            const char *passwd, const char *method,
1848                            const char *path)
1849 {
1850   char *wwwauth = NULL;
1851
1852   if (!strncasecmp (au, "Basic", 5))
1853     wwwauth = basic_authentication_encode (user, passwd, "Authorization");
1854   if (!strncasecmp (au, "NTLM", 4))
1855     wwwauth = basic_authentication_encode (user, passwd, "Authorization");
1856 #ifdef USE_DIGEST
1857   else if (!strncasecmp (au, "Digest", 6))
1858     wwwauth = digest_authentication_encode (au, user, passwd, method, path);
1859 #endif /* USE_DIGEST */
1860   return wwwauth;
1861 }