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