]> sjero.net Git - wget/blob - src/retr.c
[svn] Get rid of ssl_iread/ssl_iwrite. Have the SSL code register its
[wget] / src / retr.c
1 /* File retrieval.
2    Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
10
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables.  You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL".  If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so.  If you do not wish to do
28 so, delete this exception statement from your version.  */
29
30 #include <config.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif /* HAVE_UNISTD_H */
38 #include <errno.h>
39 #ifdef HAVE_STRING_H
40 # include <string.h>
41 #else
42 # include <strings.h>
43 #endif /* HAVE_STRING_H */
44 #include <assert.h>
45
46 #include "wget.h"
47 #include "utils.h"
48 #include "retr.h"
49 #include "progress.h"
50 #include "url.h"
51 #include "recur.h"
52 #include "ftp.h"
53 #include "host.h"
54 #include "connect.h"
55 #include "hash.h"
56 #include "convert.h"
57
58 #ifdef HAVE_SSL
59 # include "gen_sslfunc.h"       /* for ssl_iread */
60 #endif
61
62 #ifndef errno
63 extern int errno;
64 #endif
65
66 /* See the comment in gethttp() why this is needed. */
67 int global_download_count;
68
69 /* Total size of downloaded files.  Used to enforce quota.  */
70 LARGE_INT total_downloaded_bytes;
71
72 \f
73 static struct {
74   long chunk_bytes;
75   double chunk_start;
76   double sleep_adjust;
77 } limit_data;
78
79 static void
80 limit_bandwidth_reset (void)
81 {
82   limit_data.chunk_bytes = 0;
83   limit_data.chunk_start = 0;
84 }
85
86 /* Limit the bandwidth by pausing the download for an amount of time.
87    BYTES is the number of bytes received from the network, and DELTA
88    is the number of milliseconds it took to receive them.  */
89
90 static void
91 limit_bandwidth (long bytes, double *dltime, struct wget_timer *timer)
92 {
93   double delta_t = *dltime - limit_data.chunk_start;
94   double expected;
95
96   limit_data.chunk_bytes += bytes;
97
98   /* Calculate the amount of time we expect downloading the chunk
99      should take.  If in reality it took less time, sleep to
100      compensate for the difference.  */
101   expected = 1000.0 * limit_data.chunk_bytes / opt.limit_rate;
102
103   if (expected > delta_t)
104     {
105       double slp = expected - delta_t + limit_data.sleep_adjust;
106       double t0, t1;
107       if (slp < 200)
108         {
109           DEBUGP (("deferring a %.2f ms sleep (%ld/%.2f).\n",
110                    slp, limit_data.chunk_bytes, delta_t));
111           return;
112         }
113       DEBUGP (("\nsleeping %.2f ms for %ld bytes, adjust %.2f ms\n",
114                slp, limit_data.chunk_bytes, limit_data.sleep_adjust));
115
116       t0 = *dltime;
117       xsleep (slp / 1000);
118       t1 = wtimer_elapsed (timer);
119
120       /* Due to scheduling, we probably slept slightly longer (or
121          shorter) than desired.  Calculate the difference between the
122          desired and the actual sleep, and adjust the next sleep by
123          that amount.  */
124       limit_data.sleep_adjust = slp - (t1 - t0);
125
126       /* Since we've called wtimer_elapsed, we might as well update
127          the caller's dltime. */
128       *dltime = t1;
129     }
130
131   limit_data.chunk_bytes = 0;
132   limit_data.chunk_start = *dltime;
133 }
134
135 #define MIN(i, j) ((i) <= (j) ? (i) : (j))
136
137 /* Reads the contents of file descriptor FD, until it is closed, or a
138    read error occurs.  The data is read in 8K chunks, and stored to
139    stream fp, which should have been open for writing.  If BUF is
140    non-NULL and its file descriptor is equal to FD, flush RBUF first.
141    This function will *not* use the rbuf_* functions!
142
143    The EXPECTED argument is passed to show_progress() unchanged, but
144    otherwise ignored.
145
146    If opt.verbose is set, the progress is also shown.  RESTVAL
147    represents a value from which to start downloading (which will be
148    shown accordingly).  If RESTVAL is non-zero, the stream should have
149    been open for appending.
150
151    The function exits and returns codes of 0, -1 and -2 if the
152    connection was closed, there was a read error, or if it could not
153    write to the output stream, respectively.
154
155    IMPORTANT: The function flushes the contents of the buffer in
156    rbuf_flush() before actually reading from fd.  If you wish to read
157    from fd immediately, flush or discard the buffer.  */
158 int
159 get_contents (int fd, FILE *fp, long *len, long restval, long expected,
160               struct rbuf *rbuf, int use_expected, double *elapsed)
161 {
162   int res = 0;
163
164   static char dlbuf[16384];
165   int dlbufsize = sizeof (dlbuf);
166
167   void *progress = NULL;
168   struct wget_timer *timer = wtimer_allocate ();
169   double dltime = 0;
170
171   *len = restval;
172
173   if (opt.verbose)
174     progress = progress_create (restval, expected);
175
176   if (rbuf && RBUF_FD (rbuf) == fd)
177     {
178       int sz = 0;
179       while ((res = rbuf_flush (rbuf, dlbuf, sizeof (dlbuf))) != 0)
180         {
181           fwrite (dlbuf, 1, res, fp);
182           *len += res;
183           sz += res;
184         }
185       if (sz)
186         fflush (fp);
187       if (ferror (fp))
188         {
189           res = -2;
190           goto out;
191         }
192       if (progress)
193         progress_update (progress, sz, 0);
194     }
195
196   if (opt.limit_rate)
197     limit_bandwidth_reset ();
198   wtimer_reset (timer);
199
200   /* Use a smaller buffer for low requested bandwidths.  For example,
201      with --limit-rate=2k, it doesn't make sense to slurp in 16K of
202      data and then sleep for 8s.  With buffer size equal to the limit,
203      we never have to sleep for more than one second.  */
204   if (opt.limit_rate && opt.limit_rate < dlbufsize)
205     dlbufsize = opt.limit_rate;
206
207   /* Read from fd while there is available data.
208
209      Normally, if expected is 0, it means that it is not known how
210      much data is expected.  However, if use_expected is specified,
211      then expected being zero means exactly that.  */
212   while (!use_expected || (*len < expected))
213     {
214       int amount_to_read = (use_expected
215                             ? MIN (expected - *len, dlbufsize) : dlbufsize);
216       res = xread (fd, dlbuf, amount_to_read, -1);
217
218       if (res <= 0)
219         break;
220
221       fwrite (dlbuf, 1, res, fp);
222       /* Always flush the contents of the network packet.  This should
223          not hinder performance: fast downloads will be received in
224          16K chunks (which stdio would write out anyway), and slow
225          downloads won't be limited with disk performance.  */
226       fflush (fp);
227       if (ferror (fp))
228         {
229           res = -2;
230           goto out;
231         }
232
233       dltime = wtimer_elapsed (timer);
234       if (opt.limit_rate)
235         limit_bandwidth (res, &dltime, timer);
236
237       *len += res;
238       if (progress)
239         progress_update (progress, res, dltime);
240 #ifdef WINDOWS
241       if (use_expected && expected > 0)
242         ws_percenttitle (100.0 * (double)(*len) / (double)expected);
243 #endif
244     }
245   if (res < -1)
246     res = -1;
247
248  out:
249   if (progress)
250     progress_finish (progress, dltime);
251   if (elapsed)
252     *elapsed = dltime;
253   wtimer_delete (timer);
254
255   return res;
256 }
257 \f
258 /* Return a printed representation of the download rate, as
259    appropriate for the speed.  If PAD is non-zero, strings will be
260    padded to the width of 7 characters (xxxx.xx).  */
261 char *
262 retr_rate (long bytes, double msecs, int pad)
263 {
264   static char res[20];
265   static char *rate_names[] = {"B/s", "KB/s", "MB/s", "GB/s" };
266   int units = 0;
267
268   double dlrate = calc_rate (bytes, msecs, &units);
269   sprintf (res, pad ? "%7.2f %s" : "%.2f %s", dlrate, rate_names[units]);
270
271   return res;
272 }
273
274 /* Calculate the download rate and trim it as appropriate for the
275    speed.  Appropriate means that if rate is greater than 1K/s,
276    kilobytes are used, and if rate is greater than 1MB/s, megabytes
277    are used.
278
279    UNITS is zero for B/s, one for KB/s, two for MB/s, and three for
280    GB/s.  */
281 double
282 calc_rate (long bytes, double msecs, int *units)
283 {
284   double dlrate;
285
286   assert (msecs >= 0);
287   assert (bytes >= 0);
288
289   if (msecs == 0)
290     /* If elapsed time is exactly zero, it means we're under the
291        granularity of the timer.  This often happens on systems that
292        use time() for the timer.  */
293     msecs = wtimer_granularity ();
294
295   dlrate = (double)1000 * bytes / msecs;
296   if (dlrate < 1024.0)
297     *units = 0;
298   else if (dlrate < 1024.0 * 1024.0)
299     *units = 1, dlrate /= 1024.0;
300   else if (dlrate < 1024.0 * 1024.0 * 1024.0)
301     *units = 2, dlrate /= (1024.0 * 1024.0);
302   else
303     /* Maybe someone will need this, one day. */
304     *units = 3, dlrate /= (1024.0 * 1024.0 * 1024.0);
305
306   return dlrate;
307 }
308 \f
309 /* Maximum number of allowed redirections.  20 was chosen as a
310    "reasonable" value, which is low enough to not cause havoc, yet
311    high enough to guarantee that normal retrievals will not be hurt by
312    the check.  */
313
314 #define MAX_REDIRECTIONS 20
315
316 #define SUSPEND_POST_DATA do {                  \
317   post_data_suspended = 1;                      \
318   saved_post_data = opt.post_data;              \
319   saved_post_file_name = opt.post_file_name;    \
320   opt.post_data = NULL;                         \
321   opt.post_file_name = NULL;                    \
322 } while (0)
323
324 #define RESTORE_POST_DATA do {                          \
325   if (post_data_suspended)                              \
326     {                                                   \
327       opt.post_data = saved_post_data;                  \
328       opt.post_file_name = saved_post_file_name;        \
329       post_data_suspended = 0;                          \
330     }                                                   \
331 } while (0)
332
333 static char *getproxy PARAMS ((struct url *));
334
335 /* Retrieve the given URL.  Decides which loop to call -- HTTP, FTP,
336    FTP, proxy, etc.  */
337
338 /* #### This function should be rewritten so it doesn't return from
339    multiple points. */
340
341 uerr_t
342 retrieve_url (const char *origurl, char **file, char **newloc,
343               const char *refurl, int *dt)
344 {
345   uerr_t result;
346   char *url;
347   int location_changed, dummy;
348   char *mynewloc, *proxy;
349   struct url *u, *proxy_url;
350   int up_error_code;            /* url parse error code */
351   char *local_file;
352   int redirection_count = 0;
353
354   int post_data_suspended = 0;
355   char *saved_post_data = NULL;
356   char *saved_post_file_name = NULL;
357
358   /* If dt is NULL, use local storage.  */
359   if (!dt)
360     {
361       dt = &dummy;
362       dummy = 0;
363     }
364   url = xstrdup (origurl);
365   if (newloc)
366     *newloc = NULL;
367   if (file)
368     *file = NULL;
369
370   u = url_parse (url, &up_error_code);
371   if (!u)
372     {
373       logprintf (LOG_NOTQUIET, "%s: %s.\n", url, url_error (up_error_code));
374       xfree (url);
375       return URLERROR;
376     }
377
378   if (!refurl)
379     refurl = opt.referer;
380
381  redirected:
382
383   result = NOCONERROR;
384   mynewloc = NULL;
385   local_file = NULL;
386   proxy_url = NULL;
387
388   proxy = getproxy (u);
389   if (proxy)
390     {
391       /* Parse the proxy URL.  */
392       proxy_url = url_parse (proxy, &up_error_code);
393       if (!proxy_url)
394         {
395           logprintf (LOG_NOTQUIET, _("Error parsing proxy URL %s: %s.\n"),
396                      proxy, url_error (up_error_code));
397           xfree (url);
398           RESTORE_POST_DATA;
399           return PROXERR;
400         }
401       if (proxy_url->scheme != SCHEME_HTTP && proxy_url->scheme != u->scheme)
402         {
403           logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy);
404           url_free (proxy_url);
405           xfree (url);
406           RESTORE_POST_DATA;
407           return PROXERR;
408         }
409     }
410
411   if (u->scheme == SCHEME_HTTP
412 #ifdef HAVE_SSL
413       || u->scheme == SCHEME_HTTPS
414 #endif
415       || (proxy_url && proxy_url->scheme == SCHEME_HTTP))
416     {
417       result = http_loop (u, &mynewloc, &local_file, refurl, dt, proxy_url);
418     }
419   else if (u->scheme == SCHEME_FTP)
420     {
421       /* If this is a redirection, we must not allow recursive FTP
422          retrieval, so we save recursion to oldrec, and restore it
423          later.  */
424       int oldrec = opt.recursive;
425       if (redirection_count)
426         opt.recursive = 0;
427       result = ftp_loop (u, dt, proxy_url);
428       opt.recursive = oldrec;
429
430       /* There is a possibility of having HTTP being redirected to
431          FTP.  In these cases we must decide whether the text is HTML
432          according to the suffix.  The HTML suffixes are `.html',
433          `.htm' and a few others, case-insensitive.  */
434       if (redirection_count && local_file && u->scheme == SCHEME_FTP)
435         {
436           if (has_html_suffix_p (local_file))
437             *dt |= TEXTHTML;
438         }
439     }
440
441   if (proxy_url)
442     {
443       url_free (proxy_url);
444       proxy_url = NULL;
445     }
446
447   location_changed = (result == NEWLOCATION);
448   if (location_changed)
449     {
450       char *construced_newloc;
451       struct url *newloc_parsed;
452
453       assert (mynewloc != NULL);
454
455       if (local_file)
456         xfree (local_file);
457
458       /* The HTTP specs only allow absolute URLs to appear in
459          redirects, but a ton of boneheaded webservers and CGIs out
460          there break the rules and use relative URLs, and popular
461          browsers are lenient about this, so wget should be too. */
462       construced_newloc = uri_merge (url, mynewloc);
463       xfree (mynewloc);
464       mynewloc = construced_newloc;
465
466       /* Now, see if this new location makes sense. */
467       newloc_parsed = url_parse (mynewloc, &up_error_code);
468       if (!newloc_parsed)
469         {
470           logprintf (LOG_NOTQUIET, "%s: %s.\n", mynewloc,
471                      url_error (up_error_code));
472           url_free (u);
473           xfree (url);
474           xfree (mynewloc);
475           RESTORE_POST_DATA;
476           return result;
477         }
478
479       /* Now mynewloc will become newloc_parsed->url, because if the
480          Location contained relative paths like .././something, we
481          don't want that propagating as url.  */
482       xfree (mynewloc);
483       mynewloc = xstrdup (newloc_parsed->url);
484
485       /* Check for max. number of redirections.  */
486       if (++redirection_count > MAX_REDIRECTIONS)
487         {
488           logprintf (LOG_NOTQUIET, _("%d redirections exceeded.\n"),
489                      MAX_REDIRECTIONS);
490           url_free (newloc_parsed);
491           url_free (u);
492           xfree (url);
493           xfree (mynewloc);
494           RESTORE_POST_DATA;
495           return WRONGCODE;
496         }
497
498       xfree (url);
499       url = mynewloc;
500       url_free (u);
501       u = newloc_parsed;
502
503       /* If we're being redirected from POST, we don't want to POST
504          again.  Many requests answer POST with a redirection to an
505          index page; that redirection is clearly a GET.  We "suspend"
506          POST data for the duration of the redirections, and restore
507          it when we're done. */
508       if (!post_data_suspended)
509         SUSPEND_POST_DATA;
510
511       goto redirected;
512     }
513
514   if (local_file)
515     {
516       if (*dt & RETROKF)
517         {
518           register_download (u->url, local_file);
519           if (redirection_count && 0 != strcmp (origurl, u->url))
520             register_redirection (origurl, u->url);
521           if (*dt & TEXTHTML)
522             register_html (u->url, local_file);
523         }
524     }
525
526   if (file)
527     *file = local_file ? local_file : NULL;
528   else
529     xfree_null (local_file);
530
531   url_free (u);
532
533   if (redirection_count)
534     {
535       if (newloc)
536         *newloc = url;
537       else
538         xfree (url);
539     }
540   else
541     {
542       if (newloc)
543         *newloc = NULL;
544       xfree (url);
545     }
546
547   ++global_download_count;
548   RESTORE_POST_DATA;
549
550   return result;
551 }
552
553 /* Find the URLs in the file and call retrieve_url() for each of
554    them.  If HTML is non-zero, treat the file as HTML, and construct
555    the URLs accordingly.
556
557    If opt.recursive is set, call retrieve_tree() for each file.  */
558
559 uerr_t
560 retrieve_from_file (const char *file, int html, int *count)
561 {
562   uerr_t status;
563   struct urlpos *url_list, *cur_url;
564
565   url_list = (html ? get_urls_html (file, NULL, NULL)
566               : get_urls_file (file));
567   status = RETROK;             /* Suppose everything is OK.  */
568   *count = 0;                  /* Reset the URL count.  */
569
570   for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
571     {
572       char *filename = NULL, *new_file = NULL;
573       int dt;
574
575       if (cur_url->ignore_when_downloading)
576         continue;
577
578       if (opt.quota && total_downloaded_bytes > opt.quota)
579         {
580           status = QUOTEXC;
581           break;
582         }
583       if ((opt.recursive || opt.page_requisites)
584           && cur_url->url->scheme != SCHEME_FTP)
585         status = retrieve_tree (cur_url->url->url);
586       else
587         status = retrieve_url (cur_url->url->url, &filename, &new_file, NULL, &dt);
588
589       if (filename && opt.delete_after && file_exists_p (filename))
590         {
591           DEBUGP (("Removing file due to --delete-after in"
592                    " retrieve_from_file():\n"));
593           logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
594           if (unlink (filename))
595             logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
596           dt &= ~RETROKF;
597         }
598
599       xfree_null (new_file);
600       xfree_null (filename);
601     }
602
603   /* Free the linked list of URL-s.  */
604   free_urlpos (url_list);
605
606   return status;
607 }
608
609 /* Print `giving up', or `retrying', depending on the impending
610    action.  N1 and N2 are the attempt number and the attempt limit.  */
611 void
612 printwhat (int n1, int n2)
613 {
614   logputs (LOG_VERBOSE, (n1 == n2) ? _("Giving up.\n\n") : _("Retrying.\n\n"));
615 }
616
617 /* If opt.wait or opt.waitretry are specified, and if certain
618    conditions are met, sleep the appropriate number of seconds.  See
619    the documentation of --wait and --waitretry for more information.
620
621    COUNT is the count of current retrieval, beginning with 1. */
622
623 void
624 sleep_between_retrievals (int count)
625 {
626   static int first_retrieval = 1;
627
628   if (first_retrieval)
629     {
630       /* Don't sleep before the very first retrieval. */
631       first_retrieval = 0;
632       return;
633     }
634
635   if (opt.waitretry && count > 1)
636     {
637       /* If opt.waitretry is specified and this is a retry, wait for
638          COUNT-1 number of seconds, or for opt.waitretry seconds.  */
639       if (count <= opt.waitretry)
640         xsleep (count - 1);
641       else
642         xsleep (opt.waitretry);
643     }
644   else if (opt.wait)
645     {
646       if (!opt.random_wait || count > 1)
647         /* If random-wait is not specified, or if we are sleeping
648            between retries of the same download, sleep the fixed
649            interval.  */
650         xsleep (opt.wait);
651       else
652         {
653           /* Sleep a random amount of time averaging in opt.wait
654              seconds.  The sleeping amount ranges from 0 to
655              opt.wait*2, inclusive.  */
656           double waitsecs = 2 * opt.wait * random_float ();
657           DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n",
658                    opt.wait, waitsecs));
659           xsleep (waitsecs);
660         }
661     }
662 }
663
664 /* Free the linked list of urlpos.  */
665 void
666 free_urlpos (struct urlpos *l)
667 {
668   while (l)
669     {
670       struct urlpos *next = l->next;
671       if (l->url)
672         url_free (l->url);
673       xfree_null (l->local_name);
674       xfree (l);
675       l = next;
676     }
677 }
678
679 /* Rotate FNAME opt.backups times */
680 void
681 rotate_backups(const char *fname)
682 {
683   int maxlen = strlen (fname) + 1 + numdigit (opt.backups) + 1;
684   char *from = (char *)alloca (maxlen);
685   char *to = (char *)alloca (maxlen);
686   struct stat sb;
687   int i;
688
689   if (stat (fname, &sb) == 0)
690     if (S_ISREG (sb.st_mode) == 0)
691       return;
692
693   for (i = opt.backups; i > 1; i--)
694     {
695       sprintf (from, "%s.%d", fname, i - 1);
696       sprintf (to, "%s.%d", fname, i);
697       rename (from, to);
698     }
699
700   sprintf (to, "%s.%d", fname, 1);
701   rename(fname, to);
702 }
703
704 static int no_proxy_match PARAMS ((const char *, const char **));
705
706 /* Return the URL of the proxy appropriate for url U.  */
707
708 static char *
709 getproxy (struct url *u)
710 {
711   char *proxy = NULL;
712   char *rewritten_url;
713   static char rewritten_storage[1024];
714
715   if (!opt.use_proxy)
716     return NULL;
717   if (!no_proxy_match (u->host, (const char **)opt.no_proxy))
718     return NULL;
719
720   switch (u->scheme)
721     {
722     case SCHEME_HTTP:
723       proxy = opt.http_proxy ? opt.http_proxy : getenv ("http_proxy");
724       break;
725 #ifdef HAVE_SSL
726     case SCHEME_HTTPS:
727       proxy = opt.https_proxy ? opt.https_proxy : getenv ("https_proxy");
728       break;
729 #endif
730     case SCHEME_FTP:
731       proxy = opt.ftp_proxy ? opt.ftp_proxy : getenv ("ftp_proxy");
732       break;
733     case SCHEME_INVALID:
734       break;
735     }
736   if (!proxy || !*proxy)
737     return NULL;
738
739   /* Handle shorthands.  `rewritten_storage' is a kludge to allow
740      getproxy() to return static storage. */
741   rewritten_url = rewrite_shorthand_url (proxy);
742   if (rewritten_url)
743     {
744       strncpy (rewritten_storage, rewritten_url, sizeof(rewritten_storage));
745       rewritten_storage[sizeof (rewritten_storage) - 1] = '\0';
746       proxy = rewritten_storage;
747     }
748
749   return proxy;
750 }
751
752 /* Should a host be accessed through proxy, concerning no_proxy?  */
753 int
754 no_proxy_match (const char *host, const char **no_proxy)
755 {
756   if (!no_proxy)
757     return 1;
758   else
759     return !sufmatch (no_proxy, host);
760 }