]> sjero.net Git - wget/blob - src/retr.c
[svn] Use new function to test filename for common html suffixes.
[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
9 (at 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 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/types.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif /* HAVE_UNISTD_H */
28 #include <errno.h>
29 #ifdef HAVE_STRING_H
30 # include <string.h>
31 #else
32 # include <strings.h>
33 #endif /* HAVE_STRING_H */
34 #include <assert.h>
35
36 #include "wget.h"
37 #include "utils.h"
38 #include "retr.h"
39 #include "progress.h"
40 #include "url.h"
41 #include "recur.h"
42 #include "ftp.h"
43 #include "host.h"
44 #include "connect.h"
45 #include "hash.h"
46
47 #ifdef HAVE_SSL
48 # include "gen_sslfunc.h"       /* for ssl_iread */
49 #endif
50
51 #ifndef errno
52 extern int errno;
53 #endif
54
55 /* See the comment in gethttp() why this is needed. */
56 int global_download_count;
57
58 \f
59 static struct {
60   long bytes;
61   long dltime;
62 } limit_data;
63
64 static void
65 limit_bandwidth_reset (void)
66 {
67   limit_data.bytes  = 0;
68   limit_data.dltime = 0;
69 }
70
71 /* Limit the bandwidth by pausing the download for an amount of time.
72    BYTES is the number of bytes received from the network, DELTA is
73    how long it took to receive them, DLTIME the current download time,
74    TIMER the timer, and ADJUSTMENT the previous.  */
75
76 static void
77 limit_bandwidth (long bytes, long delta)
78 {
79   long expected;
80
81   limit_data.bytes += bytes;
82   limit_data.dltime += delta;
83
84   expected = (long)(1000.0 * limit_data.bytes / opt.limit_rate);
85
86   if (expected > limit_data.dltime)
87     {
88       long slp = expected - limit_data.dltime;
89       if (slp < 200)
90         {
91           DEBUGP (("deferring a %ld ms sleep (%ld/%ld) until later.\n",
92                    slp, limit_data.bytes, limit_data.dltime));
93           return;
94         }
95       DEBUGP (("sleeping %ld ms\n", slp));
96       usleep (1000 * slp);
97     }
98
99   limit_data.bytes = 0;
100   limit_data.dltime = 0;
101 }
102
103 #define MIN(i, j) ((i) <= (j) ? (i) : (j))
104
105 /* Reads the contents of file descriptor FD, until it is closed, or a
106    read error occurs.  The data is read in 8K chunks, and stored to
107    stream fp, which should have been open for writing.  If BUF is
108    non-NULL and its file descriptor is equal to FD, flush RBUF first.
109    This function will *not* use the rbuf_* functions!
110
111    The EXPECTED argument is passed to show_progress() unchanged, but
112    otherwise ignored.
113
114    If opt.verbose is set, the progress is also shown.  RESTVAL
115    represents a value from which to start downloading (which will be
116    shown accordingly).  If RESTVAL is non-zero, the stream should have
117    been open for appending.
118
119    The function exits and returns codes of 0, -1 and -2 if the
120    connection was closed, there was a read error, or if it could not
121    write to the output stream, respectively.
122
123    IMPORTANT: The function flushes the contents of the buffer in
124    rbuf_flush() before actually reading from fd.  If you wish to read
125    from fd immediately, flush or discard the buffer.  */
126 int
127 get_contents (int fd, FILE *fp, long *len, long restval, long expected,
128               struct rbuf *rbuf, int use_expected, long *elapsed)
129 {
130   int res = 0;
131   static char c[8192];
132   void *progress = NULL;
133   struct wget_timer *timer = wtimer_allocate ();
134   long dltime = 0, last_dltime = 0;
135
136   *len = restval;
137
138   if (opt.verbose)
139     progress = progress_create (restval, expected);
140
141   if (rbuf && RBUF_FD (rbuf) == fd)
142     {
143       int sz = 0;
144       while ((res = rbuf_flush (rbuf, c, sizeof (c))) != 0)
145         {
146           fwrite (c, sizeof (char), res, fp);
147           *len += res;
148           sz += res;
149         }
150       if (sz)
151         fflush (fp);
152       if (ferror (fp))
153         {
154           res = -2;
155           goto out;
156         }
157       if (opt.verbose)
158         progress_update (progress, sz, 0);
159     }
160
161   if (opt.limit_rate)
162     limit_bandwidth_reset ();
163   wtimer_reset (timer);
164
165   /* Read from fd while there is available data.
166
167      Normally, if expected is 0, it means that it is not known how
168      much data is expected.  However, if use_expected is specified,
169      then expected being zero means exactly that.  */
170   while (!use_expected || (*len < expected))
171     {
172       int amount_to_read = (use_expected
173                             ? MIN (expected - *len, sizeof (c))
174                             : sizeof (c));
175 #ifdef HAVE_SSL
176       if (rbuf->ssl!=NULL)
177         res = ssl_iread (rbuf->ssl, c, amount_to_read);
178       else
179 #endif /* HAVE_SSL */
180         res = iread (fd, c, amount_to_read);
181
182       if (res > 0)
183         {
184           fwrite (c, sizeof (char), res, fp);
185           /* Always flush the contents of the network packet.  This
186              should not be adverse to performance, as the network
187              packets typically won't be too tiny anyway.  */
188           fflush (fp);
189           if (ferror (fp))
190             {
191               res = -2;
192               goto out;
193             }
194
195           /* If bandwidth is not limited, one call to wtimer_elapsed
196              is sufficient.  */
197           dltime = wtimer_elapsed (timer);
198           if (opt.limit_rate)
199             {
200               limit_bandwidth (res, dltime - last_dltime);
201               dltime = wtimer_elapsed (timer);
202               last_dltime = dltime;
203             }
204
205           if (opt.verbose)
206             progress_update (progress, res, dltime);
207           *len += res;
208         }
209       else
210         break;
211     }
212   if (res < -1)
213     res = -1;
214
215  out:
216   if (opt.verbose)
217     progress_finish (progress, dltime);
218   if (elapsed)
219     *elapsed = dltime;
220   wtimer_delete (timer);
221
222   return res;
223 }
224 \f
225 /* Return a printed representation of the download rate, as
226    appropriate for the speed.  If PAD is non-zero, strings will be
227    padded to the width of 7 characters (xxxx.xx).  */
228 char *
229 retr_rate (long bytes, long msecs, int pad)
230 {
231   static char res[20];
232   static char *rate_names[] = {"B/s", "KB/s", "MB/s", "GB/s" };
233   int units = 0;
234
235   double dlrate = calc_rate (bytes, msecs, &units);
236   sprintf (res, pad ? "%7.2f %s" : "%.2f %s", dlrate, rate_names[units]);
237
238   return res;
239 }
240
241 /* Calculate the download rate and trim it as appropriate for the
242    speed.  Appropriate means that if rate is greater than 1K/s,
243    kilobytes are used, and if rate is greater than 1MB/s, megabytes
244    are used.
245
246    UNITS is zero for B/s, one for KB/s, two for MB/s, and three for
247    GB/s.  */
248 double
249 calc_rate (long bytes, long msecs, int *units)
250 {
251   double dlrate;
252
253   assert (msecs >= 0);
254   assert (bytes >= 0);
255
256   if (msecs == 0)
257     /* If elapsed time is 0, it means we're under the granularity of
258        the timer.  This often happens on systems that use time() for
259        the timer.  */
260     msecs = wtimer_granularity ();
261
262   dlrate = (double)1000 * bytes / msecs;
263   if (dlrate < 1024.0)
264     *units = 0;
265   else if (dlrate < 1024.0 * 1024.0)
266     *units = 1, dlrate /= 1024.0;
267   else if (dlrate < 1024.0 * 1024.0 * 1024.0)
268     *units = 2, dlrate /= (1024.0 * 1024.0);
269   else
270     /* Maybe someone will need this one day.  More realistically, it
271        will get tickled by buggy timers. */
272     *units = 3, dlrate /= (1024.0 * 1024.0 * 1024.0);
273
274   return dlrate;
275 }
276 \f
277 #define USE_PROXY_P(u) (opt.use_proxy && getproxy((u)->scheme)          \
278                         && no_proxy_match((u)->host,                    \
279                                           (const char **)opt.no_proxy))
280
281 /* Maximum number of allowed redirections.  20 was chosen as a
282    "reasonable" value, which is low enough to not cause havoc, yet
283    high enough to guarantee that normal retrievals will not be hurt by
284    the check.  */
285
286 #define MAX_REDIRECTIONS 20
287
288 /* Retrieve the given URL.  Decides which loop to call -- HTTP, FTP,
289    FTP, proxy, etc.  */
290
291 uerr_t
292 retrieve_url (const char *origurl, char **file, char **newloc,
293               const char *refurl, int *dt)
294 {
295   uerr_t result;
296   char *url;
297   int location_changed, dummy;
298   int use_proxy;
299   char *mynewloc, *proxy;
300   struct url *u;
301   int up_error_code;            /* url parse error code */
302   char *local_file;
303   int redirection_count = 0;
304
305   /* If dt is NULL, just ignore it.  */
306   if (!dt)
307     dt = &dummy;
308   url = xstrdup (origurl);
309   if (newloc)
310     *newloc = NULL;
311   if (file)
312     *file = NULL;
313
314   u = url_parse (url, &up_error_code);
315   if (!u)
316     {
317       logprintf (LOG_NOTQUIET, "%s: %s.\n", url, url_error (up_error_code));
318       xfree (url);
319       return URLERROR;
320     }
321
322   if (!refurl)
323     refurl = opt.referer;
324
325  redirected:
326
327   result = NOCONERROR;
328   mynewloc = NULL;
329   local_file = NULL;
330
331   use_proxy = USE_PROXY_P (u);
332   if (use_proxy)
333     {
334       struct url *proxy_url;
335
336       /* Get the proxy server for the current scheme.  */
337       proxy = getproxy (u->scheme);
338       if (!proxy)
339         {
340           logputs (LOG_NOTQUIET, _("Could not find proxy host.\n"));
341           url_free (u);
342           xfree (url);
343           return PROXERR;
344         }
345
346       /* Parse the proxy URL.  */
347       proxy_url = url_parse (proxy, &up_error_code);
348       if (!proxy_url)
349         {
350           logprintf (LOG_NOTQUIET, _("Error parsing proxy URL %s: %s.\n"),
351                      proxy, url_error (up_error_code));
352           xfree (url);
353           return PROXERR;
354         }
355       if (proxy_url->scheme != SCHEME_HTTP)
356         {
357           logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy);
358           url_free (proxy_url);
359           xfree (url);
360           return PROXERR;
361         }
362
363       result = http_loop (u, &mynewloc, &local_file, refurl, dt, proxy_url);
364       url_free (proxy_url);
365     }
366   else if (u->scheme == SCHEME_HTTP
367 #ifdef HAVE_SSL
368       || u->scheme == SCHEME_HTTPS
369 #endif
370       )
371     {
372       result = http_loop (u, &mynewloc, &local_file, refurl, dt, NULL);
373     }
374   else if (u->scheme == SCHEME_FTP)
375     {
376       /* If this is a redirection, we must not allow recursive FTP
377          retrieval, so we save recursion to oldrec, and restore it
378          later.  */
379       int oldrec = opt.recursive;
380       if (redirection_count)
381         opt.recursive = 0;
382       result = ftp_loop (u, dt);
383       opt.recursive = oldrec;
384
385       /* There is a possibility of having HTTP being redirected to
386          FTP.  In these cases we must decide whether the text is HTML
387          according to the suffix.  The HTML suffixes are `.html',
388          `.htm' and a few others, case-insensitive.  */
389       if (redirection_count && local_file && u->scheme == SCHEME_FTP)
390         {
391           if (has_html_suffix_p (local_file))
392             *dt |= TEXTHTML;
393         }
394     }
395   location_changed = (result == NEWLOCATION);
396   if (location_changed)
397     {
398       char *construced_newloc;
399       struct url *newloc_parsed;
400
401       assert (mynewloc != NULL);
402
403       if (local_file)
404         xfree (local_file);
405
406       /* The HTTP specs only allow absolute URLs to appear in
407          redirects, but a ton of boneheaded webservers and CGIs out
408          there break the rules and use relative URLs, and popular
409          browsers are lenient about this, so wget should be too. */
410       construced_newloc = uri_merge (url, mynewloc);
411       xfree (mynewloc);
412       mynewloc = construced_newloc;
413
414       /* Now, see if this new location makes sense. */
415       newloc_parsed = url_parse (mynewloc, &up_error_code);
416       if (!newloc_parsed)
417         {
418           logprintf (LOG_NOTQUIET, "%s: %s.\n", mynewloc,
419                      url_error (up_error_code));
420           url_free (u);
421           xfree (url);
422           xfree (mynewloc);
423           return result;
424         }
425
426       /* Now mynewloc will become newloc_parsed->url, because if the
427          Location contained relative paths like .././something, we
428          don't want that propagating as url.  */
429       xfree (mynewloc);
430       mynewloc = xstrdup (newloc_parsed->url);
431
432       /* Check for max. number of redirections.  */
433       if (++redirection_count > MAX_REDIRECTIONS)
434         {
435           logprintf (LOG_NOTQUIET, _("%d redirections exceeded.\n"),
436                      MAX_REDIRECTIONS);
437           url_free (newloc_parsed);
438           url_free (u);
439           xfree (url);
440           xfree (mynewloc);
441           return WRONGCODE;
442         }
443
444       xfree (url);
445       url = mynewloc;
446       url_free (u);
447       u = newloc_parsed;
448       goto redirected;
449     }
450
451   if (local_file)
452     {
453       if (*dt & RETROKF)
454         {
455           register_download (u->url, local_file);
456           if (redirection_count && 0 != strcmp (origurl, u->url))
457             register_redirection (origurl, u->url);
458           if (*dt & TEXTHTML)
459             register_html (u->url, local_file);
460         }
461     }
462
463   if (file)
464     *file = local_file ? local_file : NULL;
465   else
466     FREE_MAYBE (local_file);
467
468   url_free (u);
469
470   if (redirection_count)
471     {
472       if (newloc)
473         *newloc = url;
474       else
475         xfree (url);
476     }
477   else
478     {
479       if (newloc)
480         *newloc = NULL;
481       xfree (url);
482     }
483
484   ++global_download_count;
485
486   return result;
487 }
488
489 /* Find the URLs in the file and call retrieve_url() for each of
490    them.  If HTML is non-zero, treat the file as HTML, and construct
491    the URLs accordingly.
492
493    If opt.recursive is set, call recursive_retrieve() for each file.  */
494 uerr_t
495 retrieve_from_file (const char *file, int html, int *count)
496 {
497   uerr_t status;
498   struct urlpos *url_list, *cur_url;
499
500   url_list = (html ? get_urls_html (file, NULL, NULL)
501               : get_urls_file (file));
502   status = RETROK;             /* Suppose everything is OK.  */
503   *count = 0;                  /* Reset the URL count.  */
504
505   for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
506     {
507       char *filename = NULL, *new_file = NULL;
508       int dt;
509
510       if (cur_url->ignore_when_downloading)
511         continue;
512
513       if (downloaded_exceeds_quota ())
514         {
515           status = QUOTEXC;
516           break;
517         }
518       if (opt.recursive && cur_url->url->scheme != SCHEME_FTP)
519         status = retrieve_tree (cur_url->url->url);
520       else
521         status = retrieve_url (cur_url->url->url, &filename, &new_file, NULL, &dt);
522
523       if (filename && opt.delete_after && file_exists_p (filename))
524         {
525           DEBUGP (("Removing file due to --delete-after in"
526                    " retrieve_from_file():\n"));
527           logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
528           if (unlink (filename))
529             logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
530           dt &= ~RETROKF;
531         }
532
533       FREE_MAYBE (new_file);
534       FREE_MAYBE (filename);
535     }
536
537   /* Free the linked list of URL-s.  */
538   free_urlpos (url_list);
539
540   return status;
541 }
542
543 /* Print `giving up', or `retrying', depending on the impending
544    action.  N1 and N2 are the attempt number and the attempt limit.  */
545 void
546 printwhat (int n1, int n2)
547 {
548   logputs (LOG_VERBOSE, (n1 == n2) ? _("Giving up.\n\n") : _("Retrying.\n\n"));
549 }
550
551 /* Increment opt.downloaded by BY_HOW_MUCH.  If an overflow occurs,
552    set opt.downloaded_overflow to 1. */
553 void
554 downloaded_increase (unsigned long by_how_much)
555 {
556   VERY_LONG_TYPE old;
557   if (opt.downloaded_overflow)
558     return;
559   old = opt.downloaded;
560   opt.downloaded += by_how_much;
561   if (opt.downloaded < old)     /* carry flag, where are you when I
562                                    need you? */
563     {
564       /* Overflow. */
565       opt.downloaded_overflow = 1;
566       opt.downloaded = ~((VERY_LONG_TYPE)0);
567     }
568 }
569
570 /* Return non-zero if the downloaded amount of bytes exceeds the
571    desired quota.  If quota is not set or if the amount overflowed, 0
572    is returned. */
573 int
574 downloaded_exceeds_quota (void)
575 {
576   if (!opt.quota)
577     return 0;
578   if (opt.downloaded_overflow)
579     /* We don't really know.  (Wildly) assume not. */
580     return 0;
581
582   return opt.downloaded > opt.quota;
583 }
584
585 /* If opt.wait or opt.waitretry are specified, and if certain
586    conditions are met, sleep the appropriate number of seconds.  See
587    the documentation of --wait and --waitretry for more information.
588
589    COUNT is the count of current retrieval, beginning with 1. */
590
591 void
592 sleep_between_retrievals (int count)
593 {
594   static int first_retrieval = 1;
595
596   if (first_retrieval)
597     {
598       /* Don't sleep before the very first retrieval. */
599       first_retrieval = 0;
600       return;
601     }
602
603   if (opt.waitretry && count > 1)
604     {
605       /* If opt.waitretry is specified and this is a retry, wait for
606          COUNT-1 number of seconds, or for opt.waitretry seconds.  */
607       if (count <= opt.waitretry)
608         sleep (count - 1);
609       else
610         sleep (opt.waitretry);
611     }
612   else if (opt.wait)
613     {
614       if (!opt.random_wait || count > 1)
615         /* If random-wait is not specified, or if we are sleeping
616            between retries of the same download, sleep the fixed
617            interval.  */
618         sleep (opt.wait);
619       else
620         {
621           /* Sleep a random amount of time averaging in opt.wait
622              seconds.  The sleeping amount ranges from 0 to
623              opt.wait*2, inclusive.  */
624           int waitsecs = random_number (opt.wait * 2 + 1);
625
626           DEBUGP (("sleep_between_retrievals: norm=%ld,fuzz=%ld,sleep=%d\n",
627                    opt.wait, waitsecs - opt.wait, waitsecs));
628
629           if (waitsecs)
630             sleep (waitsecs);
631         }
632     }
633 }