]> sjero.net Git - wget/blob - src/http.c
If --content-disposition is used, do not send a HEAD request.
[wget] / src / http.c
1 /* HTTP support.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3    2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4
5 This file is part of GNU Wget.
6
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a
24 modified version of that library), containing parts covered by the
25 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26 grants you additional permission to convey the resulting work.
27 Corresponding Source for a non-source form of such a combination
28 shall include the source code for the parts of OpenSSL used as well
29 as that of the covered work.  */
30
31 #include "wget.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #ifdef HAVE_UNISTD_H
37 # include <unistd.h>
38 #endif
39 #include <assert.h>
40 #include <errno.h>
41 #include <time.h>
42 #include <locale.h>
43
44 #include "hash.h"
45 #include "http.h"
46 #include "utils.h"
47 #include "url.h"
48 #include "host.h"
49 #include "retr.h"
50 #include "connect.h"
51 #include "netrc.h"
52 #ifdef HAVE_SSL
53 # include "ssl.h"
54 #endif
55 #ifdef ENABLE_NTLM
56 # include "http-ntlm.h"
57 #endif
58 #include "cookies.h"
59 #include "md5.h"
60 #include "convert.h"
61 #include "spider.h"
62
63 #ifdef TESTING
64 #include "test.h"
65 #endif
66
67 #ifdef __VMS
68 # include "vms.h"
69 #endif /* def __VMS */
70
71 extern char *version_string;
72
73 /* Forward decls. */
74 struct http_stat;
75 static char *create_authorization_line (const char *, const char *,
76                                         const char *, const char *,
77                                         const char *, bool *);
78 static char *basic_authentication_encode (const char *, const char *);
79 static bool known_authentication_scheme_p (const char *, const char *);
80 static void ensure_extension (struct http_stat *, const char *, int *);
81 static void load_cookies (void);
82
83 #ifndef MIN
84 # define MIN(x, y) ((x) > (y) ? (y) : (x))
85 #endif
86
87 \f
88 static bool cookies_loaded_p;
89 static struct cookie_jar *wget_cookie_jar;
90
91 #define TEXTHTML_S "text/html"
92 #define TEXTXHTML_S "application/xhtml+xml"
93 #define TEXTCSS_S "text/css"
94
95 /* Some status code validation macros: */
96 #define H_10X(x)        (((x) >= 100) && ((x) < 200))
97 #define H_20X(x)        (((x) >= 200) && ((x) < 300))
98 #define H_PARTIAL(x)    ((x) == HTTP_STATUS_PARTIAL_CONTENTS)
99 #define H_REDIRECTED(x) ((x) == HTTP_STATUS_MOVED_PERMANENTLY          \
100                          || (x) == HTTP_STATUS_MOVED_TEMPORARILY       \
101                          || (x) == HTTP_STATUS_SEE_OTHER               \
102                          || (x) == HTTP_STATUS_TEMPORARY_REDIRECT)
103
104 /* HTTP/1.0 status codes from RFC1945, provided for reference.  */
105 /* Successful 2xx.  */
106 #define HTTP_STATUS_OK                    200
107 #define HTTP_STATUS_CREATED               201
108 #define HTTP_STATUS_ACCEPTED              202
109 #define HTTP_STATUS_NO_CONTENT            204
110 #define HTTP_STATUS_PARTIAL_CONTENTS      206
111
112 /* Redirection 3xx.  */
113 #define HTTP_STATUS_MULTIPLE_CHOICES      300
114 #define HTTP_STATUS_MOVED_PERMANENTLY     301
115 #define HTTP_STATUS_MOVED_TEMPORARILY     302
116 #define HTTP_STATUS_SEE_OTHER             303 /* from HTTP/1.1 */
117 #define HTTP_STATUS_NOT_MODIFIED          304
118 #define HTTP_STATUS_TEMPORARY_REDIRECT    307 /* from HTTP/1.1 */
119
120 /* Client error 4xx.  */
121 #define HTTP_STATUS_BAD_REQUEST           400
122 #define HTTP_STATUS_UNAUTHORIZED          401
123 #define HTTP_STATUS_FORBIDDEN             403
124 #define HTTP_STATUS_NOT_FOUND             404
125 #define HTTP_STATUS_RANGE_NOT_SATISFIABLE 416
126
127 /* Server errors 5xx.  */
128 #define HTTP_STATUS_INTERNAL              500
129 #define HTTP_STATUS_NOT_IMPLEMENTED       501
130 #define HTTP_STATUS_BAD_GATEWAY           502
131 #define HTTP_STATUS_UNAVAILABLE           503
132 \f
133 enum rp {
134   rel_none, rel_name, rel_value, rel_both
135 };
136
137 struct request {
138   const char *method;
139   char *arg;
140
141   struct request_header {
142     char *name, *value;
143     enum rp release_policy;
144   } *headers;
145   int hcount, hcapacity;
146 };
147
148 extern int numurls;
149
150 /* Create a new, empty request.  At least request_set_method must be
151    called before the request can be used.  */
152
153 static struct request *
154 request_new (void)
155 {
156   struct request *req = xnew0 (struct request);
157   req->hcapacity = 8;
158   req->headers = xnew_array (struct request_header, req->hcapacity);
159   return req;
160 }
161
162 /* Set the request's method and its arguments.  METH should be a
163    literal string (or it should outlive the request) because it will
164    not be freed.  ARG will be freed by request_free.  */
165
166 static void
167 request_set_method (struct request *req, const char *meth, char *arg)
168 {
169   req->method = meth;
170   req->arg = arg;
171 }
172
173 /* Return the method string passed with the last call to
174    request_set_method.  */
175
176 static const char *
177 request_method (const struct request *req)
178 {
179   return req->method;
180 }
181
182 /* Free one header according to the release policy specified with
183    request_set_header.  */
184
185 static void
186 release_header (struct request_header *hdr)
187 {
188   switch (hdr->release_policy)
189     {
190     case rel_none:
191       break;
192     case rel_name:
193       xfree (hdr->name);
194       break;
195     case rel_value:
196       xfree (hdr->value);
197       break;
198     case rel_both:
199       xfree (hdr->name);
200       xfree (hdr->value);
201       break;
202     }
203 }
204
205 /* Set the request named NAME to VALUE.  Specifically, this means that
206    a "NAME: VALUE\r\n" header line will be used in the request.  If a
207    header with the same name previously existed in the request, its
208    value will be replaced by this one.  A NULL value means do nothing.
209
210    RELEASE_POLICY determines whether NAME and VALUE should be released
211    (freed) with request_free.  Allowed values are:
212
213     - rel_none     - don't free NAME or VALUE
214     - rel_name     - free NAME when done
215     - rel_value    - free VALUE when done
216     - rel_both     - free both NAME and VALUE when done
217
218    Setting release policy is useful when arguments come from different
219    sources.  For example:
220
221      // Don't free literal strings!
222      request_set_header (req, "Pragma", "no-cache", rel_none);
223
224      // Don't free a global variable, we'll need it later.
225      request_set_header (req, "Referer", opt.referer, rel_none);
226
227      // Value freshly allocated, free it when done.
228      request_set_header (req, "Range",
229                          aprintf ("bytes=%s-", number_to_static_string (hs->restval)),
230                          rel_value);
231    */
232
233 static void
234 request_set_header (struct request *req, char *name, char *value,
235                     enum rp release_policy)
236 {
237   struct request_header *hdr;
238   int i;
239
240   if (!value)
241     {
242       /* A NULL value is a no-op; if freeing the name is requested,
243          free it now to avoid leaks.  */
244       if (release_policy == rel_name || release_policy == rel_both)
245         xfree (name);
246       return;
247     }
248
249   for (i = 0; i < req->hcount; i++)
250     {
251       hdr = &req->headers[i];
252       if (0 == strcasecmp (name, hdr->name))
253         {
254           /* Replace existing header. */
255           release_header (hdr);
256           hdr->name = name;
257           hdr->value = value;
258           hdr->release_policy = release_policy;
259           return;
260         }
261     }
262
263   /* Install new header. */
264
265   if (req->hcount >= req->hcapacity)
266     {
267       req->hcapacity <<= 1;
268       req->headers = xrealloc (req->headers, req->hcapacity * sizeof (*hdr));
269     }
270   hdr = &req->headers[req->hcount++];
271   hdr->name = name;
272   hdr->value = value;
273   hdr->release_policy = release_policy;
274 }
275
276 /* Like request_set_header, but sets the whole header line, as
277    provided by the user using the `--header' option.  For example,
278    request_set_user_header (req, "Foo: bar") works just like
279    request_set_header (req, "Foo", "bar").  */
280
281 static void
282 request_set_user_header (struct request *req, const char *header)
283 {
284   char *name;
285   const char *p = strchr (header, ':');
286   if (!p)
287     return;
288   BOUNDED_TO_ALLOCA (header, p, name);
289   ++p;
290   while (c_isspace (*p))
291     ++p;
292   request_set_header (req, xstrdup (name), (char *) p, rel_name);
293 }
294
295 /* Remove the header with specified name from REQ.  Returns true if
296    the header was actually removed, false otherwise.  */
297
298 static bool
299 request_remove_header (struct request *req, char *name)
300 {
301   int i;
302   for (i = 0; i < req->hcount; i++)
303     {
304       struct request_header *hdr = &req->headers[i];
305       if (0 == strcasecmp (name, hdr->name))
306         {
307           release_header (hdr);
308           /* Move the remaining headers by one. */
309           if (i < req->hcount - 1)
310             memmove (hdr, hdr + 1, (req->hcount - i - 1) * sizeof (*hdr));
311           --req->hcount;
312           return true;
313         }
314     }
315   return false;
316 }
317
318 #define APPEND(p, str) do {                     \
319   int A_len = strlen (str);                     \
320   memcpy (p, str, A_len);                       \
321   p += A_len;                                   \
322 } while (0)
323
324 /* Construct the request and write it to FD using fd_write.  */
325
326 static int
327 request_send (const struct request *req, int fd)
328 {
329   char *request_string, *p;
330   int i, size, write_error;
331
332   /* Count the request size. */
333   size = 0;
334
335   /* METHOD " " ARG " " "HTTP/1.0" "\r\n" */
336   size += strlen (req->method) + 1 + strlen (req->arg) + 1 + 8 + 2;
337
338   for (i = 0; i < req->hcount; i++)
339     {
340       struct request_header *hdr = &req->headers[i];
341       /* NAME ": " VALUE "\r\n" */
342       size += strlen (hdr->name) + 2 + strlen (hdr->value) + 2;
343     }
344
345   /* "\r\n\0" */
346   size += 3;
347
348   p = request_string = alloca_array (char, size);
349
350   /* Generate the request. */
351
352   APPEND (p, req->method); *p++ = ' ';
353   APPEND (p, req->arg);    *p++ = ' ';
354   memcpy (p, "HTTP/1.1\r\n", 10); p += 10;
355
356   for (i = 0; i < req->hcount; i++)
357     {
358       struct request_header *hdr = &req->headers[i];
359       APPEND (p, hdr->name);
360       *p++ = ':', *p++ = ' ';
361       APPEND (p, hdr->value);
362       *p++ = '\r', *p++ = '\n';
363     }
364
365   *p++ = '\r', *p++ = '\n', *p++ = '\0';
366   assert (p - request_string == size);
367
368 #undef APPEND
369
370   DEBUGP (("\n---request begin---\n%s---request end---\n", request_string));
371
372   /* Send the request to the server. */
373
374   write_error = fd_write (fd, request_string, size - 1, -1);
375   if (write_error < 0)
376     logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
377                fd_errstr (fd));
378   return write_error;
379 }
380
381 /* Release the resources used by REQ. */
382
383 static void
384 request_free (struct request *req)
385 {
386   int i;
387   xfree_null (req->arg);
388   for (i = 0; i < req->hcount; i++)
389     release_header (&req->headers[i]);
390   xfree_null (req->headers);
391   xfree (req);
392 }
393
394 static struct hash_table *basic_authed_hosts;
395
396 /* Find out if this host has issued a Basic challenge yet; if so, give
397  * it the username, password. A temporary measure until we can get
398  * proper authentication in place. */
399
400 static bool
401 maybe_send_basic_creds (const char *hostname, const char *user,
402                         const char *passwd, struct request *req)
403 {
404   bool do_challenge = false;
405
406   if (opt.auth_without_challenge)
407     {
408       DEBUGP (("Auth-without-challenge set, sending Basic credentials.\n"));
409       do_challenge = true;
410     }
411   else if (basic_authed_hosts
412       && hash_table_contains(basic_authed_hosts, hostname))
413     {
414       DEBUGP (("Found %s in basic_authed_hosts.\n", quote (hostname)));
415       do_challenge = true;
416     }
417   else
418     {
419       DEBUGP (("Host %s has not issued a general basic challenge.\n",
420               quote (hostname)));
421     }
422   if (do_challenge)
423     {
424       request_set_header (req, "Authorization",
425                           basic_authentication_encode (user, passwd),
426                           rel_value);
427     }
428   return do_challenge;
429 }
430
431 static void
432 register_basic_auth_host (const char *hostname)
433 {
434   if (!basic_authed_hosts)
435     {
436       basic_authed_hosts = make_nocase_string_hash_table (1);
437     }
438   if (!hash_table_contains(basic_authed_hosts, hostname))
439     {
440       hash_table_put (basic_authed_hosts, xstrdup(hostname), NULL);
441       DEBUGP (("Inserted %s into basic_authed_hosts\n", quote (hostname)));
442     }
443 }
444
445
446 /* Send the contents of FILE_NAME to SOCK.  Make sure that exactly
447    PROMISED_SIZE bytes are sent over the wire -- if the file is
448    longer, read only that much; if the file is shorter, report an error.  */
449
450 static int
451 post_file (int sock, const char *file_name, wgint promised_size)
452 {
453   static char chunk[8192];
454   wgint written = 0;
455   int write_error;
456   FILE *fp;
457
458   DEBUGP (("[writing POST file %s ... ", file_name));
459
460   fp = fopen (file_name, "rb");
461   if (!fp)
462     return -1;
463   while (!feof (fp) && written < promised_size)
464     {
465       int towrite;
466       int length = fread (chunk, 1, sizeof (chunk), fp);
467       if (length == 0)
468         break;
469       towrite = MIN (promised_size - written, length);
470       write_error = fd_write (sock, chunk, towrite, -1);
471       if (write_error < 0)
472         {
473           fclose (fp);
474           return -1;
475         }
476       written += towrite;
477     }
478   fclose (fp);
479
480   /* If we've written less than was promised, report a (probably
481      nonsensical) error rather than break the promise.  */
482   if (written < promised_size)
483     {
484       errno = EINVAL;
485       return -1;
486     }
487
488   assert (written == promised_size);
489   DEBUGP (("done]\n"));
490   return 0;
491 }
492 \f
493 /* Determine whether [START, PEEKED + PEEKLEN) contains an empty line.
494    If so, return the pointer to the position after the line, otherwise
495    return NULL.  This is used as callback to fd_read_hunk.  The data
496    between START and PEEKED has been read and cannot be "unread"; the
497    data after PEEKED has only been peeked.  */
498
499 static const char *
500 response_head_terminator (const char *start, const char *peeked, int peeklen)
501 {
502   const char *p, *end;
503
504   /* If at first peek, verify whether HUNK starts with "HTTP".  If
505      not, this is a HTTP/0.9 request and we must bail out without
506      reading anything.  */
507   if (start == peeked && 0 != memcmp (start, "HTTP", MIN (peeklen, 4)))
508     return start;
509
510   /* Look for "\n[\r]\n", and return the following position if found.
511      Start two chars before the current to cover the possibility that
512      part of the terminator (e.g. "\n\r") arrived in the previous
513      batch.  */
514   p = peeked - start < 2 ? start : peeked - 2;
515   end = peeked + peeklen;
516
517   /* Check for \n\r\n or \n\n anywhere in [p, end-2). */
518   for (; p < end - 2; p++)
519     if (*p == '\n')
520       {
521         if (p[1] == '\r' && p[2] == '\n')
522           return p + 3;
523         else if (p[1] == '\n')
524           return p + 2;
525       }
526   /* p==end-2: check for \n\n directly preceding END. */
527   if (p[0] == '\n' && p[1] == '\n')
528     return p + 2;
529
530   return NULL;
531 }
532
533 /* The maximum size of a single HTTP response we care to read.  Rather
534    than being a limit of the reader implementation, this limit
535    prevents Wget from slurping all available memory upon encountering
536    malicious or buggy server output, thus protecting the user.  Define
537    it to 0 to remove the limit.  */
538
539 #define HTTP_RESPONSE_MAX_SIZE 65536
540
541 /* Read the HTTP request head from FD and return it.  The error
542    conditions are the same as with fd_read_hunk.
543
544    To support HTTP/0.9 responses, this function tries to make sure
545    that the data begins with "HTTP".  If this is not the case, no data
546    is read and an empty request is returned, so that the remaining
547    data can be treated as body.  */
548
549 static char *
550 read_http_response_head (int fd)
551 {
552   return fd_read_hunk (fd, response_head_terminator, 512,
553                        HTTP_RESPONSE_MAX_SIZE);
554 }
555
556 struct response {
557   /* The response data. */
558   const char *data;
559
560   /* The array of pointers that indicate where each header starts.
561      For example, given this HTTP response:
562
563        HTTP/1.0 200 Ok
564        Description: some
565         text
566        Etag: x
567
568      The headers are located like this:
569
570      "HTTP/1.0 200 Ok\r\nDescription: some\r\n text\r\nEtag: x\r\n\r\n"
571      ^                   ^                             ^          ^
572      headers[0]          headers[1]                    headers[2] headers[3]
573
574      I.e. headers[0] points to the beginning of the request,
575      headers[1] points to the end of the first header and the
576      beginning of the second one, etc.  */
577
578   const char **headers;
579 };
580
581 /* Create a new response object from the text of the HTTP response,
582    available in HEAD.  That text is automatically split into
583    constituent header lines for fast retrieval using
584    resp_header_*.  */
585
586 static struct response *
587 resp_new (const char *head)
588 {
589   const char *hdr;
590   int count, size;
591
592   struct response *resp = xnew0 (struct response);
593   resp->data = head;
594
595   if (*head == '\0')
596     {
597       /* Empty head means that we're dealing with a headerless
598          (HTTP/0.9) response.  In that case, don't set HEADERS at
599          all.  */
600       return resp;
601     }
602
603   /* Split HEAD into header lines, so that resp_header_* functions
604      don't need to do this over and over again.  */
605
606   size = count = 0;
607   hdr = head;
608   while (1)
609     {
610       DO_REALLOC (resp->headers, size, count + 1, const char *);
611       resp->headers[count++] = hdr;
612
613       /* Break upon encountering an empty line. */
614       if (!hdr[0] || (hdr[0] == '\r' && hdr[1] == '\n') || hdr[0] == '\n')
615         break;
616
617       /* Find the end of HDR, including continuations. */
618       do
619         {
620           const char *end = strchr (hdr, '\n');
621           if (end)
622             hdr = end + 1;
623           else
624             hdr += strlen (hdr);
625         }
626       while (*hdr == ' ' || *hdr == '\t');
627     }
628   DO_REALLOC (resp->headers, size, count + 1, const char *);
629   resp->headers[count] = NULL;
630
631   return resp;
632 }
633
634 /* Locate the header named NAME in the request data, starting with
635    position START.  This allows the code to loop through the request
636    data, filtering for all requests of a given name.  Returns the
637    found position, or -1 for failure.  The code that uses this
638    function typically looks like this:
639
640      for (pos = 0; (pos = resp_header_locate (...)) != -1; pos++)
641        ... do something with header ...
642
643    If you only care about one header, use resp_header_get instead of
644    this function.  */
645
646 static int
647 resp_header_locate (const struct response *resp, const char *name, int start,
648                     const char **begptr, const char **endptr)
649 {
650   int i;
651   const char **headers = resp->headers;
652   int name_len;
653
654   if (!headers || !headers[1])
655     return -1;
656
657   name_len = strlen (name);
658   if (start > 0)
659     i = start;
660   else
661     i = 1;
662
663   for (; headers[i + 1]; i++)
664     {
665       const char *b = headers[i];
666       const char *e = headers[i + 1];
667       if (e - b > name_len
668           && b[name_len] == ':'
669           && 0 == strncasecmp (b, name, name_len))
670         {
671           b += name_len + 1;
672           while (b < e && c_isspace (*b))
673             ++b;
674           while (b < e && c_isspace (e[-1]))
675             --e;
676           *begptr = b;
677           *endptr = e;
678           return i;
679         }
680     }
681   return -1;
682 }
683
684 /* Find and retrieve the header named NAME in the request data.  If
685    found, set *BEGPTR to its starting, and *ENDPTR to its ending
686    position, and return true.  Otherwise return false.
687
688    This function is used as a building block for resp_header_copy
689    and resp_header_strdup.  */
690
691 static bool
692 resp_header_get (const struct response *resp, const char *name,
693                  const char **begptr, const char **endptr)
694 {
695   int pos = resp_header_locate (resp, name, 0, begptr, endptr);
696   return pos != -1;
697 }
698
699 /* Copy the response header named NAME to buffer BUF, no longer than
700    BUFSIZE (BUFSIZE includes the terminating 0).  If the header
701    exists, true is returned, false otherwise.  If there should be no
702    limit on the size of the header, use resp_header_strdup instead.
703
704    If BUFSIZE is 0, no data is copied, but the boolean indication of
705    whether the header is present is still returned.  */
706
707 static bool
708 resp_header_copy (const struct response *resp, const char *name,
709                   char *buf, int bufsize)
710 {
711   const char *b, *e;
712   if (!resp_header_get (resp, name, &b, &e))
713     return false;
714   if (bufsize)
715     {
716       int len = MIN (e - b, bufsize - 1);
717       memcpy (buf, b, len);
718       buf[len] = '\0';
719     }
720   return true;
721 }
722
723 /* Return the value of header named NAME in RESP, allocated with
724    malloc.  If such a header does not exist in RESP, return NULL.  */
725
726 static char *
727 resp_header_strdup (const struct response *resp, const char *name)
728 {
729   const char *b, *e;
730   if (!resp_header_get (resp, name, &b, &e))
731     return NULL;
732   return strdupdelim (b, e);
733 }
734
735 /* Parse the HTTP status line, which is of format:
736
737    HTTP-Version SP Status-Code SP Reason-Phrase
738
739    The function returns the status-code, or -1 if the status line
740    appears malformed.  The pointer to "reason-phrase" message is
741    returned in *MESSAGE.  */
742
743 static int
744 resp_status (const struct response *resp, char **message)
745 {
746   int status;
747   const char *p, *end;
748
749   if (!resp->headers)
750     {
751       /* For a HTTP/0.9 response, assume status 200. */
752       if (message)
753         *message = xstrdup (_("No headers, assuming HTTP/0.9"));
754       return 200;
755     }
756
757   p = resp->headers[0];
758   end = resp->headers[1];
759
760   if (!end)
761     return -1;
762
763   /* "HTTP" */
764   if (end - p < 4 || 0 != strncmp (p, "HTTP", 4))
765     return -1;
766   p += 4;
767
768   /* Match the HTTP version.  This is optional because Gnutella
769      servers have been reported to not specify HTTP version.  */
770   if (p < end && *p == '/')
771     {
772       ++p;
773       while (p < end && c_isdigit (*p))
774         ++p;
775       if (p < end && *p == '.')
776         ++p;
777       while (p < end && c_isdigit (*p))
778         ++p;
779     }
780
781   while (p < end && c_isspace (*p))
782     ++p;
783   if (end - p < 3 || !c_isdigit (p[0]) || !c_isdigit (p[1]) || !c_isdigit (p[2]))
784     return -1;
785
786   status = 100 * (p[0] - '0') + 10 * (p[1] - '0') + (p[2] - '0');
787   p += 3;
788
789   if (message)
790     {
791       while (p < end && c_isspace (*p))
792         ++p;
793       while (p < end && c_isspace (end[-1]))
794         --end;
795       *message = strdupdelim (p, end);
796     }
797
798   return status;
799 }
800
801 /* Release the resources used by RESP.  */
802
803 static void
804 resp_free (struct response *resp)
805 {
806   xfree_null (resp->headers);
807   xfree (resp);
808 }
809
810 /* Print a single line of response, the characters [b, e).  We tried
811    getting away with
812       logprintf (LOG_VERBOSE, "%s%.*s\n", prefix, (int) (e - b), b);
813    but that failed to escape the non-printable characters and, in fact,
814    caused crashes in UTF-8 locales.  */
815
816 static void
817 print_response_line(const char *prefix, const char *b, const char *e)
818 {
819   char *copy;
820   BOUNDED_TO_ALLOCA(b, e, copy);
821   logprintf (LOG_ALWAYS, "%s%s\n", prefix,
822              quotearg_style (escape_quoting_style, copy));
823 }
824
825 /* Print the server response, line by line, omitting the trailing CRLF
826    from individual header lines, and prefixed with PREFIX.  */
827
828 static void
829 print_server_response (const struct response *resp, const char *prefix)
830 {
831   int i;
832   if (!resp->headers)
833     return;
834   for (i = 0; resp->headers[i + 1]; i++)
835     {
836       const char *b = resp->headers[i];
837       const char *e = resp->headers[i + 1];
838       /* Skip CRLF */
839       if (b < e && e[-1] == '\n')
840         --e;
841       if (b < e && e[-1] == '\r')
842         --e;
843       print_response_line(prefix, b, e);
844     }
845 }
846
847 /* Parse the `Content-Range' header and extract the information it
848    contains.  Returns true if successful, false otherwise.  */
849 static bool
850 parse_content_range (const char *hdr, wgint *first_byte_ptr,
851                      wgint *last_byte_ptr, wgint *entity_length_ptr)
852 {
853   wgint num;
854
855   /* Ancient versions of Netscape proxy server, presumably predating
856      rfc2068, sent out `Content-Range' without the "bytes"
857      specifier.  */
858   if (0 == strncasecmp (hdr, "bytes", 5))
859     {
860       hdr += 5;
861       /* "JavaWebServer/1.1.1" sends "bytes: x-y/z", contrary to the
862          HTTP spec. */
863       if (*hdr == ':')
864         ++hdr;
865       while (c_isspace (*hdr))
866         ++hdr;
867       if (!*hdr)
868         return false;
869     }
870   if (!c_isdigit (*hdr))
871     return false;
872   for (num = 0; c_isdigit (*hdr); hdr++)
873     num = 10 * num + (*hdr - '0');
874   if (*hdr != '-' || !c_isdigit (*(hdr + 1)))
875     return false;
876   *first_byte_ptr = num;
877   ++hdr;
878   for (num = 0; c_isdigit (*hdr); hdr++)
879     num = 10 * num + (*hdr - '0');
880   if (*hdr != '/' || !c_isdigit (*(hdr + 1)))
881     return false;
882   *last_byte_ptr = num;
883   ++hdr;
884   if (*hdr == '*')
885     num = -1;
886   else
887     for (num = 0; c_isdigit (*hdr); hdr++)
888       num = 10 * num + (*hdr - '0');
889   *entity_length_ptr = num;
890   return true;
891 }
892
893 /* Read the body of the request, but don't store it anywhere and don't
894    display a progress gauge.  This is useful for reading the bodies of
895    administrative responses to which we will soon issue another
896    request.  The response is not useful to the user, but reading it
897    allows us to continue using the same connection to the server.
898
899    If reading fails, false is returned, true otherwise.  In debug
900    mode, the body is displayed for debugging purposes.  */
901
902 static bool
903 skip_short_body (int fd, wgint contlen, bool chunked)
904 {
905   enum {
906     SKIP_SIZE = 512,                /* size of the download buffer */
907     SKIP_THRESHOLD = 4096        /* the largest size we read */
908   };
909   wgint remaining_chunk_size = 0;
910   char dlbuf[SKIP_SIZE + 1];
911   dlbuf[SKIP_SIZE] = '\0';        /* so DEBUGP can safely print it */
912
913   assert (contlen != -1 || contlen);
914
915   /* If the body is too large, it makes more sense to simply close the
916      connection than to try to read the body.  */
917   if (contlen > SKIP_THRESHOLD)
918     return false;
919
920   while (contlen > 0 || chunked)
921     {
922       int ret;
923       if (chunked)
924         {
925           if (remaining_chunk_size == 0)
926             {
927               char *line = fd_read_line (fd);
928               char *endl;
929               if (line == NULL)
930                 {
931                   ret = -1;
932                   break;
933                 }
934
935               remaining_chunk_size = strtol (line, &endl, 16);
936               if (remaining_chunk_size == 0)
937                 {
938                   ret = 0;
939                   if (fd_read_line (fd) == NULL)
940                     ret = -1;
941                   break;
942                 }
943             }
944
945           contlen = MIN (remaining_chunk_size, SKIP_SIZE);
946         }
947
948       DEBUGP (("Skipping %s bytes of body: [", number_to_static_string (contlen)));
949
950       ret = fd_read (fd, dlbuf, MIN (contlen, SKIP_SIZE), -1);
951       if (ret <= 0)
952         {
953           /* Don't normally report the error since this is an
954              optimization that should be invisible to the user.  */
955           DEBUGP (("] aborting (%s).\n",
956                    ret < 0 ? fd_errstr (fd) : "EOF received"));
957           return false;
958         }
959       contlen -= ret;
960
961       if (chunked)
962         {
963           remaining_chunk_size -= ret;
964           if (remaining_chunk_size == 0)
965             if (fd_read_line (fd) == NULL)
966               return false;
967         }
968
969       /* Safe even if %.*s bogusly expects terminating \0 because
970          we've zero-terminated dlbuf above.  */
971       DEBUGP (("%.*s", ret, dlbuf));
972     }
973
974   DEBUGP (("] done.\n"));
975   return true;
976 }
977
978 #define NOT_RFC2231 0
979 #define RFC2231_NOENCODING 1
980 #define RFC2231_ENCODING 2
981
982 /* extract_param extracts the parameter name into NAME.
983    However, if the parameter name is in RFC2231 format then
984    this function adjusts NAME by stripping of the trailing
985    characters that are not part of the name but are present to
986    indicate the presence of encoding information in the value
987    or a fragment of a long parameter value
988 */
989 static int
990 modify_param_name(param_token *name)
991 {
992   const char *delim1 = memchr (name->b, '*', name->e - name->b);
993   const char *delim2 = memrchr (name->b, '*', name->e - name->b);
994
995   int result;
996
997   if(delim1 == NULL)
998     {
999       result = NOT_RFC2231;
1000     }
1001   else if(delim1 == delim2)
1002     {
1003       if ((name->e - 1) == delim1)
1004         {
1005           result = RFC2231_ENCODING;
1006         }
1007       else
1008         {
1009           result = RFC2231_NOENCODING;
1010         }
1011       name->e = delim1;
1012     }
1013   else
1014     {
1015       name->e = delim1;
1016       result = RFC2231_ENCODING;
1017     }
1018   return result;
1019 }
1020
1021 /* extract_param extract the paramater value into VALUE.
1022    Like modify_param_name this function modifies VALUE by
1023    stripping off the encoding information from the actual value
1024 */
1025 static void
1026 modify_param_value (param_token *value, int encoding_type )
1027 {
1028   if (RFC2231_ENCODING == encoding_type)
1029     {
1030       const char *delim = memrchr (value->b, '\'', value->e - value->b);
1031       if ( delim != NULL )
1032         {
1033           value->b = (delim+1);
1034         }
1035     }
1036 }
1037
1038 /* Extract a parameter from the string (typically an HTTP header) at
1039    **SOURCE and advance SOURCE to the next parameter.  Return false
1040    when there are no more parameters to extract.  The name of the
1041    parameter is returned in NAME, and the value in VALUE.  If the
1042    parameter has no value, the token's value is zeroed out.
1043
1044    For example, if *SOURCE points to the string "attachment;
1045    filename=\"foo bar\"", the first call to this function will return
1046    the token named "attachment" and no value, and the second call will
1047    return the token named "filename" and value "foo bar".  The third
1048    call will return false, indicating no more valid tokens.  */
1049
1050 bool
1051 extract_param (const char **source, param_token *name, param_token *value,
1052                char separator)
1053 {
1054   const char *p = *source;
1055
1056   while (c_isspace (*p)) ++p;
1057   if (!*p)
1058     {
1059       *source = p;
1060       return false;             /* no error; nothing more to extract */
1061     }
1062
1063   /* Extract name. */
1064   name->b = p;
1065   while (*p && !c_isspace (*p) && *p != '=' && *p != separator) ++p;
1066   name->e = p;
1067   if (name->b == name->e)
1068     return false;               /* empty name: error */
1069   while (c_isspace (*p)) ++p;
1070   if (*p == separator || !*p)           /* no value */
1071     {
1072       xzero (*value);
1073       if (*p == separator) ++p;
1074       *source = p;
1075       return true;
1076     }
1077   if (*p != '=')
1078     return false;               /* error */
1079
1080   /* *p is '=', extract value */
1081   ++p;
1082   while (c_isspace (*p)) ++p;
1083   if (*p == '"')                /* quoted */
1084     {
1085       value->b = ++p;
1086       while (*p && *p != '"') ++p;
1087       if (!*p)
1088         return false;
1089       value->e = p++;
1090       /* Currently at closing quote; find the end of param. */
1091       while (c_isspace (*p)) ++p;
1092       while (*p && *p != separator) ++p;
1093       if (*p == separator)
1094         ++p;
1095       else if (*p)
1096         /* garbage after closed quote, e.g. foo="bar"baz */
1097         return false;
1098     }
1099   else                          /* unquoted */
1100     {
1101       value->b = p;
1102       while (*p && *p != separator) ++p;
1103       value->e = p;
1104       while (value->e != value->b && c_isspace (value->e[-1]))
1105         --value->e;
1106       if (*p == separator) ++p;
1107     }
1108   *source = p;
1109
1110   int param_type = modify_param_name(name);
1111   if (NOT_RFC2231 != param_type)
1112     {
1113       modify_param_value(value, param_type);
1114     }
1115   return true;
1116 }
1117
1118 #undef NOT_RFC2231
1119 #undef RFC2231_NOENCODING
1120 #undef RFC2231_ENCODING
1121
1122 /* Appends the string represented by VALUE to FILENAME */
1123
1124 static void
1125 append_value_to_filename (char **filename, param_token const * const value)
1126 {
1127   int original_length = strlen(*filename);
1128   int new_length = strlen(*filename) + (value->e - value->b);
1129   *filename = xrealloc (*filename, new_length+1);
1130   memcpy (*filename + original_length, value->b, (value->e - value->b)); 
1131   (*filename)[new_length] = '\0';
1132 }
1133
1134 #undef MAX
1135 #define MAX(p, q) ((p) > (q) ? (p) : (q))
1136
1137 /* Parse the contents of the `Content-Disposition' header, extracting
1138    the information useful to Wget.  Content-Disposition is a header
1139    borrowed from MIME; when used in HTTP, it typically serves for
1140    specifying the desired file name of the resource.  For example:
1141
1142        Content-Disposition: attachment; filename="flora.jpg"
1143
1144    Wget will skip the tokens it doesn't care about, such as
1145    "attachment" in the previous example; it will also skip other
1146    unrecognized params.  If the header is syntactically correct and
1147    contains a file name, a copy of the file name is stored in
1148    *filename and true is returned.  Otherwise, the function returns
1149    false.
1150
1151    The file name is stripped of directory components and must not be
1152    empty.  */
1153 static bool
1154 parse_content_disposition (const char *hdr, char **filename)
1155 {
1156   *filename = NULL;
1157   param_token name, value;
1158   while (extract_param (&hdr, &name, &value, ';'))
1159     {
1160       int isFilename = BOUNDED_EQUAL_NO_CASE ( name.b, name.e, "filename" );
1161       if ( isFilename && value.b != NULL)
1162         {
1163           /* Make the file name begin at the last slash or backslash. */
1164           const char *last_slash = memrchr (value.b, '/', value.e - value.b);
1165           const char *last_bs = memrchr (value.b, '\\', value.e - value.b);
1166           if (last_slash && last_bs)
1167             value.b = 1 + MAX (last_slash, last_bs);
1168           else if (last_slash || last_bs)
1169             value.b = 1 + (last_slash ? last_slash : last_bs);
1170           if (value.b == value.e)
1171             continue;
1172           /* Start with the directory prefix, if specified. */
1173           if (opt.dir_prefix)
1174             {
1175               if (!(*filename))
1176                 {
1177                   int prefix_length = strlen (opt.dir_prefix);
1178                   bool add_slash = (opt.dir_prefix[prefix_length - 1] != '/');
1179                   int total_length;
1180                   
1181                   if (add_slash) 
1182                     ++prefix_length;
1183                   total_length = prefix_length + (value.e - value.b);            
1184                   *filename = xmalloc (total_length + 1);
1185                   strcpy (*filename, opt.dir_prefix);
1186                   if (add_slash) 
1187                     (*filename)[prefix_length - 1] = '/';
1188                   memcpy (*filename + prefix_length, value.b, (value.e - value.b));
1189                   (*filename)[total_length] = '\0';
1190                 }
1191               else
1192                 {
1193                   append_value_to_filename (filename, &value);
1194                 }  
1195             }
1196           else
1197             {
1198               if (*filename)
1199                 {
1200                   append_value_to_filename (filename, &value);
1201                 }
1202               else
1203                 {
1204                   *filename = strdupdelim (value.b, value.e);
1205                 }
1206             }
1207         }
1208     }
1209   if (*filename)
1210     {
1211       return true;
1212     }
1213   else
1214     {
1215       return false;
1216     }
1217 }
1218
1219 \f
1220 /* Persistent connections.  Currently, we cache the most recently used
1221    connection as persistent, provided that the HTTP server agrees to
1222    make it such.  The persistence data is stored in the variables
1223    below.  Ideally, it should be possible to cache an arbitrary fixed
1224    number of these connections.  */
1225
1226 /* Whether a persistent connection is active. */
1227 static bool pconn_active;
1228
1229 static struct {
1230   /* The socket of the connection.  */
1231   int socket;
1232
1233   /* Host and port of the currently active persistent connection. */
1234   char *host;
1235   int port;
1236
1237   /* Whether a ssl handshake has occoured on this connection.  */
1238   bool ssl;
1239
1240   /* Whether the connection was authorized.  This is only done by
1241      NTLM, which authorizes *connections* rather than individual
1242      requests.  (That practice is peculiar for HTTP, but it is a
1243      useful optimization.)  */
1244   bool authorized;
1245
1246 #ifdef ENABLE_NTLM
1247   /* NTLM data of the current connection.  */
1248   struct ntlmdata ntlm;
1249 #endif
1250 } pconn;
1251
1252 /* Mark the persistent connection as invalid and free the resources it
1253    uses.  This is used by the CLOSE_* macros after they forcefully
1254    close a registered persistent connection.  */
1255
1256 static void
1257 invalidate_persistent (void)
1258 {
1259   DEBUGP (("Disabling further reuse of socket %d.\n", pconn.socket));
1260   pconn_active = false;
1261   fd_close (pconn.socket);
1262   xfree (pconn.host);
1263   xzero (pconn);
1264 }
1265
1266 /* Register FD, which should be a TCP/IP connection to HOST:PORT, as
1267    persistent.  This will enable someone to use the same connection
1268    later.  In the context of HTTP, this must be called only AFTER the
1269    response has been received and the server has promised that the
1270    connection will remain alive.
1271
1272    If a previous connection was persistent, it is closed. */
1273
1274 static void
1275 register_persistent (const char *host, int port, int fd, bool ssl)
1276 {
1277   if (pconn_active)
1278     {
1279       if (pconn.socket == fd)
1280         {
1281           /* The connection FD is already registered. */
1282           return;
1283         }
1284       else
1285         {
1286           /* The old persistent connection is still active; close it
1287              first.  This situation arises whenever a persistent
1288              connection exists, but we then connect to a different
1289              host, and try to register a persistent connection to that
1290              one.  */
1291           invalidate_persistent ();
1292         }
1293     }
1294
1295   pconn_active = true;
1296   pconn.socket = fd;
1297   pconn.host = xstrdup (host);
1298   pconn.port = port;
1299   pconn.ssl = ssl;
1300   pconn.authorized = false;
1301
1302   DEBUGP (("Registered socket %d for persistent reuse.\n", fd));
1303 }
1304
1305 /* Return true if a persistent connection is available for connecting
1306    to HOST:PORT.  */
1307
1308 static bool
1309 persistent_available_p (const char *host, int port, bool ssl,
1310                         bool *host_lookup_failed)
1311 {
1312   /* First, check whether a persistent connection is active at all.  */
1313   if (!pconn_active)
1314     return false;
1315
1316   /* If we want SSL and the last connection wasn't or vice versa,
1317      don't use it.  Checking for host and port is not enough because
1318      HTTP and HTTPS can apparently coexist on the same port.  */
1319   if (ssl != pconn.ssl)
1320     return false;
1321
1322   /* If we're not connecting to the same port, we're not interested. */
1323   if (port != pconn.port)
1324     return false;
1325
1326   /* If the host is the same, we're in business.  If not, there is
1327      still hope -- read below.  */
1328   if (0 != strcasecmp (host, pconn.host))
1329     {
1330       /* Check if pconn.socket is talking to HOST under another name.
1331          This happens often when both sites are virtual hosts
1332          distinguished only by name and served by the same network
1333          interface, and hence the same web server (possibly set up by
1334          the ISP and serving many different web sites).  This
1335          admittedly unconventional optimization does not contradict
1336          HTTP and works well with popular server software.  */
1337
1338       bool found;
1339       ip_address ip;
1340       struct address_list *al;
1341
1342       if (ssl)
1343         /* Don't try to talk to two different SSL sites over the same
1344            secure connection!  (Besides, it's not clear that
1345            name-based virtual hosting is even possible with SSL.)  */
1346         return false;
1347
1348       /* If pconn.socket's peer is one of the IP addresses HOST
1349          resolves to, pconn.socket is for all intents and purposes
1350          already talking to HOST.  */
1351
1352       if (!socket_ip_address (pconn.socket, &ip, ENDPOINT_PEER))
1353         {
1354           /* Can't get the peer's address -- something must be very
1355              wrong with the connection.  */
1356           invalidate_persistent ();
1357           return false;
1358         }
1359       al = lookup_host (host, 0);
1360       if (!al)
1361         {
1362           *host_lookup_failed = true;
1363           return false;
1364         }
1365
1366       found = address_list_contains (al, &ip);
1367       address_list_release (al);
1368
1369       if (!found)
1370         return false;
1371
1372       /* The persistent connection's peer address was found among the
1373          addresses HOST resolved to; therefore, pconn.sock is in fact
1374          already talking to HOST -- no need to reconnect.  */
1375     }
1376
1377   /* Finally, check whether the connection is still open.  This is
1378      important because most servers implement liberal (short) timeout
1379      on persistent connections.  Wget can of course always reconnect
1380      if the connection doesn't work out, but it's nicer to know in
1381      advance.  This test is a logical followup of the first test, but
1382      is "expensive" and therefore placed at the end of the list.
1383
1384      (Current implementation of test_socket_open has a nice side
1385      effect that it treats sockets with pending data as "closed".
1386      This is exactly what we want: if a broken server sends message
1387      body in response to HEAD, or if it sends more than conent-length
1388      data, we won't reuse the corrupted connection.)  */
1389
1390   if (!test_socket_open (pconn.socket))
1391     {
1392       /* Oops, the socket is no longer open.  Now that we know that,
1393          let's invalidate the persistent connection before returning
1394          0.  */
1395       invalidate_persistent ();
1396       return false;
1397     }
1398
1399   return true;
1400 }
1401
1402 /* The idea behind these two CLOSE macros is to distinguish between
1403    two cases: one when the job we've been doing is finished, and we
1404    want to close the connection and leave, and two when something is
1405    seriously wrong and we're closing the connection as part of
1406    cleanup.
1407
1408    In case of keep_alive, CLOSE_FINISH should leave the connection
1409    open, while CLOSE_INVALIDATE should still close it.
1410
1411    Note that the semantics of the flag `keep_alive' is "this
1412    connection *will* be reused (the server has promised not to close
1413    the connection once we're done)", while the semantics of
1414    `pc_active_p && (fd) == pc_last_fd' is "we're *now* using an
1415    active, registered connection".  */
1416
1417 #define CLOSE_FINISH(fd) do {                   \
1418   if (!keep_alive)                              \
1419     {                                           \
1420       if (pconn_active && (fd) == pconn.socket) \
1421         invalidate_persistent ();               \
1422       else                                      \
1423         {                                       \
1424           fd_close (fd);                        \
1425           fd = -1;                              \
1426         }                                       \
1427     }                                           \
1428 } while (0)
1429
1430 #define CLOSE_INVALIDATE(fd) do {               \
1431   if (pconn_active && (fd) == pconn.socket)     \
1432     invalidate_persistent ();                   \
1433   else                                          \
1434     fd_close (fd);                              \
1435   fd = -1;                                      \
1436 } while (0)
1437 \f
1438 struct http_stat
1439 {
1440   wgint len;                    /* received length */
1441   wgint contlen;                /* expected length */
1442   wgint restval;                /* the restart value */
1443   int res;                      /* the result of last read */
1444   char *rderrmsg;               /* error message from read error */
1445   char *newloc;                 /* new location (redirection) */
1446   char *remote_time;            /* remote time-stamp string */
1447   char *error;                  /* textual HTTP error */
1448   int statcode;                 /* status code */
1449   char *message;                /* status message */
1450   wgint rd_size;                /* amount of data read from socket */
1451   double dltime;                /* time it took to download the data */
1452   const char *referer;          /* value of the referer header. */
1453   char *local_file;             /* local file name. */
1454   bool existence_checked;       /* true if we already checked for a file's
1455                                    existence after having begun to download
1456                                    (needed in gethttp for when connection is
1457                                    interrupted/restarted. */
1458   bool timestamp_checked;       /* true if pre-download time-stamping checks
1459                                  * have already been performed */
1460   char *orig_file_name;         /* name of file to compare for time-stamping
1461                                  * (might be != local_file if -K is set) */
1462   wgint orig_file_size;         /* size of file to compare for time-stamping */
1463   time_t orig_file_tstamp;      /* time-stamp of file to compare for
1464                                  * time-stamping */
1465 };
1466
1467 static void
1468 free_hstat (struct http_stat *hs)
1469 {
1470   xfree_null (hs->newloc);
1471   xfree_null (hs->remote_time);
1472   xfree_null (hs->error);
1473   xfree_null (hs->rderrmsg);
1474   xfree_null (hs->local_file);
1475   xfree_null (hs->orig_file_name);
1476   xfree_null (hs->message);
1477
1478   /* Guard against being called twice. */
1479   hs->newloc = NULL;
1480   hs->remote_time = NULL;
1481   hs->error = NULL;
1482 }
1483
1484 #define BEGINS_WITH(line, string_constant)                               \
1485   (!strncasecmp (line, string_constant, sizeof (string_constant) - 1)    \
1486    && (c_isspace (line[sizeof (string_constant) - 1])                      \
1487        || !line[sizeof (string_constant) - 1]))
1488
1489 #ifdef __VMS
1490 #define SET_USER_AGENT(req) do {                                         \
1491   if (!opt.useragent)                                                    \
1492     request_set_header (req, "User-Agent",                               \
1493                         aprintf ("Wget/%s (VMS %s %s)",                  \
1494                         version_string, vms_arch(), vms_vers()),         \
1495                         rel_value);                                      \
1496   else if (*opt.useragent)                                               \
1497     request_set_header (req, "User-Agent", opt.useragent, rel_none);     \
1498 } while (0)
1499 #else /* def __VMS */
1500 #define SET_USER_AGENT(req) do {                                         \
1501   if (!opt.useragent)                                                    \
1502     request_set_header (req, "User-Agent",                               \
1503                         aprintf ("Wget/%s (%s)",                         \
1504                         version_string, OS_TYPE),                        \
1505                         rel_value);                                      \
1506   else if (*opt.useragent)                                               \
1507     request_set_header (req, "User-Agent", opt.useragent, rel_none);     \
1508 } while (0)
1509 #endif /* def __VMS [else] */
1510
1511 /* The flags that allow clobbering the file (opening with "wb").
1512    Defined here to avoid repetition later.  #### This will require
1513    rework.  */
1514 #define ALLOW_CLOBBER (opt.noclobber || opt.always_rest || opt.timestamping \
1515                        || opt.dirstruct || opt.output_document)
1516
1517 /* Retrieve a document through HTTP protocol.  It recognizes status
1518    code, and correctly handles redirections.  It closes the network
1519    socket.  If it receives an error from the functions below it, it
1520    will print it if there is enough information to do so (almost
1521    always), returning the error to the caller (i.e. http_loop).
1522
1523    Various HTTP parameters are stored to hs.
1524
1525    If PROXY is non-NULL, the connection will be made to the proxy
1526    server, and u->url will be requested.  */
1527 static uerr_t
1528 gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
1529          struct iri *iri)
1530 {
1531   struct request *req;
1532
1533   char *type;
1534   char *user, *passwd;
1535   char *proxyauth;
1536   int statcode;
1537   int write_error;
1538   wgint contlen, contrange;
1539   struct url *conn;
1540   FILE *fp;
1541
1542   int sock = -1;
1543   int flags;
1544
1545   /* Set to 1 when the authorization has already been sent and should
1546      not be tried again. */
1547   bool auth_finished = false;
1548
1549   /* Set to 1 when just globally-set Basic authorization has been sent;
1550    * should prevent further Basic negotiations, but not other
1551    * mechanisms. */
1552   bool basic_auth_finished = false;
1553
1554   /* Whether NTLM authentication is used for this request. */
1555   bool ntlm_seen = false;
1556
1557   /* Whether our connection to the remote host is through SSL.  */
1558   bool using_ssl = false;
1559
1560   /* Whether a HEAD request will be issued (as opposed to GET or
1561      POST). */
1562   bool head_only = !!(*dt & HEAD_ONLY);
1563
1564   char *head;
1565   struct response *resp;
1566   char hdrval[256];
1567   char *message;
1568
1569   /* Whether this connection will be kept alive after the HTTP request
1570      is done. */
1571   bool keep_alive;
1572
1573   /* Is the server using the chunked transfer encoding?  */
1574   bool chunked_transfer_encoding = false;
1575
1576   /* Whether keep-alive should be inhibited.
1577
1578      RFC 2068 requests that 1.0 clients not send keep-alive requests
1579      to proxies.  This is because many 1.0 proxies do not interpret
1580      the Connection header and transfer it to the remote server,
1581      causing it to not close the connection and leave both the proxy
1582      and the client hanging.  */
1583   bool inhibit_keep_alive =
1584     !opt.http_keep_alive || opt.ignore_length || proxy != NULL;
1585
1586   /* Headers sent when using POST. */
1587   wgint post_data_size = 0;
1588
1589   bool host_lookup_failed = false;
1590
1591 #ifdef HAVE_SSL
1592   if (u->scheme == SCHEME_HTTPS)
1593     {
1594       /* Initialize the SSL context.  After this has once been done,
1595          it becomes a no-op.  */
1596       if (!ssl_init ())
1597         {
1598           scheme_disable (SCHEME_HTTPS);
1599           logprintf (LOG_NOTQUIET,
1600                      _("Disabling SSL due to encountered errors.\n"));
1601           return SSLINITFAILED;
1602         }
1603     }
1604 #endif /* HAVE_SSL */
1605
1606   /* Initialize certain elements of struct http_stat.  */
1607   hs->len = 0;
1608   hs->contlen = -1;
1609   hs->res = -1;
1610   hs->rderrmsg = NULL;
1611   hs->newloc = NULL;
1612   hs->remote_time = NULL;
1613   hs->error = NULL;
1614   hs->message = NULL;
1615
1616   conn = u;
1617
1618   /* Prepare the request to send. */
1619
1620   req = request_new ();
1621   {
1622     char *meth_arg;
1623     const char *meth = "GET";
1624     if (head_only)
1625       meth = "HEAD";
1626     else if (opt.post_file_name || opt.post_data)
1627       meth = "POST";
1628     /* Use the full path, i.e. one that includes the leading slash and
1629        the query string.  E.g. if u->path is "foo/bar" and u->query is
1630        "param=value", full_path will be "/foo/bar?param=value".  */
1631     if (proxy
1632 #ifdef HAVE_SSL
1633         /* When using SSL over proxy, CONNECT establishes a direct
1634            connection to the HTTPS server.  Therefore use the same
1635            argument as when talking to the server directly. */
1636         && u->scheme != SCHEME_HTTPS
1637 #endif
1638         )
1639       meth_arg = xstrdup (u->url);
1640     else
1641       meth_arg = url_full_path (u);
1642     request_set_method (req, meth, meth_arg);
1643   }
1644
1645   request_set_header (req, "Referer", (char *) hs->referer, rel_none);
1646   if (*dt & SEND_NOCACHE)
1647     request_set_header (req, "Pragma", "no-cache", rel_none);
1648   if (hs->restval)
1649     request_set_header (req, "Range",
1650                         aprintf ("bytes=%s-",
1651                                  number_to_static_string (hs->restval)),
1652                         rel_value);
1653   SET_USER_AGENT (req);
1654   request_set_header (req, "Accept", "*/*", rel_none);
1655
1656   /* Find the username and password for authentication. */
1657   user = u->user;
1658   passwd = u->passwd;
1659   search_netrc (u->host, (const char **)&user, (const char **)&passwd, 0);
1660   user = user ? user : (opt.http_user ? opt.http_user : opt.user);
1661   passwd = passwd ? passwd : (opt.http_passwd ? opt.http_passwd : opt.passwd);
1662
1663   /* We only do "site-wide" authentication with "global" user/password
1664    * values unless --auth-no-challange has been requested; URL user/password
1665    * info overrides. */
1666   if (user && passwd && (!u->user || opt.auth_without_challenge))
1667     {
1668       /* If this is a host for which we've already received a Basic
1669        * challenge, we'll go ahead and send Basic authentication creds. */
1670       basic_auth_finished = maybe_send_basic_creds(u->host, user, passwd, req);
1671     }
1672
1673   /* Generate the Host header, HOST:PORT.  Take into account that:
1674
1675      - Broken server-side software often doesn't recognize the PORT
1676        argument, so we must generate "Host: www.server.com" instead of
1677        "Host: www.server.com:80" (and likewise for https port).
1678
1679      - IPv6 addresses contain ":", so "Host: 3ffe:8100:200:2::2:1234"
1680        becomes ambiguous and needs to be rewritten as "Host:
1681        [3ffe:8100:200:2::2]:1234".  */
1682   {
1683     /* Formats arranged for hfmt[add_port][add_squares].  */
1684     static const char *hfmt[][2] = {
1685       { "%s", "[%s]" }, { "%s:%d", "[%s]:%d" }
1686     };
1687     int add_port = u->port != scheme_default_port (u->scheme);
1688     int add_squares = strchr (u->host, ':') != NULL;
1689     request_set_header (req, "Host",
1690                         aprintf (hfmt[add_port][add_squares], u->host, u->port),
1691                         rel_value);
1692   }
1693
1694   if (!inhibit_keep_alive)
1695     request_set_header (req, "Connection", "Keep-Alive", rel_none);
1696
1697   if (opt.post_data || opt.post_file_name)
1698     {
1699       request_set_header (req, "Content-Type",
1700                           "application/x-www-form-urlencoded", rel_none);
1701       if (opt.post_data)
1702         post_data_size = strlen (opt.post_data);
1703       else
1704         {
1705           post_data_size = file_size (opt.post_file_name);
1706           if (post_data_size == -1)
1707             {
1708               logprintf (LOG_NOTQUIET, _("POST data file %s missing: %s\n"),
1709                          quote (opt.post_file_name), strerror (errno));
1710               post_data_size = 0;
1711             }
1712         }
1713       request_set_header (req, "Content-Length",
1714                           xstrdup (number_to_static_string (post_data_size)),
1715                           rel_value);
1716     }
1717
1718  retry_with_auth:
1719   /* We need to come back here when the initial attempt to retrieve
1720      without authorization header fails.  (Expected to happen at least
1721      for the Digest authorization scheme.)  */
1722
1723   if (opt.cookies)
1724     request_set_header (req, "Cookie",
1725                         cookie_header (wget_cookie_jar,
1726                                        u->host, u->port, u->path,
1727 #ifdef HAVE_SSL
1728                                        u->scheme == SCHEME_HTTPS
1729 #else
1730                                        0
1731 #endif
1732                                        ),
1733                         rel_value);
1734
1735   /* Add the user headers. */
1736   if (opt.user_headers)
1737     {
1738       int i;
1739       for (i = 0; opt.user_headers[i]; i++)
1740         request_set_user_header (req, opt.user_headers[i]);
1741     }
1742
1743   proxyauth = NULL;
1744   if (proxy)
1745     {
1746       char *proxy_user, *proxy_passwd;
1747       /* For normal username and password, URL components override
1748          command-line/wgetrc parameters.  With proxy
1749          authentication, it's the reverse, because proxy URLs are
1750          normally the "permanent" ones, so command-line args
1751          should take precedence.  */
1752       if (opt.proxy_user && opt.proxy_passwd)
1753         {
1754           proxy_user = opt.proxy_user;
1755           proxy_passwd = opt.proxy_passwd;
1756         }
1757       else
1758         {
1759           proxy_user = proxy->user;
1760           proxy_passwd = proxy->passwd;
1761         }
1762       /* #### This does not appear right.  Can't the proxy request,
1763          say, `Digest' authentication?  */
1764       if (proxy_user && proxy_passwd)
1765         proxyauth = basic_authentication_encode (proxy_user, proxy_passwd);
1766
1767       /* If we're using a proxy, we will be connecting to the proxy
1768          server.  */
1769       conn = proxy;
1770
1771       /* Proxy authorization over SSL is handled below. */
1772 #ifdef HAVE_SSL
1773       if (u->scheme != SCHEME_HTTPS)
1774 #endif
1775         request_set_header (req, "Proxy-Authorization", proxyauth, rel_value);
1776     }
1777
1778   keep_alive = true;
1779
1780   /* Establish the connection.  */
1781
1782   if (inhibit_keep_alive)
1783     keep_alive = false;
1784   else
1785     {
1786       /* Look for a persistent connection to target host, unless a
1787          proxy is used.  The exception is when SSL is in use, in which
1788          case the proxy is nothing but a passthrough to the target
1789          host, registered as a connection to the latter.  */
1790       struct url *relevant = conn;
1791 #ifdef HAVE_SSL
1792       if (u->scheme == SCHEME_HTTPS)
1793         relevant = u;
1794 #endif
1795
1796       if (persistent_available_p (relevant->host, relevant->port,
1797 #ifdef HAVE_SSL
1798                                   relevant->scheme == SCHEME_HTTPS,
1799 #else
1800                                   0,
1801 #endif
1802                                   &host_lookup_failed))
1803         {
1804           sock = pconn.socket;
1805           using_ssl = pconn.ssl;
1806           logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"),
1807                      quotearg_style (escape_quoting_style, pconn.host),
1808                      pconn.port);
1809           DEBUGP (("Reusing fd %d.\n", sock));
1810           if (pconn.authorized)
1811             /* If the connection is already authorized, the "Basic"
1812                authorization added by code above is unnecessary and
1813                only hurts us.  */
1814             request_remove_header (req, "Authorization");
1815         }
1816       else if (host_lookup_failed)
1817         {
1818           request_free (req);
1819           logprintf(LOG_NOTQUIET,
1820                     _("%s: unable to resolve host address %s\n"),
1821                     exec_name, quote (relevant->host));
1822           return HOSTERR;
1823         }
1824     }
1825
1826   if (sock < 0)
1827     {
1828       sock = connect_to_host (conn->host, conn->port);
1829       if (sock == E_HOST)
1830         {
1831           request_free (req);
1832           return HOSTERR;
1833         }
1834       else if (sock < 0)
1835         {
1836           request_free (req);
1837           return (retryable_socket_connect_error (errno)
1838                   ? CONERROR : CONIMPOSSIBLE);
1839         }
1840
1841 #ifdef HAVE_SSL
1842       if (proxy && u->scheme == SCHEME_HTTPS)
1843         {
1844           /* When requesting SSL URLs through proxies, use the
1845              CONNECT method to request passthrough.  */
1846           struct request *connreq = request_new ();
1847           request_set_method (connreq, "CONNECT",
1848                               aprintf ("%s:%d", u->host, u->port));
1849           SET_USER_AGENT (connreq);
1850           if (proxyauth)
1851             {
1852               request_set_header (connreq, "Proxy-Authorization",
1853                                   proxyauth, rel_value);
1854               /* Now that PROXYAUTH is part of the CONNECT request,
1855                  zero it out so we don't send proxy authorization with
1856                  the regular request below.  */
1857               proxyauth = NULL;
1858             }
1859           /* Examples in rfc2817 use the Host header in CONNECT
1860              requests.  I don't see how that gains anything, given
1861              that the contents of Host would be exactly the same as
1862              the contents of CONNECT.  */
1863
1864           write_error = request_send (connreq, sock);
1865           request_free (connreq);
1866           if (write_error < 0)
1867             {
1868               CLOSE_INVALIDATE (sock);
1869               return WRITEFAILED;
1870             }
1871
1872           head = read_http_response_head (sock);
1873           if (!head)
1874             {
1875               logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
1876                          fd_errstr (sock));
1877               CLOSE_INVALIDATE (sock);
1878               return HERR;
1879             }
1880           message = NULL;
1881           if (!*head)
1882             {
1883               xfree (head);
1884               goto failed_tunnel;
1885             }
1886           DEBUGP (("proxy responded with: [%s]\n", head));
1887
1888           resp = resp_new (head);
1889           statcode = resp_status (resp, &message);
1890           if (statcode < 0)
1891             {
1892               char *tms = datetime_str (time (NULL));
1893               logprintf (LOG_VERBOSE, "%d\n", statcode);
1894               logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"), tms, statcode,
1895                          quotearg_style (escape_quoting_style,
1896                                          _("Malformed status line")));
1897               xfree (head);
1898               return HERR;
1899             }
1900           hs->message = xstrdup (message);
1901           resp_free (resp);
1902           xfree (head);
1903           if (statcode != 200)
1904             {
1905             failed_tunnel:
1906               logprintf (LOG_NOTQUIET, _("Proxy tunneling failed: %s"),
1907                          message ? quotearg_style (escape_quoting_style, message) : "?");
1908               xfree_null (message);
1909               return CONSSLERR;
1910             }
1911           xfree_null (message);
1912
1913           /* SOCK is now *really* connected to u->host, so update CONN
1914              to reflect this.  That way register_persistent will
1915              register SOCK as being connected to u->host:u->port.  */
1916           conn = u;
1917         }
1918
1919       if (conn->scheme == SCHEME_HTTPS)
1920         {
1921           if (!ssl_connect_wget (sock))
1922             {
1923               fd_close (sock);
1924               return CONSSLERR;
1925             }
1926           else if (!ssl_check_certificate (sock, u->host))
1927             {
1928               fd_close (sock);
1929               return VERIFCERTERR;
1930             }
1931           using_ssl = true;
1932         }
1933 #endif /* HAVE_SSL */
1934     }
1935
1936   /* Send the request to server.  */
1937   write_error = request_send (req, sock);
1938
1939   if (write_error >= 0)
1940     {
1941       if (opt.post_data)
1942         {
1943           DEBUGP (("[POST data: %s]\n", opt.post_data));
1944           write_error = fd_write (sock, opt.post_data, post_data_size, -1);
1945         }
1946       else if (opt.post_file_name && post_data_size != 0)
1947         write_error = post_file (sock, opt.post_file_name, post_data_size);
1948     }
1949
1950   if (write_error < 0)
1951     {
1952       CLOSE_INVALIDATE (sock);
1953       request_free (req);
1954       return WRITEFAILED;
1955     }
1956   logprintf (LOG_VERBOSE, _("%s request sent, awaiting response... "),
1957              proxy ? "Proxy" : "HTTP");
1958   contlen = -1;
1959   contrange = 0;
1960   *dt &= ~RETROKF;
1961
1962 read_header:
1963   head = read_http_response_head (sock);
1964   if (!head)
1965     {
1966       if (errno == 0)
1967         {
1968           logputs (LOG_NOTQUIET, _("No data received.\n"));
1969           CLOSE_INVALIDATE (sock);
1970           request_free (req);
1971           return HEOF;
1972         }
1973       else
1974         {
1975           logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
1976                      fd_errstr (sock));
1977           CLOSE_INVALIDATE (sock);
1978           request_free (req);
1979           return HERR;
1980         }
1981     }
1982   DEBUGP (("\n---response begin---\n%s---response end---\n", head));
1983
1984   resp = resp_new (head);
1985
1986   /* Check for status line.  */
1987   message = NULL;
1988   statcode = resp_status (resp, &message);
1989   if (statcode < 0)
1990     {
1991       char *tms = datetime_str (time (NULL));
1992       logprintf (LOG_VERBOSE, "%d\n", statcode);
1993       logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"), tms, statcode,
1994                  quotearg_style (escape_quoting_style,
1995                                  _("Malformed status line")));
1996       CLOSE_INVALIDATE (sock);
1997       request_free (req);
1998       return HERR;
1999     }
2000
2001   if (H_10X (statcode))
2002     {
2003       DEBUGP (("Ignoring response\n"));
2004       goto read_header;
2005     }
2006
2007   hs->message = xstrdup (message);
2008   if (!opt.server_response)
2009     logprintf (LOG_VERBOSE, "%2d %s\n", statcode,
2010                message ? quotearg_style (escape_quoting_style, message) : "");
2011   else
2012     {
2013       logprintf (LOG_VERBOSE, "\n");
2014       print_server_response (resp, "  ");
2015     }
2016
2017   if (!opt.ignore_length
2018       && resp_header_copy (resp, "Content-Length", hdrval, sizeof (hdrval)))
2019     {
2020       wgint parsed;
2021       errno = 0;
2022       parsed = str_to_wgint (hdrval, NULL, 10);
2023       if (parsed == WGINT_MAX && errno == ERANGE)
2024         {
2025           /* Out of range.
2026              #### If Content-Length is out of range, it most likely
2027              means that the file is larger than 2G and that we're
2028              compiled without LFS.  In that case we should probably
2029              refuse to even attempt to download the file.  */
2030           contlen = -1;
2031         }
2032       else if (parsed < 0)
2033         {
2034           /* Negative Content-Length; nonsensical, so we can't
2035              assume any information about the content to receive. */
2036           contlen = -1;
2037         }
2038       else
2039         contlen = parsed;
2040     }
2041
2042   /* Check for keep-alive related responses. */
2043   if (!inhibit_keep_alive && contlen != -1)
2044     {
2045       if (resp_header_copy (resp, "Connection", hdrval, sizeof (hdrval)))
2046         {
2047           if (0 == strcasecmp (hdrval, "Close"))
2048             keep_alive = false;
2049         }
2050     }
2051
2052   resp_header_copy (resp, "Transfer-Encoding", hdrval, sizeof (hdrval));
2053   if (0 == strcasecmp (hdrval, "chunked"))
2054     chunked_transfer_encoding = true;
2055
2056   /* Handle (possibly multiple instances of) the Set-Cookie header. */
2057   if (opt.cookies)
2058     {
2059       int scpos;
2060       const char *scbeg, *scend;
2061       /* The jar should have been created by now. */
2062       assert (wget_cookie_jar != NULL);
2063       for (scpos = 0;
2064            (scpos = resp_header_locate (resp, "Set-Cookie", scpos,
2065                                         &scbeg, &scend)) != -1;
2066            ++scpos)
2067         {
2068           char *set_cookie; BOUNDED_TO_ALLOCA (scbeg, scend, set_cookie);
2069           cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port,
2070                                     u->path, set_cookie);
2071         }
2072     }
2073
2074   if (keep_alive)
2075     /* The server has promised that it will not close the connection
2076        when we're done.  This means that we can register it.  */
2077     register_persistent (conn->host, conn->port, sock, using_ssl);
2078
2079   if (statcode == HTTP_STATUS_UNAUTHORIZED)
2080     {
2081       /* Authorization is required.  */
2082       if (keep_alive && !head_only
2083           && skip_short_body (sock, contlen, chunked_transfer_encoding))
2084         CLOSE_FINISH (sock);
2085       else
2086         CLOSE_INVALIDATE (sock);
2087       pconn.authorized = false;
2088       if (!auth_finished && (user && passwd))
2089         {
2090           /* IIS sends multiple copies of WWW-Authenticate, one with
2091              the value "negotiate", and other(s) with data.  Loop over
2092              all the occurrences and pick the one we recognize.  */
2093           int wapos;
2094           const char *wabeg, *waend;
2095           char *www_authenticate = NULL;
2096           for (wapos = 0;
2097                (wapos = resp_header_locate (resp, "WWW-Authenticate", wapos,
2098                                             &wabeg, &waend)) != -1;
2099                ++wapos)
2100             if (known_authentication_scheme_p (wabeg, waend))
2101               {
2102                 BOUNDED_TO_ALLOCA (wabeg, waend, www_authenticate);
2103                 break;
2104               }
2105
2106           if (!www_authenticate)
2107             {
2108               /* If the authentication header is missing or
2109                  unrecognized, there's no sense in retrying.  */
2110               logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n"));
2111             }
2112           else if (!basic_auth_finished
2113                    || !BEGINS_WITH (www_authenticate, "Basic"))
2114             {
2115               char *pth;
2116               pth = url_full_path (u);
2117               request_set_header (req, "Authorization",
2118                                   create_authorization_line (www_authenticate,
2119                                                              user, passwd,
2120                                                              request_method (req),
2121                                                              pth,
2122                                                              &auth_finished),
2123                                   rel_value);
2124               if (BEGINS_WITH (www_authenticate, "NTLM"))
2125                 ntlm_seen = true;
2126               else if (!u->user && BEGINS_WITH (www_authenticate, "Basic"))
2127                 {
2128                   /* Need to register this host as using basic auth,
2129                    * so we automatically send creds next time. */
2130                   register_basic_auth_host (u->host);
2131                 }
2132               xfree (pth);
2133               xfree_null (message);
2134               resp_free (resp);
2135               xfree (head);
2136               goto retry_with_auth;
2137             }
2138           else
2139             {
2140               /* We already did Basic auth, and it failed. Gotta
2141                * give up. */
2142             }
2143         }
2144       logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
2145       request_free (req);
2146       xfree_null (message);
2147       resp_free (resp);
2148       xfree (head);
2149       return AUTHFAILED;
2150     }
2151   else /* statcode != HTTP_STATUS_UNAUTHORIZED */
2152     {
2153       /* Kludge: if NTLM is used, mark the TCP connection as authorized. */
2154       if (ntlm_seen)
2155         pconn.authorized = true;
2156     }
2157
2158   /* Determine the local filename if needed. Notice that if -O is used
2159    * hstat.local_file is set by http_loop to the argument of -O. */
2160   if (!hs->local_file)
2161     {
2162       /* Honor Content-Disposition whether possible. */
2163       if (!opt.content_disposition
2164           || !resp_header_copy (resp, "Content-Disposition",
2165                                 hdrval, sizeof (hdrval))
2166           || !parse_content_disposition (hdrval, &hs->local_file))
2167         {
2168           /* The Content-Disposition header is missing or broken.
2169            * Choose unique file name according to given URL. */
2170           hs->local_file = url_file_name (u);
2171         }
2172     }
2173
2174   /* TODO: perform this check only once. */
2175   if (!hs->existence_checked && file_exists_p (hs->local_file))
2176     {
2177       if (opt.noclobber && !opt.output_document)
2178         {
2179           /* If opt.noclobber is turned on and file already exists, do not
2180              retrieve the file. But if the output_document was given, then this
2181              test was already done and the file didn't exist. Hence the !opt.output_document */
2182           logprintf (LOG_VERBOSE, _("\
2183 File %s already there; not retrieving.\n\n"), quote (hs->local_file));
2184           /* If the file is there, we suppose it's retrieved OK.  */
2185           *dt |= RETROKF;
2186
2187           /* #### Bogusness alert.  */
2188           /* If its suffix is "html" or "htm" or similar, assume text/html.  */
2189           if (has_html_suffix_p (hs->local_file))
2190             *dt |= TEXTHTML;
2191
2192           xfree (head);
2193           xfree_null (message);
2194           return RETRUNNEEDED;
2195         }
2196       else if (!ALLOW_CLOBBER)
2197         {
2198           char *unique = unique_name (hs->local_file, true);
2199           if (unique != hs->local_file)
2200             xfree (hs->local_file);
2201           hs->local_file = unique;
2202         }
2203     }
2204   hs->existence_checked = true;
2205
2206   /* Support timestamping */
2207   /* TODO: move this code out of gethttp. */
2208   if (opt.timestamping && !hs->timestamp_checked)
2209     {
2210       size_t filename_len = strlen (hs->local_file);
2211       char *filename_plus_orig_suffix = alloca (filename_len + sizeof (ORIG_SFX));
2212       bool local_dot_orig_file_exists = false;
2213       char *local_filename = NULL;
2214       struct_stat st;
2215
2216       if (opt.backup_converted)
2217         /* If -K is specified, we'll act on the assumption that it was specified
2218            last time these files were downloaded as well, and instead of just
2219            comparing local file X against server file X, we'll compare local
2220            file X.orig (if extant, else X) against server file X.  If -K
2221            _wasn't_ specified last time, or the server contains files called
2222            *.orig, -N will be back to not operating correctly with -k. */
2223         {
2224           /* Would a single s[n]printf() call be faster?  --dan
2225
2226              Definitely not.  sprintf() is horribly slow.  It's a
2227              different question whether the difference between the two
2228              affects a program.  Usually I'd say "no", but at one
2229              point I profiled Wget, and found that a measurable and
2230              non-negligible amount of time was lost calling sprintf()
2231              in url.c.  Replacing sprintf with inline calls to
2232              strcpy() and number_to_string() made a difference.
2233              --hniksic */
2234           memcpy (filename_plus_orig_suffix, hs->local_file, filename_len);
2235           memcpy (filename_plus_orig_suffix + filename_len,
2236                   ORIG_SFX, sizeof (ORIG_SFX));
2237
2238           /* Try to stat() the .orig file. */
2239           if (stat (filename_plus_orig_suffix, &st) == 0)
2240             {
2241               local_dot_orig_file_exists = true;
2242               local_filename = filename_plus_orig_suffix;
2243             }
2244         }
2245
2246       if (!local_dot_orig_file_exists)
2247         /* Couldn't stat() <file>.orig, so try to stat() <file>. */
2248         if (stat (hs->local_file, &st) == 0)
2249           local_filename = hs->local_file;
2250
2251       if (local_filename != NULL)
2252         /* There was a local file, so we'll check later to see if the version
2253            the server has is the same version we already have, allowing us to
2254            skip a download. */
2255         {
2256           hs->orig_file_name = xstrdup (local_filename);
2257           hs->orig_file_size = st.st_size;
2258           hs->orig_file_tstamp = st.st_mtime;
2259 #ifdef WINDOWS
2260           /* Modification time granularity is 2 seconds for Windows, so
2261              increase local time by 1 second for later comparison. */
2262           ++hs->orig_file_tstamp;
2263 #endif
2264         }
2265     }
2266
2267   request_free (req);
2268
2269   hs->statcode = statcode;
2270   if (statcode == -1)
2271     hs->error = xstrdup (_("Malformed status line"));
2272   else if (!*message)
2273     hs->error = xstrdup (_("(no description)"));
2274   else
2275     hs->error = xstrdup (message);
2276   xfree_null (message);
2277
2278   type = resp_header_strdup (resp, "Content-Type");
2279   if (type)
2280     {
2281       char *tmp = strchr (type, ';');
2282       if (tmp)
2283         {
2284           /* sXXXav: only needed if IRI support is enabled */
2285           char *tmp2 = tmp + 1;
2286
2287           while (tmp > type && c_isspace (tmp[-1]))
2288             --tmp;
2289           *tmp = '\0';
2290
2291           /* Try to get remote encoding if needed */
2292           if (opt.enable_iri && !opt.encoding_remote)
2293             {
2294               tmp = parse_charset (tmp2);
2295               if (tmp)
2296                 set_content_encoding (iri, tmp);
2297             }
2298         }
2299     }
2300   hs->newloc = resp_header_strdup (resp, "Location");
2301   hs->remote_time = resp_header_strdup (resp, "Last-Modified");
2302
2303   if (resp_header_copy (resp, "Content-Range", hdrval, sizeof (hdrval)))
2304     {
2305       wgint first_byte_pos, last_byte_pos, entity_length;
2306       if (parse_content_range (hdrval, &first_byte_pos, &last_byte_pos,
2307                                &entity_length))
2308         {
2309           contrange = first_byte_pos;
2310           contlen = last_byte_pos - first_byte_pos + 1;
2311         }
2312     }
2313   resp_free (resp);
2314
2315   /* 20x responses are counted among successful by default.  */
2316   if (H_20X (statcode))
2317     *dt |= RETROKF;
2318
2319   /* Return if redirected.  */
2320   if (H_REDIRECTED (statcode) || statcode == HTTP_STATUS_MULTIPLE_CHOICES)
2321     {
2322       /* RFC2068 says that in case of the 300 (multiple choices)
2323          response, the server can output a preferred URL through
2324          `Location' header; otherwise, the request should be treated
2325          like GET.  So, if the location is set, it will be a
2326          redirection; otherwise, just proceed normally.  */
2327       if (statcode == HTTP_STATUS_MULTIPLE_CHOICES && !hs->newloc)
2328         *dt |= RETROKF;
2329       else
2330         {
2331           logprintf (LOG_VERBOSE,
2332                      _("Location: %s%s\n"),
2333                      hs->newloc ? escnonprint_uri (hs->newloc) : _("unspecified"),
2334                      hs->newloc ? _(" [following]") : "");
2335           if (keep_alive && !head_only
2336               && skip_short_body (sock, contlen, chunked_transfer_encoding))
2337             CLOSE_FINISH (sock);
2338           else
2339             CLOSE_INVALIDATE (sock);
2340           xfree_null (type);
2341           xfree (head);
2342           return NEWLOCATION;
2343         }
2344     }
2345
2346   /* If content-type is not given, assume text/html.  This is because
2347      of the multitude of broken CGI's that "forget" to generate the
2348      content-type.  */
2349   if (!type ||
2350         0 == strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)) ||
2351         0 == strncasecmp (type, TEXTXHTML_S, strlen (TEXTXHTML_S)))
2352     *dt |= TEXTHTML;
2353   else
2354     *dt &= ~TEXTHTML;
2355
2356   if (type &&
2357       0 == strncasecmp (type, TEXTCSS_S, strlen (TEXTCSS_S)))
2358     *dt |= TEXTCSS;
2359   else
2360     *dt &= ~TEXTCSS;
2361
2362   if (opt.adjust_extension)
2363     {
2364       if (*dt & TEXTHTML)
2365         /* -E / --adjust-extension / adjust_extension = on was specified,
2366            and this is a text/html file.  If some case-insensitive
2367            variation on ".htm[l]" isn't already the file's suffix,
2368            tack on ".html". */
2369         {
2370           ensure_extension (hs, ".html", dt);
2371         }
2372       else if (*dt & TEXTCSS)
2373         {
2374           ensure_extension (hs, ".css", dt);
2375         }
2376     }
2377
2378   if (statcode == HTTP_STATUS_RANGE_NOT_SATISFIABLE
2379       || (hs->restval > 0 && statcode == HTTP_STATUS_OK
2380           && contrange == 0 && hs->restval >= contlen)
2381      )
2382     {
2383       /* If `-c' is in use and the file has been fully downloaded (or
2384          the remote file has shrunk), Wget effectively requests bytes
2385          after the end of file and the server response with 416
2386          (or 200 with a <= Content-Length.  */
2387       logputs (LOG_VERBOSE, _("\
2388 \n    The file is already fully retrieved; nothing to do.\n\n"));
2389       /* In case the caller inspects. */
2390       hs->len = contlen;
2391       hs->res = 0;
2392       /* Mark as successfully retrieved. */
2393       *dt |= RETROKF;
2394       xfree_null (type);
2395       CLOSE_INVALIDATE (sock);        /* would be CLOSE_FINISH, but there
2396                                    might be more bytes in the body. */
2397       xfree (head);
2398       return RETRUNNEEDED;
2399     }
2400   if ((contrange != 0 && contrange != hs->restval)
2401       || (H_PARTIAL (statcode) && !contrange))
2402     {
2403       /* The Range request was somehow misunderstood by the server.
2404          Bail out.  */
2405       xfree_null (type);
2406       CLOSE_INVALIDATE (sock);
2407       xfree (head);
2408       return RANGEERR;
2409     }
2410   if (contlen == -1)
2411     hs->contlen = -1;
2412   else
2413     hs->contlen = contlen + contrange;
2414
2415   if (opt.verbose)
2416     {
2417       if (*dt & RETROKF)
2418         {
2419           /* No need to print this output if the body won't be
2420              downloaded at all, or if the original server response is
2421              printed.  */
2422           logputs (LOG_VERBOSE, _("Length: "));
2423           if (contlen != -1)
2424             {
2425               logputs (LOG_VERBOSE, number_to_static_string (contlen + contrange));
2426               if (contlen + contrange >= 1024)
2427                 logprintf (LOG_VERBOSE, " (%s)",
2428                            human_readable (contlen + contrange));
2429               if (contrange)
2430                 {
2431                   if (contlen >= 1024)
2432                     logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
2433                                number_to_static_string (contlen),
2434                                human_readable (contlen));
2435                   else
2436                     logprintf (LOG_VERBOSE, _(", %s remaining"),
2437                                number_to_static_string (contlen));
2438                 }
2439             }
2440           else
2441             logputs (LOG_VERBOSE,
2442                      opt.ignore_length ? _("ignored") : _("unspecified"));
2443           if (type)
2444             logprintf (LOG_VERBOSE, " [%s]\n", quotearg_style (escape_quoting_style, type));
2445           else
2446             logputs (LOG_VERBOSE, "\n");
2447         }
2448     }
2449   xfree_null (type);
2450   type = NULL;                        /* We don't need it any more.  */
2451
2452   /* Return if we have no intention of further downloading.  */
2453   if (!(*dt & RETROKF) || head_only)
2454     {
2455       /* In case the caller cares to look...  */
2456       hs->len = 0;
2457       hs->res = 0;
2458       xfree_null (type);
2459       if (head_only)
2460         /* Pre-1.10 Wget used CLOSE_INVALIDATE here.  Now we trust the
2461            servers not to send body in response to a HEAD request, and
2462            those that do will likely be caught by test_socket_open.
2463            If not, they can be worked around using
2464            `--no-http-keep-alive'.  */
2465         CLOSE_FINISH (sock);
2466       else if (keep_alive
2467                && skip_short_body (sock, contlen, chunked_transfer_encoding))
2468         /* Successfully skipped the body; also keep using the socket. */
2469         CLOSE_FINISH (sock);
2470       else
2471         CLOSE_INVALIDATE (sock);
2472       xfree (head);
2473       return RETRFINISHED;
2474     }
2475
2476 /* 2005-06-17 SMS.
2477    For VMS, define common fopen() optional arguments.
2478 */
2479 #ifdef __VMS
2480 # define FOPEN_OPT_ARGS "fop=sqo", "acc", acc_cb, &open_id
2481 # define FOPEN_BIN_FLAG 3
2482 #else /* def __VMS */
2483 # define FOPEN_BIN_FLAG true
2484 #endif /* def __VMS [else] */
2485
2486   /* Open the local file.  */
2487   if (!output_stream)
2488     {
2489       mkalldirs (hs->local_file);
2490       if (opt.backups)
2491         rotate_backups (hs->local_file);
2492       if (hs->restval)
2493         {
2494 #ifdef __VMS
2495           int open_id;
2496
2497           open_id = 21;
2498           fp = fopen (hs->local_file, "ab", FOPEN_OPT_ARGS);
2499 #else /* def __VMS */
2500           fp = fopen (hs->local_file, "ab");
2501 #endif /* def __VMS [else] */
2502         }
2503       else if (ALLOW_CLOBBER)
2504         {
2505 #ifdef __VMS
2506           int open_id;
2507
2508           open_id = 22;
2509           fp = fopen (hs->local_file, "wb", FOPEN_OPT_ARGS);
2510 #else /* def __VMS */
2511           fp = fopen (hs->local_file, "wb");
2512 #endif /* def __VMS [else] */
2513         }
2514       else
2515         {
2516           fp = fopen_excl (hs->local_file, FOPEN_BIN_FLAG);
2517           if (!fp && errno == EEXIST)
2518             {
2519               /* We cannot just invent a new name and use it (which is
2520                  what functions like unique_create typically do)
2521                  because we told the user we'd use this name.
2522                  Instead, return and retry the download.  */
2523               logprintf (LOG_NOTQUIET,
2524                          _("%s has sprung into existence.\n"),
2525                          hs->local_file);
2526               CLOSE_INVALIDATE (sock);
2527               xfree (head);
2528               return FOPEN_EXCL_ERR;
2529             }
2530         }
2531       if (!fp)
2532         {
2533           logprintf (LOG_NOTQUIET, "%s: %s\n", hs->local_file, strerror (errno));
2534           CLOSE_INVALIDATE (sock);
2535           xfree (head);
2536           return FOPENERR;
2537         }
2538     }
2539   else
2540     fp = output_stream;
2541
2542   /* Print fetch message, if opt.verbose.  */
2543   if (opt.verbose)
2544     {
2545       logprintf (LOG_NOTQUIET, _("Saving to: %s\n"),
2546                  HYPHENP (hs->local_file) ? quote ("STDOUT") : quote (hs->local_file));
2547     }
2548
2549   /* This confuses the timestamping code that checks for file size.
2550      #### The timestamping code should be smarter about file size.  */
2551   if (opt.save_headers && hs->restval == 0)
2552     fwrite (head, 1, strlen (head), fp);
2553
2554   /* Now we no longer need to store the response header. */
2555   xfree (head);
2556
2557   /* Download the request body.  */
2558   flags = 0;
2559   if (contlen != -1)
2560     /* If content-length is present, read that much; otherwise, read
2561        until EOF.  The HTTP spec doesn't require the server to
2562        actually close the connection when it's done sending data. */
2563     flags |= rb_read_exactly;
2564   if (hs->restval > 0 && contrange == 0)
2565     /* If the server ignored our range request, instruct fd_read_body
2566        to skip the first RESTVAL bytes of body.  */
2567     flags |= rb_skip_startpos;
2568
2569   if (chunked_transfer_encoding)
2570     flags |= rb_chunked_transfer_encoding;
2571
2572   hs->len = hs->restval;
2573   hs->rd_size = 0;
2574   hs->res = fd_read_body (sock, fp, contlen != -1 ? contlen : 0,
2575                           hs->restval, &hs->rd_size, &hs->len, &hs->dltime,
2576                           flags);
2577
2578   if (hs->res >= 0)
2579     CLOSE_FINISH (sock);
2580   else
2581     {
2582       if (hs->res < 0)
2583         hs->rderrmsg = xstrdup (fd_errstr (sock));
2584       CLOSE_INVALIDATE (sock);
2585     }
2586
2587   if (!output_stream)
2588     fclose (fp);
2589   if (hs->res == -2)
2590     return FWRITEERR;
2591   return RETRFINISHED;
2592 }
2593
2594 /* The genuine HTTP loop!  This is the part where the retrieval is
2595    retried, and retried, and retried, and...  */
2596 uerr_t
2597 http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
2598            int *dt, struct url *proxy, struct iri *iri)
2599 {
2600   int count;
2601   bool got_head = false;         /* used for time-stamping and filename detection */
2602   bool time_came_from_head = false;
2603   bool got_name = false;
2604   char *tms;
2605   const char *tmrate;
2606   uerr_t err, ret = TRYLIMEXC;
2607   time_t tmr = -1;               /* remote time-stamp */
2608   struct http_stat hstat;        /* HTTP status */
2609   struct_stat st;
2610   bool send_head_first = true;
2611   char *file_name;
2612
2613   /* Assert that no value for *LOCAL_FILE was passed. */
2614   assert (local_file == NULL || *local_file == NULL);
2615
2616   /* Set LOCAL_FILE parameter. */
2617   if (local_file && opt.output_document)
2618     *local_file = HYPHENP (opt.output_document) ? NULL : xstrdup (opt.output_document);
2619
2620   /* Reset NEWLOC parameter. */
2621   *newloc = NULL;
2622
2623   /* This used to be done in main(), but it's a better idea to do it
2624      here so that we don't go through the hoops if we're just using
2625      FTP or whatever. */
2626   if (opt.cookies)
2627     load_cookies ();
2628
2629   /* Warn on (likely bogus) wildcard usage in HTTP. */
2630   if (opt.ftp_glob && has_wildcards_p (u->path))
2631     logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
2632
2633   /* Setup hstat struct. */
2634   xzero (hstat);
2635   hstat.referer = referer;
2636
2637   if (opt.output_document)
2638     {
2639       hstat.local_file = xstrdup (opt.output_document);
2640       got_name = true;
2641     }
2642   else if (!opt.content_disposition)
2643     {
2644       hstat.local_file = url_file_name (u);
2645       got_name = true;
2646     }
2647
2648   /* TODO: Ick! This code is now in both gethttp and http_loop, and is
2649    * screaming for some refactoring. */
2650   if (got_name && file_exists_p (hstat.local_file) && opt.noclobber && !opt.output_document)
2651     {
2652       /* If opt.noclobber is turned on and file already exists, do not
2653          retrieve the file. But if the output_document was given, then this
2654          test was already done and the file didn't exist. Hence the !opt.output_document */
2655       logprintf (LOG_VERBOSE, _("\
2656 File %s already there; not retrieving.\n\n"),
2657                  quote (hstat.local_file));
2658       /* If the file is there, we suppose it's retrieved OK.  */
2659       *dt |= RETROKF;
2660
2661       /* #### Bogusness alert.  */
2662       /* If its suffix is "html" or "htm" or similar, assume text/html.  */
2663       if (has_html_suffix_p (hstat.local_file))
2664         *dt |= TEXTHTML;
2665
2666       ret = RETROK;
2667       goto exit;
2668     }
2669
2670   /* Reset the counter. */
2671   count = 0;
2672
2673   /* Reset the document type. */
2674   *dt = 0;
2675
2676   /* Skip preliminary HEAD request if we're not in spider mode.  */
2677   if (!opt.spider)
2678     send_head_first = false;
2679
2680   /* Send preliminary HEAD request if -N is given and we have an existing
2681    * destination file. */
2682   file_name = url_file_name (u);
2683   if (opt.timestamping && file_exists_p (file_name))
2684     send_head_first = true;
2685   xfree (file_name);
2686
2687   /* THE loop */
2688   do
2689     {
2690       /* Increment the pass counter.  */
2691       ++count;
2692       sleep_between_retrievals (count);
2693
2694       /* Get the current time string.  */
2695       tms = datetime_str (time (NULL));
2696
2697       if (opt.spider && !got_head)
2698         logprintf (LOG_VERBOSE, _("\
2699 Spider mode enabled. Check if remote file exists.\n"));
2700
2701       /* Print fetch message, if opt.verbose.  */
2702       if (opt.verbose)
2703         {
2704           char *hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
2705
2706           if (count > 1)
2707             {
2708               char tmp[256];
2709               sprintf (tmp, _("(try:%2d)"), count);
2710               logprintf (LOG_NOTQUIET, "--%s--  %s  %s\n",
2711                          tms, tmp, hurl);
2712             }
2713           else
2714             {
2715               logprintf (LOG_NOTQUIET, "--%s--  %s\n",
2716                          tms, hurl);
2717             }
2718
2719 #ifdef WINDOWS
2720           ws_changetitle (hurl);
2721 #endif
2722           xfree (hurl);
2723         }
2724
2725       /* Default document type is empty.  However, if spider mode is
2726          on or time-stamping is employed, HEAD_ONLY commands is
2727          encoded within *dt.  */
2728       if (send_head_first && !got_head)
2729         *dt |= HEAD_ONLY;
2730       else
2731         *dt &= ~HEAD_ONLY;
2732
2733       /* Decide whether or not to restart.  */
2734       if (opt.always_rest
2735           && got_name
2736           && stat (hstat.local_file, &st) == 0
2737           && S_ISREG (st.st_mode))
2738         /* When -c is used, continue from on-disk size.  (Can't use
2739            hstat.len even if count>1 because we don't want a failed
2740            first attempt to clobber existing data.)  */
2741         hstat.restval = st.st_size;
2742       else if (count > 1)
2743         /* otherwise, continue where the previous try left off */
2744         hstat.restval = hstat.len;
2745       else
2746         hstat.restval = 0;
2747
2748       /* Decide whether to send the no-cache directive.  We send it in
2749          two cases:
2750            a) we're using a proxy, and we're past our first retrieval.
2751               Some proxies are notorious for caching incomplete data, so
2752               we require a fresh get.
2753            b) caching is explicitly inhibited. */
2754       if ((proxy && count > 1)        /* a */
2755           || !opt.allow_cache)        /* b */
2756         *dt |= SEND_NOCACHE;
2757       else
2758         *dt &= ~SEND_NOCACHE;
2759
2760       /* Try fetching the document, or at least its head.  */
2761       err = gethttp (u, &hstat, dt, proxy, iri);
2762
2763       /* Time?  */
2764       tms = datetime_str (time (NULL));
2765
2766       /* Get the new location (with or without the redirection).  */
2767       if (hstat.newloc)
2768         *newloc = xstrdup (hstat.newloc);
2769
2770       switch (err)
2771         {
2772         case HERR: case HEOF: case CONSOCKERR: case CONCLOSED:
2773         case CONERROR: case READERR: case WRITEFAILED:
2774         case RANGEERR: case FOPEN_EXCL_ERR:
2775           /* Non-fatal errors continue executing the loop, which will
2776              bring them to "while" statement at the end, to judge
2777              whether the number of tries was exceeded.  */
2778           printwhat (count, opt.ntry);
2779           continue;
2780         case FWRITEERR: case FOPENERR:
2781           /* Another fatal error.  */
2782           logputs (LOG_VERBOSE, "\n");
2783           logprintf (LOG_NOTQUIET, _("Cannot write to %s (%s).\n"),
2784                      quote (hstat.local_file), strerror (errno));
2785         case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case AUTHFAILED:
2786         case SSLINITFAILED: case CONTNOTSUPPORTED: case VERIFCERTERR:
2787           /* Fatal errors just return from the function.  */
2788           ret = err;
2789           goto exit;
2790         case CONSSLERR:
2791           /* Another fatal error.  */
2792           logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
2793           ret = err;
2794           goto exit;
2795         case NEWLOCATION:
2796           /* Return the new location to the caller.  */
2797           if (!*newloc)
2798             {
2799               logprintf (LOG_NOTQUIET,
2800                          _("ERROR: Redirection (%d) without location.\n"),
2801                          hstat.statcode);
2802               ret = WRONGCODE;
2803             }
2804           else
2805             {
2806               ret = NEWLOCATION;
2807             }
2808           goto exit;
2809         case RETRUNNEEDED:
2810           /* The file was already fully retrieved. */
2811           ret = RETROK;
2812           goto exit;
2813         case RETRFINISHED:
2814           /* Deal with you later.  */
2815           break;
2816         default:
2817           /* All possibilities should have been exhausted.  */
2818           abort ();
2819         }
2820
2821       if (!(*dt & RETROKF))
2822         {
2823           char *hurl = NULL;
2824           if (!opt.verbose)
2825             {
2826               /* #### Ugly ugly ugly! */
2827               hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
2828               logprintf (LOG_NONVERBOSE, "%s:\n", hurl);
2829             }
2830
2831           /* Fall back to GET if HEAD fails with a 500 or 501 error code. */
2832           if (*dt & HEAD_ONLY
2833               && (hstat.statcode == 500 || hstat.statcode == 501))
2834             {
2835               got_head = true;
2836               continue;
2837             }
2838           /* Maybe we should always keep track of broken links, not just in
2839            * spider mode.
2840            * Don't log error if it was UTF-8 encoded because we will try
2841            * once unencoded. */
2842           else if (opt.spider && !iri->utf8_encode)
2843             {
2844               /* #### Again: ugly ugly ugly! */
2845               if (!hurl)
2846                 hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
2847               nonexisting_url (hurl);
2848               logprintf (LOG_NOTQUIET, _("\
2849 Remote file does not exist -- broken link!!!\n"));
2850             }
2851           else
2852             {
2853               logprintf (LOG_NOTQUIET, _("%s ERROR %d: %s.\n"),
2854                          tms, hstat.statcode,
2855                          quotearg_style (escape_quoting_style, hstat.error));
2856             }
2857           logputs (LOG_VERBOSE, "\n");
2858           ret = WRONGCODE;
2859           xfree_null (hurl);
2860           goto exit;
2861         }
2862
2863       /* Did we get the time-stamp? */
2864       if (!got_head)
2865         {
2866           got_head = true;    /* no more time-stamping */
2867
2868           if (opt.timestamping && !hstat.remote_time)
2869             {
2870               logputs (LOG_NOTQUIET, _("\
2871 Last-modified header missing -- time-stamps turned off.\n"));
2872             }
2873           else if (hstat.remote_time)
2874             {
2875               /* Convert the date-string into struct tm.  */
2876               tmr = http_atotm (hstat.remote_time);
2877               if (tmr == (time_t) (-1))
2878                 logputs (LOG_VERBOSE, _("\
2879 Last-modified header invalid -- time-stamp ignored.\n"));
2880               if (*dt & HEAD_ONLY)
2881                 time_came_from_head = true;
2882             }
2883
2884           if (send_head_first)
2885             {
2886               /* The time-stamping section.  */
2887               if (opt.timestamping)
2888                 {
2889                   if (hstat.orig_file_name) /* Perform the following
2890                                                checks only if the file
2891                                                we're supposed to
2892                                                download already exists.  */
2893                     {
2894                       if (hstat.remote_time &&
2895                           tmr != (time_t) (-1))
2896                         {
2897                           /* Now time-stamping can be used validly.
2898                              Time-stamping means that if the sizes of
2899                              the local and remote file match, and local
2900                              file is newer than the remote file, it will
2901                              not be retrieved.  Otherwise, the normal
2902                              download procedure is resumed.  */
2903                           if (hstat.orig_file_tstamp >= tmr)
2904                             {
2905                               if (hstat.contlen == -1
2906                                   || hstat.orig_file_size == hstat.contlen)
2907                                 {
2908                                   logprintf (LOG_VERBOSE, _("\
2909 Server file no newer than local file %s -- not retrieving.\n\n"),
2910                                              quote (hstat.orig_file_name));
2911                                   ret = RETROK;
2912                                   goto exit;
2913                                 }
2914                               else
2915                                 {
2916                                   logprintf (LOG_VERBOSE, _("\
2917 The sizes do not match (local %s) -- retrieving.\n"),
2918                                              number_to_static_string (hstat.orig_file_size));
2919                                 }
2920                             }
2921                           else
2922                             logputs (LOG_VERBOSE,
2923                                      _("Remote file is newer, retrieving.\n"));
2924
2925                           logputs (LOG_VERBOSE, "\n");
2926                         }
2927                     }
2928
2929                   /* free_hstat (&hstat); */
2930                   hstat.timestamp_checked = true;
2931                 }
2932
2933               if (opt.spider)
2934                 {
2935                   bool finished = true;
2936                   if (opt.recursive)
2937                     {
2938                       if (*dt & TEXTHTML)
2939                         {
2940                           logputs (LOG_VERBOSE, _("\
2941 Remote file exists and could contain links to other resources -- retrieving.\n\n"));
2942                           finished = false;
2943                         }
2944                       else
2945                         {
2946                           logprintf (LOG_VERBOSE, _("\
2947 Remote file exists but does not contain any link -- not retrieving.\n\n"));
2948                           ret = RETROK; /* RETRUNNEEDED is not for caller. */
2949                         }
2950                     }
2951                   else
2952                     {
2953                       if (*dt & TEXTHTML)
2954                         {
2955                           logprintf (LOG_VERBOSE, _("\
2956 Remote file exists and could contain further links,\n\
2957 but recursion is disabled -- not retrieving.\n\n"));
2958                         }
2959                       else
2960                         {
2961                           logprintf (LOG_VERBOSE, _("\
2962 Remote file exists.\n\n"));
2963                         }
2964                       ret = RETROK; /* RETRUNNEEDED is not for caller. */
2965                     }
2966
2967                   if (finished)
2968                     {
2969                       logprintf (LOG_NONVERBOSE,
2970                                  _("%s URL: %s %2d %s\n"),
2971                                  tms, u->url, hstat.statcode,
2972                                  hstat.message ? quotearg_style (escape_quoting_style, hstat.message) : "");
2973                       goto exit;
2974                     }
2975                 }
2976
2977               got_name = true;
2978               *dt &= ~HEAD_ONLY;
2979               count = 0;          /* the retrieve count for HEAD is reset */
2980               continue;
2981             } /* send_head_first */
2982         } /* !got_head */
2983
2984       if (opt.useservertimestamps
2985           && (tmr != (time_t) (-1))
2986           && ((hstat.len == hstat.contlen) ||
2987               ((hstat.res == 0) && (hstat.contlen == -1))))
2988         {
2989           const char *fl = NULL;
2990           set_local_file (&fl, hstat.local_file);
2991           if (fl)
2992             {
2993               time_t newtmr = -1;
2994               /* Reparse time header, in case it's changed. */
2995               if (time_came_from_head
2996                   && hstat.remote_time && hstat.remote_time[0])
2997                 {
2998                   newtmr = http_atotm (hstat.remote_time);
2999                   if (newtmr != (time_t)-1)
3000                     tmr = newtmr;
3001                 }
3002               touch (fl, tmr);
3003             }
3004         }
3005       /* End of time-stamping section. */
3006
3007       tmrate = retr_rate (hstat.rd_size, hstat.dltime);
3008       total_download_time += hstat.dltime;
3009
3010       if (hstat.len == hstat.contlen)
3011         {
3012           if (*dt & RETROKF)
3013             {
3014               bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document));
3015
3016               logprintf (LOG_VERBOSE,
3017                          write_to_stdout
3018                          ? _("%s (%s) - written to stdout %s[%s/%s]\n\n")
3019                          : _("%s (%s) - %s saved [%s/%s]\n\n"),
3020                          tms, tmrate,
3021                          write_to_stdout ? "" : quote (hstat.local_file),
3022                          number_to_static_string (hstat.len),
3023                          number_to_static_string (hstat.contlen));
3024               logprintf (LOG_NONVERBOSE,
3025                          "%s URL:%s [%s/%s] -> \"%s\" [%d]\n",
3026                          tms, u->url,
3027                          number_to_static_string (hstat.len),
3028                          number_to_static_string (hstat.contlen),
3029                          hstat.local_file, count);
3030             }
3031           ++numurls;
3032           total_downloaded_bytes += hstat.len;
3033
3034           /* Remember that we downloaded the file for later ".orig" code. */
3035           if (*dt & ADDED_HTML_EXTENSION)
3036             downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, hstat.local_file);
3037           else
3038             downloaded_file(FILE_DOWNLOADED_NORMALLY, hstat.local_file);
3039
3040           ret = RETROK;
3041           goto exit;
3042         }
3043       else if (hstat.res == 0) /* No read error */
3044         {
3045           if (hstat.contlen == -1)  /* We don't know how much we were supposed
3046                                        to get, so assume we succeeded. */
3047             {
3048               if (*dt & RETROKF)
3049                 {
3050                   bool write_to_stdout = (opt.output_document && HYPHENP (opt.output_document));
3051
3052                   logprintf (LOG_VERBOSE,
3053                              write_to_stdout
3054                              ? _("%s (%s) - written to stdout %s[%s]\n\n")
3055                              : _("%s (%s) - %s saved [%s]\n\n"),
3056                              tms, tmrate,
3057                              write_to_stdout ? "" : quote (hstat.local_file),
3058                              number_to_static_string (hstat.len));
3059                   logprintf (LOG_NONVERBOSE,
3060                              "%s URL:%s [%s] -> \"%s\" [%d]\n",
3061                              tms, u->url, number_to_static_string (hstat.len),
3062                              hstat.local_file, count);
3063                 }
3064               ++numurls;
3065               total_downloaded_bytes += hstat.len;
3066
3067               /* Remember that we downloaded the file for later ".orig" code. */
3068               if (*dt & ADDED_HTML_EXTENSION)
3069                 downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, hstat.local_file);
3070               else
3071                 downloaded_file(FILE_DOWNLOADED_NORMALLY, hstat.local_file);
3072
3073               ret = RETROK;
3074               goto exit;
3075             }
3076           else if (hstat.len < hstat.contlen) /* meaning we lost the
3077                                                  connection too soon */
3078             {
3079               logprintf (LOG_VERBOSE,
3080                          _("%s (%s) - Connection closed at byte %s. "),
3081                          tms, tmrate, number_to_static_string (hstat.len));
3082               printwhat (count, opt.ntry);
3083               continue;
3084             }
3085           else if (hstat.len != hstat.restval)
3086             /* Getting here would mean reading more data than
3087                requested with content-length, which we never do.  */
3088             abort ();
3089           else
3090             {
3091               /* Getting here probably means that the content-length was
3092                * _less_ than the original, local size. We should probably
3093                * truncate or re-read, or something. FIXME */
3094               ret = RETROK;
3095               goto exit;
3096             }
3097         }
3098       else /* from now on hstat.res can only be -1 */
3099         {
3100           if (hstat.contlen == -1)
3101             {
3102               logprintf (LOG_VERBOSE,
3103                          _("%s (%s) - Read error at byte %s (%s)."),
3104                          tms, tmrate, number_to_static_string (hstat.len),
3105                          hstat.rderrmsg);
3106               printwhat (count, opt.ntry);
3107               continue;
3108             }
3109           else /* hstat.res == -1 and contlen is given */
3110             {
3111               logprintf (LOG_VERBOSE,
3112                          _("%s (%s) - Read error at byte %s/%s (%s). "),
3113                          tms, tmrate,
3114                          number_to_static_string (hstat.len),
3115                          number_to_static_string (hstat.contlen),
3116                          hstat.rderrmsg);
3117               printwhat (count, opt.ntry);
3118               continue;
3119             }
3120         }
3121       /* not reached */
3122     }
3123   while (!opt.ntry || (count < opt.ntry));
3124
3125 exit:
3126   if (ret == RETROK)
3127     *local_file = xstrdup (hstat.local_file);
3128   free_hstat (&hstat);
3129
3130   return ret;
3131 }
3132 \f
3133 /* Check whether the result of strptime() indicates success.
3134    strptime() returns the pointer to how far it got to in the string.
3135    The processing has been successful if the string is at `GMT' or
3136    `+X', or at the end of the string.
3137
3138    In extended regexp parlance, the function returns 1 if P matches
3139    "^ *(GMT|[+-][0-9]|$)", 0 otherwise.  P being NULL (which strptime
3140    can return) is considered a failure and 0 is returned.  */
3141 static bool
3142 check_end (const char *p)
3143 {
3144   if (!p)
3145     return false;
3146   while (c_isspace (*p))
3147     ++p;
3148   if (!*p
3149       || (p[0] == 'G' && p[1] == 'M' && p[2] == 'T')
3150       || ((p[0] == '+' || p[0] == '-') && c_isdigit (p[1])))
3151     return true;
3152   else
3153     return false;
3154 }
3155
3156 /* Convert the textual specification of time in TIME_STRING to the
3157    number of seconds since the Epoch.
3158
3159    TIME_STRING can be in any of the three formats RFC2616 allows the
3160    HTTP servers to emit -- RFC1123-date, RFC850-date or asctime-date,
3161    as well as the time format used in the Set-Cookie header.
3162    Timezones are ignored, and should be GMT.
3163
3164    Return the computed time_t representation, or -1 if the conversion
3165    fails.
3166
3167    This function uses strptime with various string formats for parsing
3168    TIME_STRING.  This results in a parser that is not as lenient in
3169    interpreting TIME_STRING as I would like it to be.  Being based on
3170    strptime, it always allows shortened months, one-digit days, etc.,
3171    but due to the multitude of formats in which time can be
3172    represented, an ideal HTTP time parser would be even more
3173    forgiving.  It should completely ignore things like week days and
3174    concentrate only on the various forms of representing years,
3175    months, days, hours, minutes, and seconds.  For example, it would
3176    be nice if it accepted ISO 8601 out of the box.
3177
3178    I've investigated free and PD code for this purpose, but none was
3179    usable.  getdate was big and unwieldy, and had potential copyright
3180    issues, or so I was informed.  Dr. Marcus Hennecke's atotm(),
3181    distributed with phttpd, is excellent, but we cannot use it because
3182    it is not assigned to the FSF.  So I stuck it with strptime.  */
3183
3184 time_t
3185 http_atotm (const char *time_string)
3186 {
3187   /* NOTE: Solaris strptime man page claims that %n and %t match white
3188      space, but that's not universally available.  Instead, we simply
3189      use ` ' to mean "skip all WS", which works under all strptime
3190      implementations I've tested.  */
3191
3192   static const char *time_formats[] = {
3193     "%a, %d %b %Y %T",          /* rfc1123: Thu, 29 Jan 1998 22:12:57 */
3194     "%A, %d-%b-%y %T",          /* rfc850:  Thursday, 29-Jan-98 22:12:57 */
3195     "%a %b %d %T %Y",           /* asctime: Thu Jan 29 22:12:57 1998 */
3196     "%a, %d-%b-%Y %T"           /* cookies: Thu, 29-Jan-1998 22:12:57
3197                                    (used in Set-Cookie, defined in the
3198                                    Netscape cookie specification.) */
3199   };
3200   const char *oldlocale;
3201   char savedlocale[256];
3202   size_t i;
3203   time_t ret = (time_t) -1;
3204
3205   /* Solaris strptime fails to recognize English month names in
3206      non-English locales, which we work around by temporarily setting
3207      locale to C before invoking strptime.  */
3208   oldlocale = setlocale (LC_TIME, NULL);
3209   if (oldlocale)
3210     {
3211       size_t l = strlen (oldlocale) + 1;
3212       if (l >= sizeof savedlocale)
3213         savedlocale[0] = '\0';
3214       else
3215         memcpy (savedlocale, oldlocale, l);
3216     }
3217   else savedlocale[0] = '\0';
3218
3219   setlocale (LC_TIME, "C");
3220
3221   for (i = 0; i < countof (time_formats); i++)
3222     {
3223       struct tm t;
3224
3225       /* Some versions of strptime use the existing contents of struct
3226          tm to recalculate the date according to format.  Zero it out
3227          to prevent stack garbage from influencing strptime.  */
3228       xzero (t);
3229
3230       if (check_end (strptime (time_string, time_formats[i], &t)))
3231         {
3232           ret = timegm (&t);
3233           break;
3234         }
3235     }
3236
3237   /* Restore the previous locale. */
3238   if (savedlocale[0])
3239     setlocale (LC_TIME, savedlocale);
3240
3241   return ret;
3242 }
3243 \f
3244 /* Authorization support: We support three authorization schemes:
3245
3246    * `Basic' scheme, consisting of base64-ing USER:PASSWORD string;
3247
3248    * `Digest' scheme, added by Junio Hamano <junio@twinsun.com>,
3249    consisting of answering to the server's challenge with the proper
3250    MD5 digests.
3251
3252    * `NTLM' ("NT Lan Manager") scheme, based on code written by Daniel
3253    Stenberg for libcurl.  Like digest, NTLM is based on a
3254    challenge-response mechanism, but unlike digest, it is non-standard
3255    (authenticates TCP connections rather than requests), undocumented
3256    and Microsoft-specific.  */
3257
3258 /* Create the authentication header contents for the `Basic' scheme.
3259    This is done by encoding the string "USER:PASS" to base64 and
3260    prepending the string "Basic " in front of it.  */
3261
3262 static char *
3263 basic_authentication_encode (const char *user, const char *passwd)
3264 {
3265   char *t1, *t2;
3266   int len1 = strlen (user) + 1 + strlen (passwd);
3267
3268   t1 = (char *)alloca (len1 + 1);
3269   sprintf (t1, "%s:%s", user, passwd);
3270
3271   t2 = (char *)alloca (BASE64_LENGTH (len1) + 1);
3272   base64_encode (t1, len1, t2);
3273
3274   return concat_strings ("Basic ", t2, (char *) 0);
3275 }
3276
3277 #define SKIP_WS(x) do {                         \
3278   while (c_isspace (*(x)))                        \
3279     ++(x);                                      \
3280 } while (0)
3281
3282 #ifdef ENABLE_DIGEST
3283 /* Dump the hexadecimal representation of HASH to BUF.  HASH should be
3284    an array of 16 bytes containing the hash keys, and BUF should be a
3285    buffer of 33 writable characters (32 for hex digits plus one for
3286    zero termination).  */
3287 static void
3288 dump_hash (char *buf, const unsigned char *hash)
3289 {
3290   int i;
3291
3292   for (i = 0; i < MD5_DIGEST_SIZE; i++, hash++)
3293     {
3294       *buf++ = XNUM_TO_digit (*hash >> 4);
3295       *buf++ = XNUM_TO_digit (*hash & 0xf);
3296     }
3297   *buf = '\0';
3298 }
3299
3300 /* Take the line apart to find the challenge, and compose a digest
3301    authorization header.  See RFC2069 section 2.1.2.  */
3302 static char *
3303 digest_authentication_encode (const char *au, const char *user,
3304                               const char *passwd, const char *method,
3305                               const char *path)
3306 {
3307   static char *realm, *opaque, *nonce;
3308   static struct {
3309     const char *name;
3310     char **variable;
3311   } options[] = {
3312     { "realm", &realm },
3313     { "opaque", &opaque },
3314     { "nonce", &nonce }
3315   };
3316   char *res;
3317   param_token name, value;
3318
3319   realm = opaque = nonce = NULL;
3320
3321   au += 6;                      /* skip over `Digest' */
3322   while (extract_param (&au, &name, &value, ','))
3323     {
3324       size_t i;
3325       size_t namelen = name.e - name.b;
3326       for (i = 0; i < countof (options); i++)
3327         if (namelen == strlen (options[i].name)
3328             && 0 == strncmp (name.b, options[i].name,
3329                              namelen))
3330           {
3331             *options[i].variable = strdupdelim (value.b, value.e);
3332             break;
3333           }
3334     }
3335   if (!realm || !nonce || !user || !passwd || !path || !method)
3336     {
3337       xfree_null (realm);
3338       xfree_null (opaque);
3339       xfree_null (nonce);
3340       return NULL;
3341     }
3342
3343   /* Calculate the digest value.  */
3344   {
3345     struct md5_ctx ctx;
3346     unsigned char hash[MD5_DIGEST_SIZE];
3347     char a1buf[MD5_DIGEST_SIZE * 2 + 1], a2buf[MD5_DIGEST_SIZE * 2 + 1];
3348     char response_digest[MD5_DIGEST_SIZE * 2 + 1];
3349
3350     /* A1BUF = H(user ":" realm ":" password) */
3351     md5_init_ctx (&ctx);
3352     md5_process_bytes ((unsigned char *)user, strlen (user), &ctx);
3353     md5_process_bytes ((unsigned char *)":", 1, &ctx);
3354     md5_process_bytes ((unsigned char *)realm, strlen (realm), &ctx);
3355     md5_process_bytes ((unsigned char *)":", 1, &ctx);
3356     md5_process_bytes ((unsigned char *)passwd, strlen (passwd), &ctx);
3357     md5_finish_ctx (&ctx, hash);
3358     dump_hash (a1buf, hash);
3359
3360     /* A2BUF = H(method ":" path) */
3361     md5_init_ctx (&ctx);
3362     md5_process_bytes ((unsigned char *)method, strlen (method), &ctx);
3363     md5_process_bytes ((unsigned char *)":", 1, &ctx);
3364     md5_process_bytes ((unsigned char *)path, strlen (path), &ctx);
3365     md5_finish_ctx (&ctx, hash);
3366     dump_hash (a2buf, hash);
3367
3368     /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */
3369     md5_init_ctx (&ctx);
3370     md5_process_bytes ((unsigned char *)a1buf, MD5_DIGEST_SIZE * 2, &ctx);
3371     md5_process_bytes ((unsigned char *)":", 1, &ctx);
3372     md5_process_bytes ((unsigned char *)nonce, strlen (nonce), &ctx);
3373     md5_process_bytes ((unsigned char *)":", 1, &ctx);
3374     md5_process_bytes ((unsigned char *)a2buf, MD5_DIGEST_SIZE * 2, &ctx);
3375     md5_finish_ctx (&ctx, hash);
3376     dump_hash (response_digest, hash);
3377
3378     res = xmalloc (strlen (user)
3379                    + strlen (user)
3380                    + strlen (realm)
3381                    + strlen (nonce)
3382                    + strlen (path)
3383                    + 2 * MD5_DIGEST_SIZE /*strlen (response_digest)*/
3384                    + (opaque ? strlen (opaque) : 0)
3385                    + 128);
3386     sprintf (res, "Digest \
3387 username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
3388              user, realm, nonce, path, response_digest);
3389     if (opaque)
3390       {
3391         char *p = res + strlen (res);
3392         strcat (p, ", opaque=\"");
3393         strcat (p, opaque);
3394         strcat (p, "\"");
3395       }
3396   }
3397   return res;
3398 }
3399 #endif /* ENABLE_DIGEST */
3400
3401 /* Computing the size of a string literal must take into account that
3402    value returned by sizeof includes the terminating \0.  */
3403 #define STRSIZE(literal) (sizeof (literal) - 1)
3404
3405 /* Whether chars in [b, e) begin with the literal string provided as
3406    first argument and are followed by whitespace or terminating \0.
3407    The comparison is case-insensitive.  */
3408 #define STARTS(literal, b, e)                           \
3409   ((e > b) \
3410    && ((size_t) ((e) - (b))) >= STRSIZE (literal)   \
3411    && 0 == strncasecmp (b, literal, STRSIZE (literal))  \
3412    && ((size_t) ((e) - (b)) == STRSIZE (literal)          \
3413        || c_isspace (b[STRSIZE (literal)])))
3414
3415 static bool
3416 known_authentication_scheme_p (const char *hdrbeg, const char *hdrend)
3417 {
3418   return STARTS ("Basic", hdrbeg, hdrend)
3419 #ifdef ENABLE_DIGEST
3420     || STARTS ("Digest", hdrbeg, hdrend)
3421 #endif
3422 #ifdef ENABLE_NTLM
3423     || STARTS ("NTLM", hdrbeg, hdrend)
3424 #endif
3425     ;
3426 }
3427
3428 #undef STARTS
3429
3430 /* Create the HTTP authorization request header.  When the
3431    `WWW-Authenticate' response header is seen, according to the
3432    authorization scheme specified in that header (`Basic' and `Digest'
3433    are supported by the current implementation), produce an
3434    appropriate HTTP authorization request header.  */
3435 static char *
3436 create_authorization_line (const char *au, const char *user,
3437                            const char *passwd, const char *method,
3438                            const char *path, bool *finished)
3439 {
3440   /* We are called only with known schemes, so we can dispatch on the
3441      first letter. */
3442   switch (c_toupper (*au))
3443     {
3444     case 'B':                   /* Basic */
3445       *finished = true;
3446       return basic_authentication_encode (user, passwd);
3447 #ifdef ENABLE_DIGEST
3448     case 'D':                   /* Digest */
3449       *finished = true;
3450       return digest_authentication_encode (au, user, passwd, method, path);
3451 #endif
3452 #ifdef ENABLE_NTLM
3453     case 'N':                   /* NTLM */
3454       if (!ntlm_input (&pconn.ntlm, au))
3455         {
3456           *finished = true;
3457           return NULL;
3458         }
3459       return ntlm_output (&pconn.ntlm, user, passwd, finished);
3460 #endif
3461     default:
3462       /* We shouldn't get here -- this function should be only called
3463          with values approved by known_authentication_scheme_p.  */
3464       abort ();
3465     }
3466 }
3467 \f
3468 static void
3469 load_cookies (void)
3470 {
3471   if (!wget_cookie_jar)
3472     wget_cookie_jar = cookie_jar_new ();
3473   if (opt.cookies_input && !cookies_loaded_p)
3474     {
3475       cookie_jar_load (wget_cookie_jar, opt.cookies_input);
3476       cookies_loaded_p = true;
3477     }
3478 }
3479
3480 void
3481 save_cookies (void)
3482 {
3483   if (wget_cookie_jar)
3484     cookie_jar_save (wget_cookie_jar, opt.cookies_output);
3485 }
3486
3487 void
3488 http_cleanup (void)
3489 {
3490   xfree_null (pconn.host);
3491   if (wget_cookie_jar)
3492     cookie_jar_delete (wget_cookie_jar);
3493 }
3494
3495 void
3496 ensure_extension (struct http_stat *hs, const char *ext, int *dt)
3497 {
3498   char *last_period_in_local_filename = strrchr (hs->local_file, '.');
3499   char shortext[8];
3500   int len = strlen (ext);
3501   if (len == 5)
3502     {
3503       strncpy (shortext, ext, len - 1);
3504       shortext[len - 2] = '\0';
3505     }
3506
3507   if (last_period_in_local_filename == NULL
3508       || !(0 == strcasecmp (last_period_in_local_filename, shortext)
3509            || 0 == strcasecmp (last_period_in_local_filename, ext)))
3510     {
3511       int local_filename_len = strlen (hs->local_file);
3512       /* Resize the local file, allowing for ".html" preceded by
3513          optional ".NUMBER".  */
3514       hs->local_file = xrealloc (hs->local_file,
3515                                  local_filename_len + 24 + len);
3516       strcpy (hs->local_file + local_filename_len, ext);
3517       /* If clobbering is not allowed and the file, as named,
3518          exists, tack on ".NUMBER.html" instead. */
3519       if (!ALLOW_CLOBBER && file_exists_p (hs->local_file))
3520         {
3521           int ext_num = 1;
3522           do
3523             sprintf (hs->local_file + local_filename_len,
3524                      ".%d%s", ext_num++, ext);
3525           while (file_exists_p (hs->local_file));
3526         }
3527       *dt |= ADDED_HTML_EXTENSION;
3528     }
3529 }
3530
3531
3532 #ifdef TESTING
3533
3534 const char *
3535 test_parse_content_disposition()
3536 {
3537   int i;
3538   struct {
3539     char *hdrval;
3540     char *opt_dir_prefix;
3541     char *filename;
3542     bool result;
3543   } test_array[] = {
3544     { "filename=\"file.ext\"", NULL, "file.ext", true },
3545     { "filename=\"file.ext\"", "somedir", "somedir/file.ext", true },
3546     { "attachment; filename=\"file.ext\"", NULL, "file.ext", true },
3547     { "attachment; filename=\"file.ext\"", "somedir", "somedir/file.ext", true },
3548     { "attachment; filename=\"file.ext\"; dummy", NULL, "file.ext", true },
3549     { "attachment; filename=\"file.ext\"; dummy", "somedir", "somedir/file.ext", true },
3550     { "attachment", NULL, NULL, false },
3551     { "attachment", "somedir", NULL, false },
3552     { "attachement; filename*=UTF-8'en-US'hello.txt", NULL, "hello.txt", true },
3553     { "attachement; filename*0=\"hello\"; filename*1=\"world.txt\"", NULL, "helloworld.txt", true },
3554   };
3555
3556   for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i)
3557     {
3558       char *filename;
3559       bool res;
3560
3561       opt.dir_prefix = test_array[i].opt_dir_prefix;
3562       res = parse_content_disposition (test_array[i].hdrval, &filename);
3563
3564       mu_assert ("test_parse_content_disposition: wrong result",
3565                  res == test_array[i].result
3566                  && (res == false
3567                      || 0 == strcmp (test_array[i].filename, filename)));
3568     }
3569
3570   return NULL;
3571 }
3572
3573 #endif /* TESTING */
3574
3575 /*
3576  * vim: et sts=2 sw=2 cino+={s
3577  */
3578