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