1 package HTTP::Request::Common;
4 use vars qw(@EXPORT @EXPORT_OK $VERSION $DYNAMIC_FILE_UPLOAD);
6 $DYNAMIC_FILE_UPLOAD ||= 0; # make it defined (don't know why)
9 *import = \&Exporter::import;
10 @EXPORT =qw(GET HEAD PUT POST);
11 @EXPORT_OK = qw($DYNAMIC_FILE_UPLOAD DELETE);
13 require HTTP::Request;
18 my $CRLF = "\015\012"; # "\r\n" is not portable
20 sub GET { _simple_req('GET', @_); }
21 sub HEAD { _simple_req('HEAD', @_); }
22 sub PUT { _simple_req('PUT' , @_); }
23 sub DELETE { _simple_req('DELETE', @_); }
28 my $req = HTTP::Request->new(POST => $url);
30 $content = shift if @_ and ref $_[0];
32 while (($k,$v) = splice(@_, 0, 2)) {
33 if (lc($k) eq 'content') {
37 $req->push_header($k, $v);
40 my $ct = $req->header('Content-Type');
42 $ct = 'application/x-www-form-urlencoded';
44 elsif ($ct eq 'form-data') {
45 $ct = 'multipart/form-data';
49 if ($ct =~ m,^multipart/form-data\s*(;|$),i) {
50 require HTTP::Headers::Util;
51 my @v = HTTP::Headers::Util::split_header_words($ct);
52 Carp::carp("Multiple Content-Type headers") if @v > 1;
57 for (my @tmp = @v; @tmp;) {
58 my($k, $v) = splice(@tmp, 0, 2);
59 if ($k eq "boundary") {
61 $boundary_index = @v - @tmp - 1;
66 ($content, $boundary) = form_data($content, $boundary, $req);
68 if ($boundary_index) {
69 $v[$boundary_index] = $boundary;
72 push(@v, boundary => $boundary);
75 $ct = HTTP::Headers::Util::join_header_words(@v);
78 # We use a temporary URI object to format
79 # the application/x-www-form-urlencoded content.
81 my $url = URI->new('http:');
82 $url->query_form(ref($content) eq "HASH" ? %$content : @$content);
83 $content = $url->query;
87 $req->header('Content-Type' => $ct); # might be redundant
88 if (defined($content)) {
89 $req->header('Content-Length' =>
90 length($content)) unless ref($content);
91 $req->content($content);
94 $req->header('Content-Length' => 0);
102 my($method, $url) = splice(@_, 0, 2);
103 my $req = HTTP::Request->new($method => $url);
106 while (($k,$v) = splice(@_, 0, 2)) {
107 if (lc($k) eq 'content') {
108 $req->add_content($v);
112 $req->push_header($k, $v);
115 if ($content && !defined($req->header("Content-Length"))) {
116 $req->header("Content-Length", length(${$req->content_ref}));
122 sub form_data # RFC1867
124 my($data, $boundary, $req) = @_;
125 my @data = ref($data) eq "HASH" ? %$data : @$data; # copy
129 while (($k,$v) = splice(@data, 0, 2)) {
131 $k =~ s/([\\\"])/\\$1/g; # escape quotes and backslashes
133 qq(Content-Disposition: form-data; name="$k"$CRLF$CRLF$v));
136 my($file, $usename, @headers) = @$v;
137 unless (defined $usename) {
139 $usename =~ s,.*/,, if defined($usename);
141 $k =~ s/([\\\"])/\\$1/g;
142 my $disp = qq(form-data; name="$k");
143 if (defined($usename) and length($usename)) {
144 $usename =~ s/([\\\"])/\\$1/g;
145 $disp .= qq(; filename="$usename");
148 my $h = HTTP::Headers->new(@headers);
150 open(my $fh, "<", $file) or Carp::croak("Can't open file $file: $!");
152 if ($DYNAMIC_FILE_UPLOAD) {
153 # will read file later, close it now in order to
154 # not accumulate to many open file handles
159 local($/) = undef; # slurp files
163 unless ($h->header("Content-Type")) {
164 require LWP::MediaTypes;
165 LWP::MediaTypes::guess_media_type($file, $h);
168 if ($h->header("Content-Disposition")) {
169 # just to get it sorted first
170 $disp = $h->header("Content-Disposition");
171 $h->remove_header("Content-Disposition");
173 if ($h->header("Content")) {
174 $content = $h->header("Content");
175 $h->remove_header("Content");
177 my $head = join($CRLF, "Content-Disposition: $disp",
178 $h->as_string($CRLF),
181 push(@parts, [$head, $$content]);
185 push(@parts, $head . $content);
189 return ("", "none") unless @parts;
193 $boundary = boundary(10) # hopefully enough randomness
196 # add the boundaries to the @parts array
198 splice(@parts, $_*2-1, 0, "$CRLF--$boundary$CRLF");
200 unshift(@parts, "--$boundary$CRLF");
201 push(@parts, "$CRLF--$boundary--$CRLF");
203 # See if we can generate Content-Length header
207 my ($head, $f) = @$_;
209 unless ( -f $f && ($file_size = -s _) ) {
210 # The file is either a dynamic file like /dev/audio
211 # or perhaps a file in the /proc file system where
212 # stat may return a 0 size even though reading it
213 # will produce data. So we cannot make
214 # a Content-Length header.
218 $length += $file_size + length $head;
224 $length && $req->header('Content-Length' => $length);
226 # set up a closure that will return content piecemeal
230 defined $length && $length != 0 &&
231 Carp::croak "length of data sent did not match calculated Content-Length header. Probably because uploaded file changed in size during transfer.";
234 my $p = shift @parts;
236 $p .= shift @parts while @parts && !ref($parts[0]);
237 defined $length && ($length -= length $p);
244 open($fh, "<", $file) || Carp::croak("Can't open file $file: $!");
247 my $buflength = length $buf;
248 my $n = read($fh, $buf, 2048, $buflength);
251 unshift(@parts, ["", $fh]);
257 defined $length && ($length -= $buflength);
265 $boundary = boundary() unless $boundary;
271 if (index($_, $boundary) >= 0) {
272 # must have a better boundary
273 $boundary = boundary(++$bno);
279 $content = "--$boundary$CRLF" .
280 join("$CRLF--$boundary$CRLF", @parts) .
281 "$CRLF--$boundary--$CRLF";
284 wantarray ? ($content, $boundary) : $content;
290 my $size = shift || return "xYzZY";
291 require MIME::Base64;
292 my $b = MIME::Base64::encode(join("", map chr(rand(256)), 1..$size*3), "");
293 $b =~ s/[\W]/X/g; # ensure alnum only
303 HTTP::Request::Common - Construct common HTTP::Request objects
307 use HTTP::Request::Common;
308 $ua = LWP::UserAgent->new;
309 $ua->request(GET 'http://www.sn.no/');
310 $ua->request(POST 'http://somewhere/foo', [foo => bar, bar => foo]);
314 This module provide functions that return newly created C<HTTP::Request>
315 objects. These functions are usually more convenient to use than the
316 standard C<HTTP::Request> constructor for the most common requests. The
317 following functions are provided:
323 =item GET $url, Header => Value,...
325 The GET() function returns an C<HTTP::Request> object initialized with
326 the "GET" method and the specified URL. It is roughly equivalent to the
331 HTTP::Headers->new(Header => Value,...),
334 but is less cluttered. What is different is that a header named
335 C<Content> will initialize the content part of the request instead of
336 setting a header field. Note that GET requests should normally not
337 have a content, so this hack makes more sense for the PUT() and POST()
338 functions described below.
340 The get(...) method of C<LWP::UserAgent> exists as a shortcut for
341 $ua->request(GET ...).
345 =item HEAD $url, Header => Value,...
347 Like GET() but the method in the request is "HEAD".
349 The head(...) method of "LWP::UserAgent" exists as a shortcut for
350 $ua->request(HEAD ...).
354 =item PUT $url, Header => Value,...
356 =item PUT $url, Header => Value,..., Content => $content
358 Like GET() but the method in the request is "PUT".
360 The content of the request can be specified using the "Content"
361 pseudo-header. This steals a bit of the header field namespace as
362 there is no way to directly specify a header that is actually called
363 "Content". If you really need this you must update the request
364 returned in a separate statement.
368 =item DELETE $url, Header => Value,...
370 Like GET() but the method in the request is "DELETE". This function
371 is not exported by default.
375 =item POST $url, Header => Value,...
377 =item POST $url, $form_ref, Header => Value,...
379 =item POST $url, Header => Value,..., Content => $form_ref
381 =item POST $url, Header => Value,..., Content => $content
383 This works mostly like PUT() with "POST" as the method, but this
384 function also takes a second optional array or hash reference
385 parameter $form_ref. As for PUT() the content can also be specified
386 directly using the "Content" pseudo-header, and you may also provide
387 the $form_ref this way.
389 The $form_ref argument can be used to pass key/value pairs for the
390 form content. By default we will initialize a request using the
391 C<application/x-www-form-urlencoded> content type. This means that
392 you can emulate a HTML E<lt>form> POSTing like this:
394 POST 'http://www.perl.org/survey.cgi',
395 [ name => 'Gisle Aas',
396 email => 'gisle@aas.no',
402 This will create a HTTP::Request object that looks like this:
404 POST http://www.perl.org/survey.cgi
406 Content-Type: application/x-www-form-urlencoded
408 name=Gisle%20Aas&email=gisle%40aas.no&gender=M&born=1964&perc=3%25
410 Multivalued form fields can be specified by either repeating the field
411 name or by passing the value as an array reference.
413 The POST method also supports the C<multipart/form-data> content used
414 for I<Form-based File Upload> as specified in RFC 1867. You trigger
415 this content format by specifying a content type of C<'form-data'> as
416 one of the request headers. If one of the values in the $form_ref is
417 an array reference, then it is treated as a file part specification
418 with the following interpretation:
420 [ $file, $filename, Header => Value... ]
421 [ undef, $filename, Header => Value,..., Content => $content ]
423 The first value in the array ($file) is the name of a file to open.
424 This file will be read and its content placed in the request. The
425 routine will croak if the file can't be opened. Use an C<undef> as
426 $file value if you want to specify the content directly with a
427 C<Content> header. The $filename is the filename to report in the
428 request. If this value is undefined, then the basename of the $file
429 will be used. You can specify an empty string as $filename if you
430 want to suppress sending the filename when you provide a $file value.
432 If a $file is provided by no C<Content-Type> header, then C<Content-Type>
433 and C<Content-Encoding> will be filled in automatically with the values
434 returned by LWP::MediaTypes::guess_media_type()
436 Sending my F<~/.profile> to the survey used as example above can be
439 POST 'http://www.perl.org/survey.cgi',
440 Content_Type => 'form-data',
441 Content => [ name => 'Gisle Aas',
442 email => 'gisle@aas.no',
445 init => ["$ENV{HOME}/.profile"],
448 This will create a HTTP::Request object that almost looks this (the
449 boundary and the content of your F<~/.profile> is likely to be
452 POST http://www.perl.org/survey.cgi
454 Content-Type: multipart/form-data; boundary="6G+f"
457 Content-Disposition: form-data; name="name"
461 Content-Disposition: form-data; name="email"
465 Content-Disposition: form-data; name="gender"
469 Content-Disposition: form-data; name="born"
473 Content-Disposition: form-data; name="init"; filename=".profile"
474 Content-Type: text/plain
476 PATH=/local/perl/bin:$PATH
481 If you set the $DYNAMIC_FILE_UPLOAD variable (exportable) to some TRUE
482 value, then you get back a request object with a subroutine closure as
483 the content attribute. This subroutine will read the content of any
484 files on demand and return it in suitable chunks. This allow you to
485 upload arbitrary big files without using lots of memory. You can even
486 upload infinite files like F</dev/audio> if you wish; however, if
487 the file is not a plain file, there will be no Content-Length header
488 defined for the request. Not all servers (or server
489 applications) like this. Also, if the file(s) change in size between
490 the time the Content-Length is calculated and the time that the last
491 chunk is delivered, the subroutine will C<Croak>.
493 The post(...) method of "LWP::UserAgent" exists as a shortcut for
494 $ua->request(POST ...).
500 L<HTTP::Request>, L<LWP::UserAgent>
505 Copyright 1997-2004, Gisle Aas
507 This library is free software; you can redistribute it and/or
508 modify it under the same terms as Perl itself.