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);
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' , @_); }
27 my $req = HTTP::Request->new(POST => $url);
29 $content = shift if @_ and ref $_[0];
31 while (($k,$v) = splice(@_, 0, 2)) {
32 if (lc($k) eq 'content') {
36 $req->push_header($k, $v);
39 my $ct = $req->header('Content-Type');
41 $ct = 'application/x-www-form-urlencoded';
43 elsif ($ct eq 'form-data') {
44 $ct = 'multipart/form-data';
48 if ($ct =~ m,^multipart/form-data\s*(;|$),i) {
49 require HTTP::Headers::Util;
50 my @v = HTTP::Headers::Util::split_header_words($ct);
51 Carp::carp("Multiple Content-Type headers") if @v > 1;
56 for (my @tmp = @v; @tmp;) {
57 my($k, $v) = splice(@tmp, 0, 2);
58 if (lc($k) eq "boundary") {
60 $boundary_index = @v - @tmp - 1;
65 ($content, $boundary) = form_data($content, $boundary, $req);
67 if ($boundary_index) {
68 $v[$boundary_index] = $boundary;
71 push(@v, boundary => $boundary);
74 $ct = HTTP::Headers::Util::join_header_words(@v);
77 # We use a temporary URI object to format
78 # the application/x-www-form-urlencoded content.
80 my $url = URI->new('http:');
81 $url->query_form(ref($content) eq "HASH" ? %$content : @$content);
82 $content = $url->query;
86 $req->header('Content-Type' => $ct); # might be redundant
87 if (defined($content)) {
88 $req->header('Content-Length' =>
89 length($content)) unless ref($content);
90 $req->content($content);
93 $req->header('Content-Length' => 0);
101 my($method, $url) = splice(@_, 0, 2);
102 my $req = HTTP::Request->new($method => $url);
104 while (($k,$v) = splice(@_, 0, 2)) {
105 if (lc($k) eq 'content') {
106 $req->add_content($v);
107 $req->header("Content-Length", length(${$req->content_ref}));
110 $req->push_header($k, $v);
117 sub form_data # RFC1867
119 my($data, $boundary, $req) = @_;
120 my @data = ref($data) eq "HASH" ? %$data : @$data; # copy
124 while (($k,$v) = splice(@data, 0, 2)) {
126 $k =~ s/([\\\"])/\\$1/g; # escape quotes and backslashes
128 qq(Content-Disposition: form-data; name="$k"$CRLF$CRLF$v));
131 my($file, $usename, @headers) = @$v;
132 unless (defined $usename) {
134 $usename =~ s,.*/,, if defined($usename);
136 $k =~ s/([\\\"])/\\$1/g;
137 my $disp = qq(form-data; name="$k");
138 if (defined($usename) and length($usename)) {
139 $usename =~ s/([\\\"])/\\$1/g;
140 $disp .= qq(; filename="$usename");
143 my $h = HTTP::Headers->new(@headers);
146 my $fh = Symbol::gensym();
147 open($fh, $file) or Carp::croak("Can't open file $file: $!");
149 if ($DYNAMIC_FILE_UPLOAD) {
150 # will read file later
154 local($/) = undef; # slurp files
158 unless ($h->header("Content-Type")) {
159 require LWP::MediaTypes;
160 LWP::MediaTypes::guess_media_type($file, $h);
163 if ($h->header("Content-Disposition")) {
164 # just to get it sorted first
165 $disp = $h->header("Content-Disposition");
166 $h->remove_header("Content-Disposition");
168 if ($h->header("Content")) {
169 $content = $h->header("Content");
170 $h->remove_header("Content");
172 my $head = join($CRLF, "Content-Disposition: $disp",
173 $h->as_string($CRLF),
176 push(@parts, [$head, $content]);
180 push(@parts, $head . $content);
184 return ("", "none") unless @parts;
188 $boundary = boundary(10) # hopefully enough randomness
191 # add the boundaries to the @parts array
193 splice(@parts, $_*2-1, 0, "$CRLF--$boundary$CRLF");
195 unshift(@parts, "--$boundary$CRLF");
196 push(@parts, "$CRLF--$boundary--$CRLF");
198 # See if we can generate Content-Length header
202 my ($head, $f) = @$_;
204 unless ( -f $f && ($file_size = -s _) ) {
205 # The file is either a dynamic file like /dev/audio
206 # or perhaps a file in the /proc file system where
207 # stat may return a 0 size even though reading it
208 # will produce data. So we cannot make
209 # a Content-Length header.
213 $length += $file_size + length $head;
219 $length && $req->header('Content-Length' => $length);
221 # set up a closure that will return content piecemeal
225 defined $length && $length != 0 &&
226 Carp::croak "length of data sent did not match calculated Content-Length header. Probably because uploaded file changed in size during transfer.";
229 my $p = shift @parts;
231 $p .= shift @parts while @parts && !ref($parts[0]);
232 defined $length && ($length -= length $p);
236 my $buflength = length $buf;
237 my $n = read($fh, $buf, 2048, $buflength);
240 unshift(@parts, ["", $fh]);
246 defined $length && ($length -= $buflength);
254 $boundary = boundary() unless $boundary;
260 if (index($_, $boundary) >= 0) {
261 # must have a better boundary
262 $boundary = boundary(++$bno);
268 $content = "--$boundary$CRLF" .
269 join("$CRLF--$boundary$CRLF", @parts) .
270 "$CRLF--$boundary--$CRLF";
273 wantarray ? ($content, $boundary) : $content;
279 my $size = shift || return "xYzZY";
280 require MIME::Base64;
281 my $b = MIME::Base64::encode(join("", map chr(rand(256)), 1..$size*3), "");
282 $b =~ s/[\W]/X/g; # ensure alnum only
292 HTTP::Request::Common - Construct common HTTP::Request objects
296 use HTTP::Request::Common;
297 $ua = LWP::UserAgent->new;
298 $ua->request(GET 'http://www.sn.no/');
299 $ua->request(POST 'http://somewhere/foo', [foo => bar, bar => foo]);
303 This module provide functions that return newly created C<HTTP::Request>
304 objects. These functions are usually more convenient to use than the
305 standard C<HTTP::Request> constructor for the most common requests. The
306 following functions are provided:
312 =item GET $url, Header => Value,...
314 The GET() function returns an C<HTTP::Request> object initialized with
315 the "GET" method and the specified URL. It is roughly equivalent to the
320 HTTP::Headers->new(Header => Value,...),
323 but is less cluttered. What is different is that a header named
324 C<Content> will initialize the content part of the request instead of
325 setting a header field. Note that GET requests should normally not
326 have a content, so this hack makes more sense for the PUT() and POST()
327 functions described below.
329 The get(...) method of C<LWP::UserAgent> exists as a shortcut for
330 $ua->request(GET ...).
334 =item HEAD $url, Header => Value,...
336 Like GET() but the method in the request is "HEAD".
338 The head(...) method of "LWP::UserAgent" exists as a shortcut for
339 $ua->request(HEAD ...).
343 =item PUT $url, Header => Value,...
345 =item PUT $url, Header => Value,..., Content => $content
347 Like GET() but the method in the request is "PUT".
349 The content of the request can be specified using the "Content"
350 pseudo-header. This steals a bit of the header field namespace as
351 there is no way to directly specify a header that is actually called
352 "Content". If you really need this you must update the request
353 returned in a separate statement.
357 =item POST $url, Header => Value,...
359 =item POST $url, $form_ref, Header => Value,...
361 =item POST $url, Header => Value,..., Content => $form_ref
363 =item POST $url, Header => Value,..., Content => $content
365 This works mostly like PUT() with "POST" as the method, but this
366 function also takes a second optional array or hash reference
367 parameter $form_ref. As for PUT() the content can also be specified
368 directly using the "Content" pseudo-header, and you may also provide
369 the $form_ref this way.
371 The $form_ref argument can be used to pass key/value pairs for the
372 form content. By default we will initialize a request using the
373 C<application/x-www-form-urlencoded> content type. This means that
374 you can emulate a HTML E<lt>form> POSTing like this:
376 POST 'http://www.perl.org/survey.cgi',
377 [ name => 'Gisle Aas',
378 email => 'gisle@aas.no',
384 This will create a HTTP::Request object that looks like this:
386 POST http://www.perl.org/survey.cgi
388 Content-Type: application/x-www-form-urlencoded
390 name=Gisle%20Aas&email=gisle%40aas.no&gender=M&born=1964&perc=3%25
392 Multivalued form fields can be specified by either repeating the field
393 name or by passing the value as an array reference.
395 The POST method also supports the C<multipart/form-data> content used
396 for I<Form-based File Upload> as specified in RFC 1867. You trigger
397 this content format by specifying a content type of C<'form-data'> as
398 one of the request headers. If one of the values in the $form_ref is
399 an array reference, then it is treated as a file part specification
400 with the following interpretation:
402 [ $file, $filename, Header => Value... ]
403 [ undef, $filename, Header => Value,..., Content => $content ]
405 The first value in the array ($file) is the name of a file to open.
406 This file will be read and its content placed in the request. The
407 routine will croak if the file can't be opened. Use an C<undef> as
408 $file value if you want to specify the content directly with a
409 C<Content> header. The $filename is the filename to report in the
410 request. If this value is undefined, then the basename of the $file
411 will be used. You can specify an empty string as $filename if you
412 want to suppress sending the filename when you provide a $file value.
414 If a $file is provided by no C<Content-Type> header, then C<Content-Type>
415 and C<Content-Encoding> will be filled in automatically with the values
416 returned by LWP::MediaTypes::guess_media_type()
418 Sending my F<~/.profile> to the survey used as example above can be
421 POST 'http://www.perl.org/survey.cgi',
422 Content_Type => 'form-data',
423 Content => [ name => 'Gisle Aas',
424 email => 'gisle@aas.no',
427 init => ["$ENV{HOME}/.profile"],
430 This will create a HTTP::Request object that almost looks this (the
431 boundary and the content of your F<~/.profile> is likely to be
434 POST http://www.perl.org/survey.cgi
436 Content-Type: multipart/form-data; boundary="6G+f"
439 Content-Disposition: form-data; name="name"
443 Content-Disposition: form-data; name="email"
447 Content-Disposition: form-data; name="gender"
451 Content-Disposition: form-data; name="born"
455 Content-Disposition: form-data; name="init"; filename=".profile"
456 Content-Type: text/plain
458 PATH=/local/perl/bin:$PATH
463 If you set the $DYNAMIC_FILE_UPLOAD variable (exportable) to some TRUE
464 value, then you get back a request object with a subroutine closure as
465 the content attribute. This subroutine will read the content of any
466 files on demand and return it in suitable chunks. This allow you to
467 upload arbitrary big files without using lots of memory. You can even
468 upload infinite files like F</dev/audio> if you wish; however, if
469 the file is not a plain file, there will be no Content-Length header
470 defined for the request. Not all servers (or server
471 applications) like this. Also, if the file(s) change in size between
472 the time the Content-Length is calculated and the time that the last
473 chunk is delivered, the subroutine will C<Croak>.
475 The post(...) method of "LWP::UserAgent" exists as a shortcut for
476 $ua->request(POST ...).
482 L<HTTP::Request>, L<LWP::UserAgent>
487 Copyright 1997-2004, Gisle Aas
489 This library is free software; you can redistribute it and/or
490 modify it under the same terms as Perl itself.