rewrite home page redirect
[dh-make-perl] / dev / arm / libwww-perl / libwww-perl-5.813 / debian / libwww-perl / usr / bin / lwp-request
1 #!/usr/bin/perl -w
2
3 eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
4     if 0; # not running under some shell
5
6 # Simple user agent using LWP library.
7
8 =head1 NAME
9
10 lwp-request, GET, POST, HEAD - Simple command line user agent
11
12 =head1 SYNOPSIS
13
14 B<lwp-request> [B<-afPuUsSedvhx>] [B<-m> I<method>] [B<-b> I<base URL>] [B<-t> I<timeout>]
15             [B<-i> I<if-modified-since>] [B<-c> I<content-type>]
16             [B<-C> I<credentials>] [B<-p> I<proxy-url>] [B<-o> I<format>] I<url>...
17
18 =head1 DESCRIPTION
19
20 This program can be used to send requests to WWW servers and your
21 local file system. The request content for POST and PUT
22 methods is read from stdin.  The content of the response is printed on
23 stdout.  Error messages are printed on stderr.  The program returns a
24 status value indicating the number of URLs that failed.
25
26 The options are:
27
28 =over 4
29
30 =item -m <method>
31
32 Set which method to use for the request.  If this option is not used,
33 then the method is derived from the name of the program.
34
35 =item -f
36
37 Force request through, even if the program believes that the method is
38 illegal.  The server might reject the request eventually.
39
40 =item -b <uri>
41
42 This URI will be used as the base URI for resolving all relative URIs
43 given as argument.
44
45 =item -t <timeout>
46
47 Set the timeout value for the requests.  The timeout is the amount of
48 time that the program will wait for a response from the remote server
49 before it fails.  The default unit for the timeout value is seconds.
50 You might append "m" or "h" to the timeout value to make it minutes or
51 hours, respectively.  The default timeout is '3m', i.e. 3 minutes.
52
53 =item -i <time>
54
55 Set the If-Modified-Since header in the request. If I<time> is the
56 name of a file, use the modification timestamp for this file. If
57 I<time> is not a file, it is parsed as a literal date. Take a look at
58 L<HTTP::Date> for recognized formats.
59
60 =item -c <content-type>
61
62 Set the Content-Type for the request.  This option is only allowed for
63 requests that take a content, i.e. POST and PUT.  You can
64 force methods to take content by using the C<-f> option together with
65 C<-c>.  The default Content-Type for POST is
66 C<application/x-www-form-urlencoded>.  The default Content-type for
67 the others is C<text/plain>.
68
69 =item -p <proxy-url>
70
71 Set the proxy to be used for the requests.  The program also loads
72 proxy settings from the environment.  You can disable this with the
73 C<-P> option.
74
75 =item -P
76
77 Don't load proxy settings from environment.
78
79 =item -H <header>
80
81 Send this HTTP header with each request. You can specify several, e.g.:
82
83     lwp-request \
84         -H 'Referer: http://other.url/' \
85         -H 'Host: somehost' \
86         http://this.url/
87
88 =item -C <username>:<password>
89
90 Provide credentials for documents that are protected by Basic
91 Authentication.  If the document is protected and you did not specify
92 the username and password with this option, then you will be prompted
93 to provide these values.
94
95 =back
96
97 The following options controls what is displayed by the program:
98
99 =over 4
100
101 =item -u
102
103 Print request method and absolute URL as requests are made.
104
105 =item -U
106
107 Print request headers in addition to request method and absolute URL.
108
109 =item -s
110
111 Print response status code.  This option is always on for HEAD requests.
112
113 =item -S
114
115 Print response status chain. This shows redirect and authorization
116 requests that are handled by the library.
117
118 =item -e
119
120 Print response headers.  This option is always on for HEAD requests.
121
122 =item -d
123
124 Do B<not> print the content of the response.
125
126 =item -o <format>
127
128 Process HTML content in various ways before printing it.  If the
129 content type of the response is not HTML, then this option has no
130 effect.  The legal format values are; I<text>, I<ps>, I<links>,
131 I<html> and I<dump>.
132
133 If you specify the I<text> format then the HTML will be formatted as
134 plain latin1 text.  If you specify the I<ps> format then it will be
135 formatted as Postscript.
136
137 The I<links> format will output all links found in the HTML document.
138 Relative links will be expanded to absolute ones.
139
140 The I<html> format will reformat the HTML code and the I<dump> format
141 will just dump the HTML syntax tree.
142
143 Note that the C<HTML-Tree> distribution needs to be installed for this
144 option to work.  In addition the C<HTML-Format> distribution needs to
145 be installed for I<-o text> or I<-o ps> to work.
146
147 =item -v
148
149 Print the version number of the program and quit.
150
151 =item -h
152
153 Print usage message and quit.
154
155 =item -x
156
157 Extra debugging output.
158
159 =item -a
160
161 Set text(ascii) mode for content input and output.  If this option is not
162 used, content input and output is done in binary mode.
163
164 =back
165
166 Because this program is implemented using the LWP library, it will
167 only support the protocols that LWP supports.
168
169 =head1 SEE ALSO
170
171 L<lwp-mirror>, L<LWP>
172
173 =head1 COPYRIGHT
174
175 Copyright 1995-1999 Gisle Aas.
176
177 This library is free software; you can redistribute it and/or
178 modify it under the same terms as Perl itself.
179
180 =head1 AUTHOR
181
182 Gisle Aas <gisle@aas.no>
183
184 =cut
185
186 $progname = $0;
187 $progname =~ s,.*[\\/],,;  # use basename only
188 $progname =~ s/\.\w*$//;   # strip extension, if any
189
190 $VERSION = "5.810";
191
192
193 require LWP;
194 require LWP::Debug;
195
196 use URI;
197 use URI::Heuristic qw(uf_uri);
198
199 use HTTP::Status qw(status_message);
200 use HTTP::Date qw(time2str str2time);
201
202
203 # This table lists the methods that are allowed.  It should really be
204 # a superset for all methods supported for every scheme that may be
205 # supported by the library.  Currently it might be a bit too HTTP
206 # specific.  You might use the -f option to force a method through.
207 #
208 # "" = No content in request, "C" = Needs content in request
209 #
210 %allowed_methods = (
211     GET        => "",
212     HEAD       => "",
213     POST       => "C",
214     PUT        => "C",
215     DELETE     => "",
216     TRACE      => "",
217     OPTIONS    => "",
218 );
219
220
221 # We make our own specialization of LWP::UserAgent that asks for
222 # user/password if document is protected.
223 {
224     package RequestAgent;
225     @ISA = qw(LWP::UserAgent);
226
227     sub new
228     { 
229         my $self = LWP::UserAgent::new(@_);
230         $self->agent("lwp-request/$main::VERSION");
231         $self;
232     }
233
234     sub get_basic_credentials
235     {
236         my($self, $realm, $uri) = @_;
237         if ($main::options{'C'}) {
238             return split(':', $main::options{'C'}, 2);
239         }
240         elsif (-t) {
241             my $netloc = $uri->host_port;
242             print "Enter username for $realm at $netloc: ";
243             my $user = <STDIN>;
244             chomp($user);
245             return (undef, undef) unless length $user;
246             print "Password: ";
247             system("stty -echo");
248             my $password = <STDIN>;
249             system("stty echo");
250             print "\n";  # because we disabled echo
251             chomp($password);
252             return ($user, $password);
253         }
254         else {
255             return (undef, undef)
256         }
257     }
258 }
259
260 $method = uc(lc($progname) eq "lwp-request" ? "GET" : $progname);
261
262 # Parse command line
263 use Getopt::Long;
264
265 my @getopt_args = (
266     'a', # content i/o in text(ascii) mode
267     'm=s', # set method
268     'f', # make request even if method is not in %allowed_methods
269     'b=s', # base url
270     't=s', # timeout
271     'i=s', # if-modified-since
272     'c=s', # content type for POST
273     'C=s', # credentials for basic authorization
274     'H=s@', # extra headers, form "Header: value string"
275     #
276     'u', # display method, URL and headers of request
277     'U', # display request headers also
278     's', # display status code
279     'S', # display whole chain of status codes
280     'e', # display response headers (default for HEAD)
281     'd', # don't display content
282     #
283     'h', # print usage
284     'v', # print version
285     #
286     'x', # extra debugging info
287     'p=s', # proxy URL
288     'P', # don't load proxy setting from environment
289     #
290     'o=s', # output format
291 );
292
293 Getopt::Long::config("noignorecase", "bundling");
294 unless (GetOptions(\%options, @getopt_args)) {
295     usage();
296 }
297 if ($options{'v'}) {
298     require LWP;
299     my $DISTNAME = 'libwww-perl-' . LWP::Version();
300     die <<"EOT";
301 This is lwp-request version $VERSION ($DISTNAME)
302
303 Copyright 1995-1999, Gisle Aas.
304
305 This program is free software; you can redistribute it and/or
306 modify it under the same terms as Perl itself.
307 EOT
308 }
309
310 usage() if $options{'h'} || !@ARGV;
311
312 LWP::Debug::level('+') if $options{'x'};
313
314 # Create the user agent object
315 $ua = RequestAgent->new;
316
317 # Load proxy settings from *_proxy environment variables.
318 $ua->env_proxy unless $options{'P'};
319
320 $method = uc($options{'m'}) if defined $options{'m'};
321
322 if ($options{'f'}) {
323     if ($options{'c'}) {
324         $allowed_methods{$method} = "C";  # force content
325     }
326     else {
327         $allowed_methods{$method} = "";
328     }
329 }
330 elsif (!defined $allowed_methods{$method}) {
331     die "$progname: $method is not an allowed method\n";
332 }
333
334 if ($method eq "HEAD") {
335     $options{'s'} = 1;
336     $options{'e'} = 1 unless $options{'d'};
337     $options{'d'} = 1;
338 }
339
340 if (defined $options{'t'}) {
341     $options{'t'} =~ /^(\d+)([smh])?/;
342     die "$progname: Illegal timeout value!\n" unless defined $1;
343     $timeout = $1;
344     if (defined $2) {
345         $timeout *= 60   if $2 eq "m";
346         $timeout *= 3600 if $2 eq "h";
347     }
348     $ua->timeout($timeout);
349 }
350
351 if (defined $options{'i'}) {
352     if (-e $options{'i'}) {
353         $time = (stat _)[9];
354     }
355     else {
356         $time = str2time($options{'i'});
357         die "$progname: Illegal time syntax for -i option\n"
358             unless defined $time;
359     }
360     $options{'i'} = time2str($time);
361 }
362
363 $content = undef;
364 if ($allowed_methods{$method} eq "C") {
365     # This request needs some content
366     unless (defined $options{'c'}) {
367         # set default content type
368         $options{'c'} = ($method eq "POST") ?
369               "application/x-www-form-urlencoded"
370             : "text/plain";
371     }
372     else {
373         die "$progname: Illegal Content-type format\n"
374             unless $options{'c'} =~ m,^[\w\-]+/[\w\-.+]+(?:\s*;.*)?$,
375     }
376     print "Please enter content ($options{'c'}) to be ${method}ed:\n"
377         if -t;
378     binmode STDIN unless -t or $options{'a'};
379     $content = join("", <STDIN>);
380 }
381 else {
382     die "$progname: Can't set Content-type for $method requests\n"
383         if defined $options{'c'};
384 }
385
386 # Set up a request.  We will use the same request object for all URLs.
387 $request = HTTP::Request->new($method);
388 $request->header('If-Modified-Since', $options{'i'}) if defined $options{'i'};
389 for my $user_header (@{ $options{'H'} || [] }) {
390     my ($header_name, $header_value) = split /:\s*/, $user_header, 2;
391     $request->header($header_name, $header_value);
392     $ua->agent($header_value) if lc($header_name) eq "user-agent"; # Ugh!
393 }
394 #$request->header('Accept', '*/*');
395 if ($options{'c'}) { # will always be set for request that wants content
396     $request->header('Content-Type', $options{'c'});
397     $request->header('Content-Length', length $content);  # Not really needed
398     $request->content($content);
399 }
400
401 $errors = 0;
402
403 # Ok, now we perform the requests, one URL at a time
404 while ($url = shift) {
405     # Create the URL object, but protect us against bad URLs
406     eval {
407         if ($url =~ /^\w+:/ || $options{'b'}) {  # is there any scheme specification
408             $url = URI->new($url, $options{'b'});
409             $url = $url->abs($options{'b'}) if $options{'b'};
410         }
411         else {
412             $url = uf_uri($url);
413         }
414     };
415     if ($@) {
416         $@ =~ s/ at .* line \d+.*//;
417         print STDERR $@;
418         $errors++;
419         next;
420     }
421
422     $ua->proxy($url->scheme, $options{'p'}) if $options{'p'};
423
424     # Send the request and get a response back from the server
425     $request->url($url);
426     $response = $ua->request($request);
427
428     if ($options{'u'} || $options{'U'}) {
429         my $url = $response->request->url->as_string;
430         print "$method $url\n";
431         print $response->request->headers_as_string, "\n" if $options{'U'};
432     }
433
434     if ($options{'S'}) {
435         printResponseChain($response);
436     }
437     elsif ($options{'s'}) {
438         print $response->status_line, "\n";
439     }
440
441     if ($options{'e'}) {
442         # Display headers
443         print $response->headers_as_string;
444         print "\n";  # separate headers and content
445     }
446
447     unless ($options{'d'}) {
448         if ($options{'o'} &&
449             $response->content_type eq 'text/html') {
450             eval {
451                 require HTML::Parse;
452             };
453             if ($@) {
454                 if ($@ =~ m,^Can't locate HTML/Parse.pm in \@INC,) {
455                     die "The HTML-Tree distribution need to be installed for the -o option to be used.\n";
456                 }
457                 else {
458                     die $@;
459                 }
460             }
461             my $html = HTML::Parse::parse_html($response->content);
462             {
463                 $options{'o'} eq 'ps' && do {
464                     require HTML::FormatPS;
465                     my $f = HTML::FormatPS->new;
466                     print $f->format($html);
467                     last;
468                 };
469                 $options{'o'} eq 'text' && do {
470                     require HTML::FormatText;
471                     my $f = HTML::FormatText->new;
472                     print $f->format($html);
473                     last;
474                 };
475                 $options{'o'} eq 'html' && do {
476                     print $html->as_HTML;
477                     last;
478                 };
479                 $options{'o'} eq 'links' && do {
480                     my $base = $response->base;
481                     $base = $options{'b'} if $options{'b'};
482                     for ( @{ $html->extract_links } ) {
483                         my($link, $elem) = @$_;
484                         my $tag = uc $elem->tag;
485                         $link = URI->new($link)->abs($base)->as_string;
486                         print "$tag\t$link\n";
487                     }
488                     last;
489                 };
490                 $options{'o'} eq 'dump' && do {
491                     $html->dump;
492                     last;
493                 };
494                 # It is bad to not notice this before now :-(
495                 die "Illegal -o option value ($options{'o'})\n";
496             }
497         }
498         else {
499             binmode STDOUT unless $options{'a'};
500             print $response->content;
501         }
502     }
503
504     $errors++ unless $response->is_success;
505 }
506
507 exit $errors;
508
509
510 sub printResponseChain
511 {
512     my($response) = @_;
513     return unless defined $response;
514     printResponseChain($response->previous);
515     my $method = $response->request->method;
516     my $url = $response->request->url->as_string;
517     my $code = $response->code;
518     print "$method $url --> ", $response->status_line, "\n";
519 }
520
521
522 sub usage
523 {
524     die <<"EOT";
525 Usage: $progname [-options] <url>...
526     -m <method>   use method for the request (default is '$method')
527     -f            make request even if $progname believes method is illegal
528     -b <base>     Use the specified URL as base
529     -t <timeout>  Set timeout value
530     -i <time>     Set the If-Modified-Since header on the request
531     -c <conttype> use this content-type for POST, PUT, CHECKIN
532     -a            Use text mode for content I/O
533     -p <proxyurl> use this as a proxy
534     -P            don't load proxy settings from environment
535     -H <header>   send this HTTP header (you can specify several)
536     -C <username>:<password>
537                   provide credentials for basic authentication
538
539     -u            Display method and URL before any response
540     -U            Display request headers (implies -u)
541     -s            Display response status code
542     -S            Display response status chain
543     -e            Display response headers
544     -d            Do not display content
545     -o <format>   Process HTML content in various ways
546
547     -v            Show program version
548     -h            Print this message
549
550     -x            Extra debugging output
551 EOT
552 }