ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-HTTP/HTTP.pm
(Generate patch)

Comparing AnyEvent-HTTP/HTTP.pm (file contents):
Revision 1.2 by root, Wed Jun 4 11:37:41 2008 UTC vs.
Revision 1.6 by root, Wed Jun 4 12:05:45 2008 UTC

34our $VERSION = '1.0'; 34our $VERSION = '1.0';
35 35
36our @EXPORT = qw(http_get http_request); 36our @EXPORT = qw(http_get http_request);
37 37
38our $USERAGENT = "Mozilla/5.0 (compatible; AnyEvent::HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)"; 38our $USERAGENT = "Mozilla/5.0 (compatible; AnyEvent::HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)";
39our $MAX_REDIRECTS = 10; 39our $MAX_RECURSE = 10;
40our $MAX_PERSISTENT = 8; 40our $MAX_PERSISTENT = 8;
41our $PERSISTENT_TIMEOUT = 2; 41our $PERSISTENT_TIMEOUT = 2;
42our $TIMEOUT = 300; 42our $TIMEOUT = 300;
43 43
44# changing these is evil 44# changing these is evil
51 51
52=item http_get $url, key => value..., $cb->($data, $headers) 52=item http_get $url, key => value..., $cb->($data, $headers)
53 53
54Executes an HTTP-GET request. See the http_request function for details on 54Executes an HTTP-GET request. See the http_request function for details on
55additional parameters. 55additional parameters.
56
57=item http_head $url, key => value..., $cb->($data, $headers)
58
59Executes an HTTP-HEAD request. See the http_request function for details on
60additional parameters.
61
62=item http_post $url, $body, key => value..., $cb->($data, $headers)
63
64Executes an HTTP-POST request with a requets body of C<$bod>. See the
65http_request function for details on additional parameters.
56 66
57=item http_request $method => $url, key => value..., $cb->($data, $headers) 67=item http_request $method => $url, key => value..., $cb->($data, $headers)
58 68
59Executes a HTTP request of type C<$method> (e.g. C<GET>, C<POST>). The URL 69Executes a HTTP request of type C<$method> (e.g. C<GET>, C<POST>). The URL
60must be an absolute http or https URL. 70must be an absolute http or https URL.
70 80
71If an internal error occurs, such as not being able to resolve a hostname, 81If an internal error occurs, such as not being able to resolve a hostname,
72then C<$data> will be C<undef>, C<< $headers->{Status} >> will be C<599> 82then C<$data> will be C<undef>, C<< $headers->{Status} >> will be C<599>
73and the C<Reason> pseudo-header will contain an error message. 83and the C<Reason> pseudo-header will contain an error message.
74 84
85A typical callback might look like this:
86
87 sub {
88 my ($body, $hdr) = @_;
89
90 if ($hdr->{Status} =~ /^2/) {
91 ... everything should be ok
92 } else {
93 print "error, $hdr->{Status} $hdr->{Reason}\n";
94 }
95 }
96
75Additional parameters are key-value pairs, and are fully optional. They 97Additional parameters are key-value pairs, and are fully optional. They
76include: 98include:
77 99
78=over 4 100=over 4
79 101
80=item recurse => $boolean (default: true) 102=item recurse => $count (default: $MAX_RECURSE)
81 103
82Whether to recurse requests or not, e.g. on redirects, authentication 104Whether to recurse requests or not, e.g. on redirects, authentication
83retries and so on. 105retries and so on, and how often to do so.
84 106
85=item headers => hashref 107=item headers => hashref
86 108
87The request headers to use. 109The request headers to use.
88 110
96Use the given http proxy for all requests. If not specified, then the 118Use the given http proxy for all requests. If not specified, then the
97default proxy (as specified by C<$ENV{http_proxy}>) is used. 119default proxy (as specified by C<$ENV{http_proxy}>) is used.
98 120
99C<$scheme> must be either missing or C<http> for HTTP, or C<https> for 121C<$scheme> must be either missing or C<http> for HTTP, or C<https> for
100HTTPS. 122HTTPS.
123
124=item body => $string
125
126The request body, usually empty. Will be-sent as-is (future versions of
127this module might offer more options).
101 128
102=back 129=back
103 130
104=back 131=back
105 132
108sub http_request($$$;@) { 135sub http_request($$$;@) {
109 my $cb = pop; 136 my $cb = pop;
110 my ($method, $url, %arg) = @_; 137 my ($method, $url, %arg) = @_;
111 138
112 my %hdr; 139 my %hdr;
140
141 $method = uc $method;
113 142
114 if (my $hdr = delete $arg{headers}) { 143 if (my $hdr = delete $arg{headers}) {
115 while (my ($k, $v) = each %$hdr) { 144 while (my ($k, $v) = each %$hdr) {
116 $hdr{lc $k} = $v; 145 $hdr{lc $k} = $v;
117 } 146 }
118 } 147 }
119 148
120 my $proxy = $arg{proxy} || $PROXY; 149 my $proxy = $arg{proxy} || $PROXY;
121 my $timeout = $arg{timeout} || $TIMEOUT; 150 my $timeout = $arg{timeout} || $TIMEOUT;
151 my $recurse = exists $arg{recurse} ? $arg{recurse} : $MAX_RECURSE;
122 152
123 $hdr{"user-agent"} ||= $USERAGENT; 153 $hdr{"user-agent"} ||= $USERAGENT;
124 154
125 my ($host, $port, $path, $scheme); 155 my ($host, $port, $path, $scheme);
126 156
151 181
152 $scheme = lc $scheme; 182 $scheme = lc $scheme;
153 183
154 my %state; 184 my %state;
155 185
156 my $body = "";
157 $state{body} = $body; 186 $state{body} = delete $arg{body};
158 187
159 $hdr{"content-length"} = length $body; 188 $hdr{"content-length"} = length $state{body};
160 189
161 $state{connect_guard} = AnyEvent::Socket::tcp_connect $host, $port, sub { 190 $state{connect_guard} = AnyEvent::Socket::tcp_connect $host, $port, sub {
162 $state{fh} = shift 191 $state{fh} = shift
163 or return $cb->(undef, { Status => 599, Reason => "$!" }); 192 or return $cb->(undef, { Status => 599, Reason => "$!" });
164 193
190 $cb->(undef, { Status => 599, Reason => "unexpected end-of-file" }); 219 $cb->(undef, { Status => 599, Reason => "unexpected end-of-file" });
191 }); 220 });
192 221
193 # send request 222 # send request
194 $state{handle}->push_write ( 223 $state{handle}->push_write (
195 "\U$method\E $path HTTP/1.0\015\012" 224 "$method $path HTTP/1.0\015\012"
196 . (join "", map "$_: $hdr{$_}\015\012", keys %hdr) 225 . (join "", map "$_: $hdr{$_}\015\012", keys %hdr)
197 . "\015\012" 226 . "\015\012"
198 . (delete $state{body}) 227 . (delete $state{body})
199 ); 228 );
200 229
229 } 258 }
230 259
231 substr $_, 0, 1, "" 260 substr $_, 0, 1, ""
232 for values %hdr; 261 for values %hdr;
233 262
234 if (exists $hdr{"content-length"}) { 263 if ($method eq "HEAD") {
235 $_[0]->unshift_read (chunk => $hdr{"content-length"}, sub {
236 # could cache persistent connection now
237 if ($hdr{connection} =~ /\bkeep-alive\b/i) {
238 # but we don't, due to misdesigns, this is annoyingly complex
239 };
240
241 %state = (); 264 %state = ();
242 $cb->($_[1], \%hdr); 265 $cb->(undef, \%hdr);
243 });
244 } else { 266 } else {
267 if (exists $hdr{"content-length"}) {
268 $_[0]->unshift_read (chunk => $hdr{"content-length"}, sub {
269 # could cache persistent connection now
270 if ($hdr{connection} =~ /\bkeep-alive\b/i) {
271 # but we don't, due to misdesigns, this is annoyingly complex
272 };
273
274 %state = ();
275 $cb->($_[1], \%hdr);
276 });
277 } else {
245 # too bad, need to read until we get an error or EOF, 278 # too bad, need to read until we get an error or EOF,
246 # no way to detect winged data. 279 # no way to detect winged data.
247 $_[0]->on_error (sub { 280 $_[0]->on_error (sub {
248 %state = (); 281 %state = ();
249 $cb->($_[0]{rbuf}, \%hdr); 282 $cb->($_[0]{rbuf}, \%hdr);
250 }); 283 });
251 $_[0]->on_eof (undef); 284 $_[0]->on_eof (undef);
252 $_[0]->on_read (sub { }); 285 $_[0]->on_read (sub { });
286 }
253 } 287 }
254 }); 288 });
255 }); 289 });
256 }, sub { 290 }, sub {
257 $timeout 291 $timeout
263sub http_get($$;@) { 297sub http_get($$;@) {
264 unshift @_, "GET"; 298 unshift @_, "GET";
265 &http_request 299 &http_request
266} 300}
267 301
302sub http_head($$;@) {
303 unshift @_, "HEAD";
304 &http_request
305}
306
307sub http_post($$$;@) {
308 unshift @_, "POST", "body";
309 &http_request
310}
311
268=head2 GLOBAL FUNCTIONS AND VARIABLES 312=head2 GLOBAL FUNCTIONS AND VARIABLES
269 313
270=over 4 314=over 4
271 315
272=item AnyEvent::HTTP::set_proxy "proxy-url" 316=item AnyEvent::HTTP::set_proxy "proxy-url"
273 317
274Sets the default proxy server to use. The proxy-url must begin with a 318Sets the default proxy server to use. The proxy-url must begin with a
275string of the form C<http://host:port> (optionally C<https:...>). 319string of the form C<http://host:port> (optionally C<https:...>).
276 320
277=item $AnyEvent::HTTP::MAX_REDIRECTS 321=item $AnyEvent::HTTP::MAX_RECURSE
278 322
279The default value for the C<max_redirects> request parameter 323The default value for the C<recurse> request parameter (default: C<10>).
280(default: C<10>).
281 324
282=item $AnyEvent::HTTP::USERAGENT 325=item $AnyEvent::HTTP::USERAGENT
283 326
284The default value for the C<User-Agent> header (the default is 327The default value for the C<User-Agent> header (the default is
285C<Mozilla/5.0 (compatible; AnyEvent::HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)>). 328C<Mozilla/5.0 (compatible; AnyEvent::HTTP/$VERSION; +http://software.schmorp.de/pkg/AnyEvent)>).
286 329
287=item $AnyEvent::HTTP::MAX_PERSISTENT 330=item $AnyEvent::HTTP::MAX_PERSISTENT
288 331
289The maximum number of persistent connections to keep open (default: 8). 332The maximum number of persistent connections to keep open (default: 8).
290 333
334Not implemented currently.
335
291=item $AnyEvent::HTTP::PERSISTENT_TIMEOUT 336=item $AnyEvent::HTTP::PERSISTENT_TIMEOUT
292 337
293The maximum time to cache a persistent connection, in seconds (default: 2). 338The maximum time to cache a persistent connection, in seconds (default: 2).
339
340Not implemented currently.
294 341
295=back 342=back
296 343
297=cut 344=cut
298 345

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines