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