]> sjero.net Git - wget/blob - src/http.c
[svn] Implemented the item I formerly had in the TODO: When -K and -N are used
[wget] / src / http.c
1 /* HTTP support.
2    Copyright (C) 1995, 1996, 1997, 1998 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   *result = xstrdup (hdr);
245   p = strrchr (hdr, ';');
246   if (p)
247     {
248       int len = p - hdr;
249       *result = (char *)xmalloc (len + 1);
250       memcpy (*result, hdr, len);
251       (*result)[len] = '\0';
252     }
253   else
254     *result = xstrdup (hdr);
255   return 1;
256 }
257
258 \f
259 struct http_stat
260 {
261   long len;                     /* received length */
262   long contlen;                 /* expected length */
263   long restval;                 /* the restart value */
264   int res;                      /* the result of last read */
265   char *newloc;                 /* new location (redirection) */
266   char *remote_time;            /* remote time-stamp string */
267   char *error;                  /* textual HTTP error */
268   int statcode;                 /* status code */
269   long dltime;                  /* time of the download */
270 };
271
272 /* Free the elements of hstat X.  */
273 #define FREEHSTAT(x) do                                 \
274 {                                                       \
275   FREE_MAYBE ((x).newloc);                              \
276   FREE_MAYBE ((x).remote_time);                         \
277   FREE_MAYBE ((x).error);                               \
278   (x).newloc = (x).remote_time = (x).error = NULL;      \
279 } while (0)
280
281 static char *create_authorization_line PARAMS ((const char *, const char *,
282                                                 const char *, const char *,
283                                                 const char *));
284 static char *basic_authentication_encode PARAMS ((const char *, const char *,
285                                                   const char *));
286 static int known_authentication_scheme_p PARAMS ((const char *));
287
288 static time_t http_atotm PARAMS ((char *));
289
290 /* Retrieve a document through HTTP protocol.  It recognizes status
291    code, and correctly handles redirections.  It closes the network
292    socket.  If it receives an error from the functions below it, it
293    will print it if there is enough information to do so (almost
294    always), returning the error to the caller (i.e. http_loop).
295
296    Various HTTP parameters are stored to hs.  Although it parses the
297    response code correctly, it is not used in a sane way.  The caller
298    can do that, though.
299
300    If u->proxy is non-NULL, the URL u will be taken as a proxy URL,
301    and u->proxy->url will be given to the proxy server (bad naming,
302    I'm afraid).  */
303 static uerr_t
304 gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
305 {
306   char *request, *type, *command, *path;
307   char *user, *passwd;
308   char *pragma_h, *referer, *useragent, *range, *wwwauth, *remhost;
309   char *authenticate_h;
310   char *proxyauth;
311   char *all_headers;
312   int sock, hcount, num_written, all_length, remport, statcode;
313   long contlen, contrange;
314   struct urlinfo *ou;
315   uerr_t err;
316   FILE *fp;
317   int auth_tried_already;
318   struct rbuf rbuf;
319
320   /* Let the others worry about local filename...  */
321   if (!(*dt & HEAD_ONLY))
322     assert (u->local != NULL);
323
324   authenticate_h = 0;
325   auth_tried_already = 0;
326
327  again:
328   /* We need to come back here when the initial attempt to retrieve
329      without authorization header fails.  */
330
331   /* Initialize certain elements of struct hstat.  */
332   hs->len = 0L;
333   hs->contlen = -1;
334   hs->res = -1;
335   hs->newloc = NULL;
336   hs->remote_time = NULL;
337   hs->error = NULL;
338
339   /* Which structure to use to retrieve the original URL data.  */
340   if (u->proxy)
341     ou = u->proxy;
342   else
343     ou = u;
344
345   /* First: establish the connection.  */
346   logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
347   err = make_connection (&sock, u->host, u->port);
348   switch (err)
349     {
350     case HOSTERR:
351       logputs (LOG_VERBOSE, "\n");
352       logprintf (LOG_NOTQUIET, "%s: %s.\n", u->host, herrmsg (h_errno));
353       return HOSTERR;
354       break;
355     case CONSOCKERR:
356       logputs (LOG_VERBOSE, "\n");
357       logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
358       return CONSOCKERR;
359       break;
360     case CONREFUSED:
361       logputs (LOG_VERBOSE, "\n");
362       logprintf (LOG_NOTQUIET,
363                  _("Connection to %s:%hu refused.\n"), u->host, u->port);
364       CLOSE (sock);
365       return CONREFUSED;
366     case CONERROR:
367       logputs (LOG_VERBOSE, "\n");
368       logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
369       CLOSE (sock);
370       return CONERROR;
371       break;
372     case NOCONERROR:
373       /* Everything is fine!  */
374       logputs (LOG_VERBOSE, _("connected!\n"));
375       break;
376     default:
377       abort ();
378       break;
379     } /* switch */
380
381   if (u->proxy)
382     path = u->proxy->url;
383   else
384     path = u->path;
385   command = (*dt & HEAD_ONLY) ? "HEAD" : "GET";
386   referer = NULL;
387   if (ou->referer)
388     {
389       referer = (char *)alloca (9 + strlen (ou->referer) + 3);
390       sprintf (referer, "Referer: %s\r\n", ou->referer);
391     }
392   if (*dt & SEND_NOCACHE)
393     pragma_h = "Pragma: no-cache\r\n";
394   else
395     pragma_h = "";
396   if (hs->restval)
397     {
398       range = (char *)alloca (13 + numdigit (hs->restval) + 4);
399       /* #### Gag me!  Some servers (e.g. WebSitePro) have been known
400          to misinterpret the following `Range' format, and return the
401          document as multipart/x-byte-ranges MIME type!
402
403          #### TODO: Interpret MIME types, recognize bullshits similar
404          the one described above, and deal with them!  */
405       sprintf (range, "Range: bytes=%ld-\r\n", hs->restval);
406     }
407   else
408     range = NULL;
409   if (opt.useragent)
410     STRDUP_ALLOCA (useragent, opt.useragent);
411   else
412     {
413       useragent = (char *)alloca (10 + strlen (version_string));
414       sprintf (useragent, "Wget/%s", version_string);
415     }
416   /* Construct the authentication, if userid is present.  */
417   user = ou->user;
418   passwd = ou->passwd;
419   search_netrc (u->host, (const char **)&user, (const char **)&passwd, 0);
420   user = user ? user : opt.http_user;
421   passwd = passwd ? passwd : opt.http_passwd;
422
423   wwwauth = NULL;
424   if (authenticate_h && user && passwd)
425     {
426       wwwauth = create_authorization_line (authenticate_h, user, passwd,
427                                            command, ou->path);
428     }
429
430   proxyauth = NULL;
431   if (u->proxy)
432     {
433       char *proxy_user, *proxy_passwd;
434       /* For normal username and password, URL components override
435          command-line/wgetrc parameters.  With proxy authentication,
436          it's the reverse, because proxy URLs are normally the
437          "permanent" ones, so command-line args should take
438          precedence.  */
439       if (opt.proxy_user && opt.proxy_passwd)
440         {
441           proxy_user = opt.proxy_user;
442           proxy_passwd = opt.proxy_passwd;
443         }
444       else
445         {
446           proxy_user = u->user;
447           proxy_passwd = u->passwd;
448         }
449       /* #### This is junky.  Can't the proxy request, say, `Digest'
450          authentication?  */
451       if (proxy_user && proxy_passwd)
452         proxyauth = basic_authentication_encode (proxy_user, proxy_passwd,
453                                                  "Proxy-Authorization");
454     }
455   remhost = ou->host;
456   remport = ou->port;
457   /* Allocate the memory for the request.  */
458   request = (char *)alloca (strlen (command) + strlen (path)
459                             + strlen (useragent)
460                             + strlen (remhost) + numdigit (remport)
461                             + strlen (HTTP_ACCEPT)
462                             + (referer ? strlen (referer) : 0)
463                             + (wwwauth ? strlen (wwwauth) : 0)
464                             + (proxyauth ? strlen (proxyauth) : 0)
465                             + (range ? strlen (range) : 0)
466                             + strlen (pragma_h)
467                             + (opt.user_header ? strlen (opt.user_header) : 0)
468                             + 64);
469   /* Construct the request.  */
470   sprintf (request, "\
471 %s %s HTTP/1.0\r\n\
472 User-Agent: %s\r\n\
473 Host: %s:%d\r\n\
474 Accept: %s\r\n\
475 %s%s%s%s%s%s\r\n",
476           command, path, useragent, remhost, remport, HTTP_ACCEPT, 
477           referer ? referer : "", 
478           wwwauth ? wwwauth : "", 
479           proxyauth ? proxyauth : "", 
480           range ? range : "",
481           pragma_h, 
482           opt.user_header ? opt.user_header : "");
483   DEBUGP (("---request begin---\n%s---request end---\n", request));
484    /* Free the temporary memory.  */
485   FREE_MAYBE (wwwauth);
486   FREE_MAYBE (proxyauth);
487
488   /* Send the request to server.  */
489   num_written = iwrite (sock, request, strlen (request));
490   if (num_written < 0)
491     {
492       logputs (LOG_VERBOSE, _("Failed writing HTTP request.\n"));
493       free (request);
494       CLOSE (sock);
495       return WRITEFAILED;
496     }
497   logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "),
498              u->proxy ? "Proxy" : "HTTP");
499   contlen = contrange = -1;
500   type = NULL;
501   statcode = -1;
502   *dt &= ~RETROKF;
503
504   /* Before reading anything, initialize the rbuf.  */
505   rbuf_initialize (&rbuf, sock);
506
507   all_headers = NULL;
508   all_length = 0;
509   /* Header-fetching loop.  */
510   hcount = 0;
511   while (1)
512     {
513       char *hdr;
514       int status;
515
516       ++hcount;
517       /* Get the header.  */
518       status = header_get (&rbuf, &hdr,
519                            /* Disallow continuations for status line.  */
520                            (hcount == 1 ? HG_NO_CONTINUATIONS : HG_NONE));
521
522       /* Check for errors.  */
523       if (status == HG_EOF && *hdr)
524         {
525           /* This used to be an unconditional error, but that was
526              somewhat controversial, because of a large number of
527              broken CGI's that happily "forget" to send the second EOL
528              before closing the connection of a HEAD request.
529
530              So, the deal is to check whether the header is empty
531              (*hdr is zero if it is); if yes, it means that the
532              previous header was fully retrieved, and that -- most
533              probably -- the request is complete.  "...be liberal in
534              what you accept."  Oh boy.  */
535           logputs (LOG_VERBOSE, "\n");
536           logputs (LOG_NOTQUIET, _("End of file while parsing headers.\n"));
537           free (hdr);
538           FREE_MAYBE (type);
539           FREE_MAYBE (hs->newloc);
540           FREE_MAYBE (all_headers);
541           CLOSE (sock);
542           return HEOF;
543         }
544       else if (status == HG_ERROR)
545         {
546           logputs (LOG_VERBOSE, "\n");
547           logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
548                      strerror (errno));
549           free (hdr);
550           FREE_MAYBE (type);
551           FREE_MAYBE (hs->newloc);
552           FREE_MAYBE (all_headers);
553           CLOSE (sock);
554           return HERR;
555         }
556
557       /* If the headers are to be saved to a file later, save them to
558          memory now.  */
559       if (opt.save_headers)
560         {
561           int lh = strlen (hdr);
562           all_headers = (char *)xrealloc (all_headers, all_length + lh + 2);
563           memcpy (all_headers + all_length, hdr, lh);
564           all_length += lh;
565           all_headers[all_length++] = '\n';
566           all_headers[all_length] = '\0';
567         }
568
569       /* Print the header if requested.  */
570       if (opt.server_response && hcount != 1)
571         logprintf (LOG_VERBOSE, "\n%d %s", hcount, hdr);
572
573       /* Check for status line.  */
574       if (hcount == 1)
575         {
576           const char *error;
577           /* Parse the first line of server response.  */
578           statcode = parse_http_status_line (hdr, &error);
579           hs->statcode = statcode;
580           /* Store the descriptive response.  */
581           if (statcode == -1) /* malformed response */
582             {
583               /* A common reason for "malformed response" error is the
584                  case when no data was actually received.  Handle this
585                  special case.  */
586               if (!*hdr)
587                 hs->error = xstrdup (_("No data received"));
588               else
589                 hs->error = xstrdup (_("Malformed status line"));
590               free (hdr);
591               break;
592             }
593           else if (!*error)
594             hs->error = xstrdup (_("(no description)"));
595           else
596             hs->error = xstrdup (error);
597
598           if ((statcode != -1)
599 #ifdef DEBUG
600               && !opt.debug
601 #endif
602               )
603             logprintf (LOG_VERBOSE, "%d %s", statcode, error);
604
605           goto done_header;
606         }
607
608       /* Exit on empty header.  */
609       if (!*hdr)
610         {
611           free (hdr);
612           break;
613         }
614
615       /* Try getting content-length.  */
616       if (contlen == -1 && !opt.ignore_length)
617         if (header_process (hdr, "Content-Length", header_extract_number,
618                             &contlen))
619           goto done_header;
620       /* Try getting content-type.  */
621       if (!type)
622         if (header_process (hdr, "Content-Type", http_process_type, &type))
623           goto done_header;
624       /* Try getting location.  */
625       if (!hs->newloc)
626         if (header_process (hdr, "Location", header_strdup, &hs->newloc))
627           goto done_header;
628       /* Try getting last-modified.  */
629       if (!hs->remote_time)
630         if (header_process (hdr, "Last-Modified", header_strdup,
631                             &hs->remote_time))
632           goto done_header;
633       /* Try getting www-authentication.  */
634       if (!authenticate_h)
635         if (header_process (hdr, "WWW-Authenticate", header_strdup,
636                             &authenticate_h))
637           goto done_header;
638       /* Check for accept-ranges header.  If it contains the word
639          `none', disable the ranges.  */
640       if (*dt & ACCEPTRANGES)
641         {
642           int nonep;
643           if (header_process (hdr, "Accept-Ranges", http_process_none, &nonep))
644             {
645               if (nonep)
646                 *dt &= ~ACCEPTRANGES;
647               goto done_header;
648             }
649         }
650       /* Try getting content-range.  */
651       if (contrange == -1)
652         {
653           struct http_process_range_closure closure;
654           if (header_process (hdr, "Content-Range", http_process_range, &closure))
655             {
656               contrange = closure.first_byte_pos;
657               goto done_header;
658             }
659         }
660     done_header:
661       free (hdr);
662     }
663
664   logputs (LOG_VERBOSE, "\n");
665
666   if ((statcode == HTTP_STATUS_UNAUTHORIZED)
667       && authenticate_h)
668     {
669       /* Authorization is required.  */
670       FREE_MAYBE (type);
671       type = NULL;
672       FREEHSTAT (*hs);
673       CLOSE (sock);
674       if (auth_tried_already)
675         {
676           /* If we have tried it already, then there is not point
677              retrying it.  */
678           logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
679           free (authenticate_h);
680           return AUTHFAILED;
681         }
682       else if (!known_authentication_scheme_p (authenticate_h))
683         {
684           free (authenticate_h);
685           logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n"));
686           return AUTHFAILED;
687         }
688       else
689         {
690           auth_tried_already = 1;
691           goto again;
692         }
693     }
694   /* We do not need this anymore.  */
695   if (authenticate_h)
696     {
697       free (authenticate_h);
698       authenticate_h = NULL;
699     }
700
701   /* 20x responses are counted among successful by default.  */
702   if (H_20X (statcode))
703     *dt |= RETROKF;
704
705   if (type && !strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)))
706     *dt |= TEXTHTML;
707   else
708     /* We don't assume text/html by default.  */
709     *dt &= ~TEXTHTML;
710
711   if (contrange == -1)
712     hs->restval = 0;
713   else if (contrange != hs->restval ||
714            (H_PARTIAL (statcode) && contrange == -1))
715     {
716       /* This means the whole request was somehow misunderstood by the
717          server.  Bail out.  */
718       FREE_MAYBE (type);
719       FREE_MAYBE (hs->newloc);
720       FREE_MAYBE (all_headers);
721       CLOSE (sock);
722       return RANGEERR;
723     }
724
725   if (hs->restval)
726     {
727       if (contlen != -1)
728         contlen += contrange;
729       else
730         contrange = -1;        /* If conent-length was not sent,
731                                   content-range will be ignored.  */
732     }
733   hs->contlen = contlen;
734
735   /* Return if redirected.  */
736   if (H_REDIRECTED (statcode) || statcode == HTTP_STATUS_MULTIPLE_CHOICES)
737     {
738       /* RFC2068 says that in case of the 300 (multiple choices)
739          response, the server can output a preferred URL through
740          `Location' header; otherwise, the request should be treated
741          like GET.  So, if the location is set, it will be a
742          redirection; otherwise, just proceed normally.  */
743       if (statcode == HTTP_STATUS_MULTIPLE_CHOICES && !hs->newloc)
744         *dt |= RETROKF;
745       else
746         {
747           logprintf (LOG_VERBOSE,
748                      _("Location: %s%s\n"),
749                      hs->newloc ? hs->newloc : _("unspecified"),
750                      hs->newloc ? _(" [following]") : "");
751           CLOSE (sock);
752           FREE_MAYBE (type);
753           FREE_MAYBE (all_headers);
754           return NEWLOCATION;
755         }
756     }
757   if (opt.verbose)
758     {
759       if ((*dt & RETROKF) && !opt.server_response)
760         {
761           /* No need to print this output if the body won't be
762              downloaded at all, or if the original server response is
763              printed.  */
764           logputs (LOG_VERBOSE, _("Length: "));
765           if (contlen != -1)
766             {
767               logputs (LOG_VERBOSE, legible (contlen));
768               if (contrange != -1)
769                 logprintf (LOG_VERBOSE, _(" (%s to go)"),
770                            legible (contlen - contrange));
771             }
772           else
773             logputs (LOG_VERBOSE,
774                      opt.ignore_length ? _("ignored") : _("unspecified"));
775           if (type)
776             logprintf (LOG_VERBOSE, " [%s]\n", type);
777           else
778             logputs (LOG_VERBOSE, "\n");
779         }
780     }
781   FREE_MAYBE (type);
782   type = NULL;                  /* We don't need it any more.  */
783
784   /* Return if we have no intention of further downloading.  */
785   if (!(*dt & RETROKF) || (*dt & HEAD_ONLY))
786     {
787       /* In case someone cares to look...  */
788       hs->len = 0L;
789       hs->res = 0;
790       FREE_MAYBE (type);
791       FREE_MAYBE (all_headers);
792       CLOSE (sock);
793       return RETRFINISHED;
794     }
795
796   /* Open the local file.  */
797   if (!opt.dfp)
798     {
799       mkalldirs (u->local);
800       if (opt.backups)
801         rotate_backups (u->local);
802       fp = fopen (u->local, hs->restval ? "ab" : "wb");
803       if (!fp)
804         {
805           logprintf (LOG_NOTQUIET, "%s: %s\n", u->local, strerror (errno));
806           CLOSE (sock);
807           FREE_MAYBE (all_headers);
808           return FOPENERR;
809         }
810     }
811   else                      /* opt.dfp */
812     fp = opt.dfp;
813
814   /* #### This confuses the code that checks for file size.  There
815      should be some overhead information.  */
816   if (opt.save_headers)
817     fwrite (all_headers, 1, all_length, fp);
818   reset_timer ();
819   /* Get the contents of the document.  */
820   hs->res = get_contents (sock, fp, &hs->len, hs->restval,
821                           (contlen != -1 ? contlen : 0),
822                           &rbuf);
823   hs->dltime = elapsed_time ();
824   if (!opt.dfp)
825     fclose (fp);
826   else
827     fflush (fp);
828   FREE_MAYBE (all_headers);
829   CLOSE (sock);
830   if (hs->res == -2)
831     return FWRITEERR;
832   return RETRFINISHED;
833 }
834
835 /* The genuine HTTP loop!  This is the part where the retrieval is
836    retried, and retried, and retried, and...  */
837 uerr_t
838 http_loop (struct urlinfo *u, char **newloc, int *dt)
839 {
840   static int first_retrieval = 1;
841
842   int count;
843   int local_dot_orig_file_exists = FALSE;
844   int use_ts, got_head = 0;     /* time-stamping info */
845   char *tms, *suf, *locf, *tmrate;
846   uerr_t err;
847   time_t tml = -1, tmr = -1;    /* local and remote time-stamps */
848   long local_size = 0;          /* the size of the local file */
849   struct http_stat hstat;       /* HTTP status */
850   struct stat st;
851
852   *newloc = NULL;
853
854   /* Warn on (likely bogus) wildcard usage in HTTP.  Don't use
855      has_wildcards_p because it would also warn on `?', and we know that
856      shows up in CGI paths a *lot*.  */
857   if (strchr (u->url, '*'))
858     logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
859
860   /* Determine the local filename.  */
861   if (!u->local)
862     u->local = url_filename (u->proxy ? u->proxy : u);
863
864   if (!opt.output_document)
865     locf = u->local;
866   else
867     locf = opt.output_document;
868
869   if (opt.noclobber && file_exists_p (u->local))
870     {
871       /* If opt.noclobber is turned on and file already exists, do not
872          retrieve the file */
873       logprintf (LOG_VERBOSE, _("\
874 File `%s' already there, will not retrieve.\n"), u->local);
875       /* If the file is there, we suppose it's retrieved OK.  */
876       *dt |= RETROKF;
877
878       /* #### Bogusness alert.  */
879       /* If its suffix is "html" or (yuck!) "htm", we suppose it's
880          text/html, a harmless lie.  */
881       if (((suf = suffix (u->local)) != NULL)
882           && (!strcmp (suf, "html") || !strcmp (suf, "htm")))
883         *dt |= TEXTHTML;
884       free (suf);
885       /* Another harmless lie: */
886       return RETROK;
887     }
888
889   use_ts = 0;
890   if (opt.timestamping)
891     {
892       boolean  local_file_exists = FALSE;
893
894       if (opt.backup_converted)
895         /* If -K is specified, we'll act on the assumption that it was specified
896            last time these files were downloaded as well, and instead of just
897            comparing local file X against server file X, we'll compare local
898            file X.orig (if extant, else X) against server file X.  If -K
899            _wasn't_ specified last time, or the server contains files called
900            *.orig, -N will be back to not operating correctly with -k. */
901         {
902           size_t filename_len = strlen(u->local);
903           char*  filename_plus_orig_suffix = malloc(filename_len +
904                                                     sizeof(".orig"));
905
906           /* Would a single s[n]printf() call be faster? */
907           strcpy(filename_plus_orig_suffix, u->local);
908           strcpy(filename_plus_orig_suffix + filename_len, ".orig");
909
910           /* Try to stat() the .orig file. */
911           if (stat(filename_plus_orig_suffix, &st) == 0)
912             {
913               local_file_exists = TRUE;
914               local_dot_orig_file_exists = TRUE;
915             }
916
917           free(filename_plus_orig_suffix);
918         }      
919
920       if (!local_dot_orig_file_exists)
921         /* Couldn't stat() <file>.orig, so try to stat() <file>. */
922         if (stat (u->local, &st) == 0)
923           local_file_exists = TRUE;
924
925       if (local_file_exists)
926         /* There was a local file, so we'll check later to see if the version
927            the server has is the same version we already have, allowing us to
928            skip a download. */
929         {
930           use_ts = 1;
931           tml = st.st_mtime;
932           local_size = st.st_size;
933           got_head = 0;
934         }
935     }
936   /* Reset the counter.  */
937   count = 0;
938   *dt = 0 | ACCEPTRANGES;
939   /* THE loop */
940   do
941     {
942       /* Increment the pass counter.  */
943       ++count;
944       /* Wait before the retrieval (unless this is the very first
945          retrieval).  */
946       if (!first_retrieval && opt.wait)
947         sleep (opt.wait);
948       if (first_retrieval)
949         first_retrieval = 0;
950       /* Get the current time string.  */
951       tms = time_str (NULL);
952       /* Print fetch message, if opt.verbose.  */
953       if (opt.verbose)
954         {
955           char *hurl = str_url (u->proxy ? u->proxy : u, 1);
956           char tmp[15];
957           strcpy (tmp, "        ");
958           if (count > 1)
959             sprintf (tmp, _("(try:%2d)"), count);
960           logprintf (LOG_VERBOSE, "--%s--  %s\n  %s => `%s'\n",
961                      tms, hurl, tmp, locf);
962 #ifdef WINDOWS
963           ws_changetitle (hurl, 1);
964 #endif
965           free (hurl);
966         }
967
968       /* Default document type is empty.  However, if spider mode is
969          on or time-stamping is employed, HEAD_ONLY commands is
970          encoded within *dt.  */
971       if (opt.spider || (use_ts && !got_head))
972         *dt |= HEAD_ONLY;
973       else
974         *dt &= ~HEAD_ONLY;
975       /* Assume no restarting.  */
976       hstat.restval = 0L;
977       /* Decide whether or not to restart.  */
978       if (((count > 1 && (*dt & ACCEPTRANGES)) || opt.always_rest)
979           && file_exists_p (u->local))
980         if (stat (u->local, &st) == 0)
981           hstat.restval = st.st_size;
982       /* Decide whether to send the no-cache directive.  */
983       if (u->proxy && (count > 1 || (opt.proxy_cache == 0)))
984         *dt |= SEND_NOCACHE;
985       else
986         *dt &= ~SEND_NOCACHE;
987
988       /* Try fetching the document, or at least its head.  :-) */
989       err = gethttp (u, &hstat, dt);
990       /* Time?  */
991       tms = time_str (NULL);
992       /* Get the new location (with or without the redirection).  */
993       if (hstat.newloc)
994         *newloc = xstrdup (hstat.newloc);
995       switch (err)
996         {
997         case HERR: case HEOF: case CONSOCKERR: case CONCLOSED:
998         case CONERROR: case READERR: case WRITEFAILED:
999         case RANGEERR:
1000           /* Non-fatal errors continue executing the loop, which will
1001              bring them to "while" statement at the end, to judge
1002              whether the number of tries was exceeded.  */
1003           FREEHSTAT (hstat);
1004           printwhat (count, opt.ntry);
1005           continue;
1006           break;
1007         case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED:
1008           /* Fatal errors just return from the function.  */
1009           FREEHSTAT (hstat);
1010           return err;
1011           break;
1012         case FWRITEERR: case FOPENERR:
1013           /* Another fatal error.  */
1014           logputs (LOG_VERBOSE, "\n");
1015           logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"),
1016                      u->local, strerror (errno));
1017           FREEHSTAT (hstat);
1018           return err;
1019           break;
1020         case NEWLOCATION:
1021           /* Return the new location to the caller.  */
1022           if (!hstat.newloc)
1023             {
1024               logprintf (LOG_NOTQUIET,
1025                          _("ERROR: Redirection (%d) without location.\n"),
1026                          hstat.statcode);
1027               return WRONGCODE;
1028             }
1029           FREEHSTAT (hstat);
1030           return NEWLOCATION;
1031           break;
1032         case RETRFINISHED:
1033           /* Deal with you later.  */
1034           break;
1035         default:
1036           /* All possibilities should have been exhausted.  */
1037           abort ();
1038         }
1039       if (!(*dt & RETROKF))
1040         {
1041           if (!opt.verbose)
1042             {
1043               /* #### Ugly ugly ugly! */
1044               char *hurl = str_url (u->proxy ? u->proxy : u, 1);
1045               logprintf (LOG_NONVERBOSE, "%s:\n", hurl);
1046               free (hurl);
1047             }
1048           logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"),
1049                      tms, hstat.statcode, hstat.error);
1050           logputs (LOG_VERBOSE, "\n");
1051           FREEHSTAT (hstat);
1052           return WRONGCODE;
1053         }
1054
1055       /* Did we get the time-stamp?  */
1056       if (!got_head)
1057         {
1058           if (opt.timestamping && !hstat.remote_time)
1059             {
1060               logputs (LOG_NOTQUIET, _("\
1061 Last-modified header missing -- time-stamps turned off.\n"));
1062             }
1063           else if (hstat.remote_time)
1064             {
1065               /* Convert the date-string into struct tm.  */
1066               tmr = http_atotm (hstat.remote_time);
1067               if (tmr == (time_t) (-1))
1068                 logputs (LOG_VERBOSE, _("\
1069 Last-modified header invalid -- time-stamp ignored.\n"));
1070             }
1071         }
1072
1073       /* The time-stamping section.  */
1074       if (use_ts)
1075         {
1076           got_head = 1;
1077           *dt &= ~HEAD_ONLY;
1078           use_ts = 0;           /* no more time-stamping */
1079           count = 0;            /* the retrieve count for HEAD is
1080                                    reset */
1081           if (hstat.remote_time && tmr != (time_t) (-1))
1082             {
1083               /* Now time-stamping can be used validly.  Time-stamping
1084                  means that if the sizes of the local and remote file
1085                  match, and local file is newer than the remote file,
1086                  it will not be retrieved.  Otherwise, the normal
1087                  download procedure is resumed.  */
1088               if (tml >= tmr &&
1089                   (hstat.contlen == -1 || local_size == hstat.contlen))
1090                 {
1091                   if (local_dot_orig_file_exists)
1092                     /* We can't collapse this down into just one logprintf()
1093                        call with a variable set to u->local or the .orig
1094                        filename because we have to malloc() space for the
1095                        latter, and because there are multiple returns above (a
1096                        coding style no-no by many measures, for reasons such as
1097                        this) we'd have to remember to free() the string at each
1098                        one to avoid a memory leak. */
1099                     logprintf (LOG_VERBOSE, _("\
1100 Server file no newer than local file `%s.orig' -- not retrieving.\n\n"),
1101                                u->local);
1102                   else
1103                     logprintf (LOG_VERBOSE, _("\
1104 Server file no newer than local file `%s' -- not retrieving.\n\n"), u->local);
1105                   FREEHSTAT (hstat);
1106                   return RETROK;
1107                 }
1108               else if (tml >= tmr)
1109                 logprintf (LOG_VERBOSE, _("\
1110 The sizes do not match (local %ld) -- retrieving.\n"), local_size);
1111               else
1112                 logputs (LOG_VERBOSE,
1113                          _("Remote file is newer, retrieving.\n"));
1114             }
1115           FREEHSTAT (hstat);
1116           continue;
1117         }
1118       if (!opt.dfp
1119           && (tmr != (time_t) (-1))
1120           && !opt.spider
1121           && ((hstat.len == hstat.contlen) ||
1122               ((hstat.res == 0) &&
1123                ((hstat.contlen == -1) ||
1124                 (hstat.len >= hstat.contlen && !opt.kill_longer)))))
1125         {
1126           touch (u->local, tmr);
1127         }
1128       /* End of time-stamping section.  */
1129
1130       if (opt.spider)
1131         {
1132           logprintf (LOG_NOTQUIET, "%d %s\n\n", hstat.statcode, hstat.error);
1133           return RETROK;
1134         }
1135
1136       /* It is now safe to free the remainder of hstat, since the
1137          strings within it will no longer be used.  */
1138       FREEHSTAT (hstat);
1139
1140       tmrate = rate (hstat.len - hstat.restval, hstat.dltime);
1141
1142       if (hstat.len == hstat.contlen)
1143         {
1144           if (*dt & RETROKF)
1145             {
1146               logprintf (LOG_VERBOSE,
1147                          _("%s (%s) - `%s' saved [%ld/%ld]\n\n"),
1148                          tms, tmrate, locf, hstat.len, hstat.contlen);
1149               logprintf (LOG_NONVERBOSE,
1150                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
1151                          tms, u->url, hstat.len, hstat.contlen, locf, count);
1152             }
1153           ++opt.numurls;
1154           opt.downloaded += hstat.len;
1155           downloaded_file(ADD_FILE, locf);
1156           return RETROK;
1157         }
1158       else if (hstat.res == 0) /* No read error */
1159         {
1160           if (hstat.contlen == -1)  /* We don't know how much we were supposed
1161                                        to get, so assume we succeeded. */ 
1162             {
1163               if (*dt & RETROKF)
1164                 {
1165                   logprintf (LOG_VERBOSE,
1166                              _("%s (%s) - `%s' saved [%ld]\n\n"),
1167                              tms, tmrate, locf, hstat.len);
1168                   logprintf (LOG_NONVERBOSE,
1169                              "%s URL:%s [%ld] -> \"%s\" [%d]\n",
1170                              tms, u->url, hstat.len, locf, count);
1171                 }
1172               ++opt.numurls;
1173               opt.downloaded += hstat.len;
1174               downloaded_file(ADD_FILE, locf);
1175               return RETROK;
1176             }
1177           else if (hstat.len < hstat.contlen) /* meaning we lost the
1178                                                  connection too soon */
1179             {
1180               logprintf (LOG_VERBOSE,
1181                          _("%s (%s) - Connection closed at byte %ld. "),
1182                          tms, tmrate, hstat.len);
1183               printwhat (count, opt.ntry);
1184               continue;
1185             }
1186           else if (!opt.kill_longer) /* meaning we got more than expected */
1187             {
1188               logprintf (LOG_VERBOSE,
1189                          _("%s (%s) - `%s' saved [%ld/%ld])\n\n"),
1190                          tms, tmrate, locf, hstat.len, hstat.contlen);
1191               logprintf (LOG_NONVERBOSE,
1192                          "%s URL:%s [%ld/%ld] -> \"%s\" [%d]\n",
1193                          tms, u->url, hstat.len, hstat.contlen, locf, count);
1194               ++opt.numurls;
1195               opt.downloaded += hstat.len;
1196               downloaded_file(ADD_FILE, locf);
1197               return RETROK;
1198             }
1199           else                  /* the same, but not accepted */
1200             {
1201               logprintf (LOG_VERBOSE,
1202                          _("%s (%s) - Connection closed at byte %ld/%ld. "),
1203                          tms, tmrate, hstat.len, hstat.contlen);
1204               printwhat (count, opt.ntry);
1205               continue;
1206             }
1207         }
1208       else                      /* now hstat.res can only be -1 */
1209         {
1210           if (hstat.contlen == -1)
1211             {
1212               logprintf (LOG_VERBOSE,
1213                          _("%s (%s) - Read error at byte %ld (%s)."),
1214                          tms, tmrate, hstat.len, strerror (errno));
1215               printwhat (count, opt.ntry);
1216               continue;
1217             }
1218           else                  /* hstat.res == -1 and contlen is given */
1219             {
1220               logprintf (LOG_VERBOSE,
1221                          _("%s (%s) - Read error at byte %ld/%ld (%s). "),
1222                          tms, tmrate, hstat.len, hstat.contlen,
1223                          strerror (errno));
1224               printwhat (count, opt.ntry);
1225               continue;
1226             }
1227         }
1228       /* not reached */
1229       break;
1230     }
1231   while (!opt.ntry || (count < opt.ntry));
1232   return TRYLIMEXC;
1233 }
1234 \f
1235 /* Converts struct tm to time_t, assuming the data in tm is UTC rather
1236    than local timezone (mktime assumes the latter).
1237
1238    Contributed by Roger Beeman <beeman@cisco.com>, with the help of
1239    Mark Baushke <mdb@cisco.com> and the rest of the Gurus at CISCO.  */
1240 static time_t
1241 mktime_from_utc (struct tm *t)
1242 {
1243   time_t tl, tb;
1244
1245   tl = mktime (t);
1246   if (tl == -1)
1247     return -1;
1248   tb = mktime (gmtime (&tl));
1249   return (tl <= tb ? (tl + (tl - tb)) : (tl - (tb - tl)));
1250 }
1251
1252 /* Check whether the result of strptime() indicates success.
1253    strptime() returns the pointer to how far it got to in the string.
1254    The processing has been successful if the string is at `GMT' or
1255    `+X', or at the end of the string.
1256
1257    In extended regexp parlance, the function returns 1 if P matches
1258    "^ *(GMT|[+-][0-9]|$)", 0 otherwise.  P being NULL (a valid result of
1259    strptime()) is considered a failure and 0 is returned.  */
1260 static int
1261 check_end (char *p)
1262 {
1263   if (!p)
1264     return 0;
1265   while (ISSPACE (*p))
1266     ++p;
1267   if (!*p
1268       || (p[0] == 'G' && p[1] == 'M' && p[2] == 'T')
1269       || ((p[0] == '+' || p[1] == '-') && ISDIGIT (p[1])))
1270     return 1;
1271   else
1272     return 0;
1273 }
1274
1275 /* Convert TIME_STRING time to time_t.  TIME_STRING can be in any of
1276    the three formats RFC2068 allows the HTTP servers to emit --
1277    RFC1123-date, RFC850-date or asctime-date.  Timezones are ignored,
1278    and should be GMT.
1279
1280    We use strptime() to recognize various dates, which makes it a
1281    little bit slacker than the RFC1123/RFC850/asctime (e.g. it always
1282    allows shortened dates and months, one-digit days, etc.).  It also
1283    allows more than one space anywhere where the specs require one SP.
1284    The routine should probably be even more forgiving (as recommended
1285    by RFC2068), but I do not have the time to write one.
1286
1287    Return the computed time_t representation, or -1 if all the
1288    schemes fail.
1289
1290    Needless to say, what we *really* need here is something like
1291    Marcus Hennecke's atotm(), which is forgiving, fast, to-the-point,
1292    and does not use strptime().  atotm() is to be found in the sources
1293    of `phttpd', a little-known HTTP server written by Peter Erikson.  */
1294 static time_t
1295 http_atotm (char *time_string)
1296 {
1297   struct tm t;
1298
1299   /* Roger Beeman says: "This function dynamically allocates struct tm
1300      t, but does no initialization.  The only field that actually
1301      needs initialization is tm_isdst, since the others will be set by
1302      strptime.  Since strptime does not set tm_isdst, it will return
1303      the data structure with whatever data was in tm_isdst to begin
1304      with.  For those of us in timezones where DST can occur, there
1305      can be a one hour shift depending on the previous contents of the
1306      data area where the data structure is allocated."  */
1307   t.tm_isdst = -1;
1308
1309   /* Note that under foreign locales Solaris strptime() fails to
1310      recognize English dates, which renders this function useless.  I
1311      assume that other non-GNU strptime's are plagued by the same
1312      disease.  We solve this by setting only LC_MESSAGES in
1313      i18n_initialize(), instead of LC_ALL.
1314
1315      Another solution could be to temporarily set locale to C, invoke
1316      strptime(), and restore it back.  This is slow and dirty,
1317      however, and locale support other than LC_MESSAGES can mess other
1318      things, so I rather chose to stick with just setting LC_MESSAGES.
1319
1320      Also note that none of this is necessary under GNU strptime(),
1321      because it recognizes both international and local dates.  */
1322
1323   /* NOTE: We don't use `%n' for white space, as OSF's strptime uses
1324      it to eat all white space up to (and including) a newline, and
1325      the function fails if there is no newline (!).
1326
1327      Let's hope all strptime() implementations use ` ' to skip *all*
1328      whitespace instead of just one (it works that way on all the
1329      systems I've tested it on).  */
1330
1331   /* RFC1123: Thu, 29 Jan 1998 22:12:57 */
1332   if (check_end (strptime (time_string, "%a, %d %b %Y %T", &t)))
1333     return mktime_from_utc (&t);
1334   /* RFC850:  Thu, 29-Jan-98 22:12:57 */
1335   if (check_end (strptime (time_string, "%a, %d-%b-%y %T", &t)))
1336     return mktime_from_utc (&t);
1337   /* asctime: Thu Jan 29 22:12:57 1998 */
1338   if (check_end (strptime (time_string, "%a %b %d %T %Y", &t)))
1339     return mktime_from_utc (&t);
1340   /* Failure.  */
1341   return -1;
1342 }
1343 \f
1344 /* Authorization support: We support two authorization schemes:
1345
1346    * `Basic' scheme, consisting of base64-ing USER:PASSWORD string;
1347
1348    * `Digest' scheme, added by Junio Hamano <junio@twinsun.com>,
1349    consisting of answering to the server's challenge with the proper
1350    MD5 digests.  */
1351
1352 /* How many bytes it will take to store LEN bytes in base64.  */
1353 #define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
1354
1355 /* Encode the string S of length LENGTH to base64 format and place it
1356    to STORE.  STORE will be 0-terminated, and must point to a writable
1357    buffer of at least 1+BASE64_LENGTH(length) bytes.  */
1358 static void
1359 base64_encode (const char *s, char *store, int length)
1360 {
1361   /* Conversion table.  */
1362   static char tbl[64] = {
1363     'A','B','C','D','E','F','G','H',
1364     'I','J','K','L','M','N','O','P',
1365     'Q','R','S','T','U','V','W','X',
1366     'Y','Z','a','b','c','d','e','f',
1367     'g','h','i','j','k','l','m','n',
1368     'o','p','q','r','s','t','u','v',
1369     'w','x','y','z','0','1','2','3',
1370     '4','5','6','7','8','9','+','/'
1371   };
1372   int i;
1373   unsigned char *p = (unsigned char *)store;
1374
1375   /* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
1376   for (i = 0; i < length; i += 3)
1377     {
1378       *p++ = tbl[s[0] >> 2];
1379       *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
1380       *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
1381       *p++ = tbl[s[2] & 0x3f];
1382       s += 3;
1383     }
1384   /* Pad the result if necessary...  */
1385   if (i == length + 1)
1386     *(p - 1) = '=';
1387   else if (i == length + 2)
1388     *(p - 1) = *(p - 2) = '=';
1389   /* ...and zero-terminate it.  */
1390   *p = '\0';
1391 }
1392
1393 /* Create the authentication header contents for the `Basic' scheme.
1394    This is done by encoding the string `USER:PASS' in base64 and
1395    prepending `HEADER: Basic ' to it.  */
1396 static char *
1397 basic_authentication_encode (const char *user, const char *passwd,
1398                              const char *header)
1399 {
1400   char *t1, *t2, *res;
1401   int len1 = strlen (user) + 1 + strlen (passwd);
1402   int len2 = BASE64_LENGTH (len1);
1403
1404   t1 = (char *)alloca (len1 + 1);
1405   sprintf (t1, "%s:%s", user, passwd);
1406   t2 = (char *)alloca (1 + len2);
1407   base64_encode (t1, t2, len1);
1408   res = (char *)malloc (len2 + 11 + strlen (header));
1409   sprintf (res, "%s: Basic %s\r\n", header, t2);
1410
1411   return res;
1412 }
1413
1414 #ifdef USE_DIGEST
1415 /* Parse HTTP `WWW-Authenticate:' header.  AU points to the beginning
1416    of a field in such a header.  If the field is the one specified by
1417    ATTR_NAME ("realm", "opaque", and "nonce" are used by the current
1418    digest authorization code), extract its value in the (char*)
1419    variable pointed by RET.  Returns negative on a malformed header,
1420    or number of bytes that have been parsed by this call.  */
1421 static int
1422 extract_header_attr (const char *au, const char *attr_name, char **ret)
1423 {
1424   const char *cp, *ep;
1425
1426   ep = cp = au;
1427
1428   if (strncmp (cp, attr_name, strlen (attr_name)) == 0)
1429     {
1430       cp += strlen (attr_name);
1431       if (!*cp)
1432         return -1;
1433       cp += skip_lws (cp);
1434       if (*cp != '=')
1435         return -1;
1436       if (!*++cp)
1437         return -1;
1438       cp += skip_lws (cp);
1439       if (*cp != '\"')
1440         return -1;
1441       if (!*++cp)
1442         return -1;
1443       for (ep = cp; *ep && *ep != '\"'; ep++)
1444         ;
1445       if (!*ep)
1446         return -1;
1447       FREE_MAYBE (*ret);
1448       *ret = strdupdelim (cp, ep);
1449       return ep - au + 1;
1450     }
1451   else
1452     return 0;
1453 }
1454
1455 /* Response value needs to be in lowercase, so we cannot use HEXD2ASC
1456    from url.h.  See RFC 2069 2.1.2 for the syntax of response-digest.  */
1457 #define HEXD2asc(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'a'))
1458
1459 /* Dump the hexadecimal representation of HASH to BUF.  HASH should be
1460    an array of 16 bytes containing the hash keys, and BUF should be a
1461    buffer of 33 writable characters (32 for hex digits plus one for
1462    zero termination).  */
1463 static void
1464 dump_hash (unsigned char *buf, const unsigned char *hash)
1465 {
1466   int i;
1467
1468   for (i = 0; i < MD5_HASHLEN; i++, hash++)
1469     {
1470       *buf++ = HEXD2asc (*hash >> 4);
1471       *buf++ = HEXD2asc (*hash & 0xf);
1472     }
1473   *buf = '\0';
1474 }
1475
1476 /* Take the line apart to find the challenge, and compose a digest
1477    authorization header.  See RFC2069 section 2.1.2.  */
1478 char *
1479 digest_authentication_encode (const char *au, const char *user,
1480                               const char *passwd, const char *method,
1481                               const char *path)
1482 {
1483   static char *realm, *opaque, *nonce;
1484   static struct {
1485     const char *name;
1486     char **variable;
1487   } options[] = {
1488     { "realm", &realm },
1489     { "opaque", &opaque },
1490     { "nonce", &nonce }
1491   };
1492   char *res;
1493
1494   realm = opaque = nonce = NULL;
1495
1496   au += 6;                      /* skip over `Digest' */
1497   while (*au)
1498     {
1499       int i;
1500
1501       au += skip_lws (au);
1502       for (i = 0; i < ARRAY_SIZE (options); i++)
1503         {
1504           int skip = extract_header_attr (au, options[i].name,
1505                                           options[i].variable);
1506           if (skip < 0)
1507             {
1508               FREE_MAYBE (realm);
1509               FREE_MAYBE (opaque);
1510               FREE_MAYBE (nonce);
1511               return NULL;
1512             }
1513           else if (skip)
1514             {
1515               au += skip;
1516               break;
1517             }
1518         }
1519       if (i == ARRAY_SIZE (options))
1520         {
1521           while (*au && *au != '=')
1522             au++;
1523           if (*au && *++au)
1524             {
1525               au += skip_lws (au);
1526               if (*au == '\"')
1527                 {
1528                   au++;
1529                   while (*au && *au != '\"')
1530                     au++;
1531                   if (*au)
1532                     au++;
1533                 }
1534             }
1535         }
1536       while (*au && *au != ',')
1537         au++;
1538       if (*au)
1539         au++;
1540     }
1541   if (!realm || !nonce || !user || !passwd || !path || !method)
1542     {
1543       FREE_MAYBE (realm);
1544       FREE_MAYBE (opaque);
1545       FREE_MAYBE (nonce);
1546       return NULL;
1547     }
1548
1549   /* Calculate the digest value.  */
1550   {
1551     struct md5_ctx ctx;
1552     unsigned char hash[MD5_HASHLEN];
1553     unsigned char a1buf[MD5_HASHLEN * 2 + 1], a2buf[MD5_HASHLEN * 2 + 1];
1554     unsigned char response_digest[MD5_HASHLEN * 2 + 1];
1555
1556     /* A1BUF = H(user ":" realm ":" password) */
1557     md5_init_ctx (&ctx);
1558     md5_process_bytes (user, strlen (user), &ctx);
1559     md5_process_bytes (":", 1, &ctx);
1560     md5_process_bytes (realm, strlen (realm), &ctx);
1561     md5_process_bytes (":", 1, &ctx);
1562     md5_process_bytes (passwd, strlen (passwd), &ctx);
1563     md5_finish_ctx (&ctx, hash);
1564     dump_hash (a1buf, hash);
1565
1566     /* A2BUF = H(method ":" path) */
1567     md5_init_ctx (&ctx);
1568     md5_process_bytes (method, strlen (method), &ctx);
1569     md5_process_bytes (":", 1, &ctx);
1570     md5_process_bytes (path, strlen (path), &ctx);
1571     md5_finish_ctx (&ctx, hash);
1572     dump_hash (a2buf, hash);
1573
1574     /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */
1575     md5_init_ctx (&ctx);
1576     md5_process_bytes (a1buf, MD5_HASHLEN * 2, &ctx);
1577     md5_process_bytes (":", 1, &ctx);
1578     md5_process_bytes (nonce, strlen (nonce), &ctx);
1579     md5_process_bytes (":", 1, &ctx);
1580     md5_process_bytes (a2buf, MD5_HASHLEN * 2, &ctx);
1581     md5_finish_ctx (&ctx, hash);
1582     dump_hash (response_digest, hash);
1583
1584     res = (char*) xmalloc (strlen (user)
1585                            + strlen (user)
1586                            + strlen (realm)
1587                            + strlen (nonce)
1588                            + strlen (path)
1589                            + 2 * MD5_HASHLEN /*strlen (response_digest)*/
1590                            + (opaque ? strlen (opaque) : 0)
1591                            + 128);
1592     sprintf (res, "Authorization: Digest \
1593 username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
1594              user, realm, nonce, path, response_digest);
1595     if (opaque)
1596       {
1597         char *p = res + strlen (res);
1598         strcat (p, ", opaque=\"");
1599         strcat (p, opaque);
1600         strcat (p, "\"");
1601       }
1602     strcat (res, "\r\n");
1603   }
1604   return res;
1605 }
1606 #endif /* USE_DIGEST */
1607
1608
1609 #define HACK_O_MATIC(line, string_constant)                             \
1610   (!strncasecmp (line, string_constant, sizeof (string_constant) - 1)   \
1611    && (ISSPACE (line[sizeof (string_constant) - 1])                     \
1612        || !line[sizeof (string_constant) - 1]))
1613
1614 static int
1615 known_authentication_scheme_p (const char *au)
1616 {
1617   return HACK_O_MATIC (au, "Basic") || HACK_O_MATIC (au, "Digest");
1618 }
1619
1620 #undef HACK_O_MATIC
1621
1622 /* Create the HTTP authorization request header.  When the
1623    `WWW-Authenticate' response header is seen, according to the
1624    authorization scheme specified in that header (`Basic' and `Digest'
1625    are supported by the current implementation), produce an
1626    appropriate HTTP authorization request header.  */
1627 static char *
1628 create_authorization_line (const char *au, const char *user,
1629                            const char *passwd, const char *method,
1630                            const char *path)
1631 {
1632   char *wwwauth = NULL;
1633
1634   if (!strncasecmp (au, "Basic", 5))
1635     wwwauth = basic_authentication_encode (user, passwd, "Authorization");
1636 #ifdef USE_DIGEST
1637   else if (!strncasecmp (au, "Digest", 6))
1638     wwwauth = digest_authentication_encode (au, user, passwd, method, path);
1639 #endif /* USE_DIGEST */
1640   return wwwauth;
1641 }