line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package HTTP::MHTTP; |
2
|
2
|
|
|
2
|
|
13784
|
use strict; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
102
|
|
3
|
|
|
|
|
|
|
require 5.005; |
4
|
2
|
|
|
2
|
|
14
|
use Carp; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
181
|
|
5
|
|
|
|
|
|
|
require DynaLoader; |
6
|
|
|
|
|
|
|
require Exporter; |
7
|
2
|
|
|
2
|
|
3864
|
use MIME::Base64 qw(encode_base64); |
|
2
|
|
|
|
|
2530
|
|
|
2
|
|
|
|
|
191
|
|
8
|
2
|
|
|
2
|
|
16
|
use vars qw(@ISA $VERSION @EXPORT_OK); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
710
|
|
9
|
|
|
|
|
|
|
$VERSION = '0.15'; |
10
|
|
|
|
|
|
|
@ISA = qw(DynaLoader Exporter); |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
13
|
2
|
|
|
2
|
1
|
618
|
sub dl_load_flags { 0x01 } |
14
|
|
|
|
|
|
|
HTTP::MHTTP->bootstrap($VERSION); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# the supported request headers |
18
|
|
|
|
|
|
|
my $headers = { |
19
|
|
|
|
|
|
|
'Accept-Encoding' => '0', |
20
|
|
|
|
|
|
|
'Accept-Language' => '1', |
21
|
|
|
|
|
|
|
'Connection' => '2', |
22
|
|
|
|
|
|
|
'Cookie' => '3', |
23
|
|
|
|
|
|
|
'Host' => '4', |
24
|
|
|
|
|
|
|
'User-Agent' => '5', |
25
|
|
|
|
|
|
|
'Authorization' => '6', |
26
|
|
|
|
|
|
|
'Accept' => '7', |
27
|
|
|
|
|
|
|
'SOAPAction' => '8', |
28
|
|
|
|
|
|
|
'Content-Type' => '9', |
29
|
|
|
|
|
|
|
'Cache-control' => '10', |
30
|
|
|
|
|
|
|
'Cache-Control' => '10', |
31
|
|
|
|
|
|
|
'Accept-Charset' => '11', |
32
|
|
|
|
|
|
|
'Pragma' => '12', |
33
|
|
|
|
|
|
|
'Referrer' => '13', |
34
|
|
|
|
|
|
|
'Referer' => '13', |
35
|
|
|
|
|
|
|
'Keep-Alive' => '14', |
36
|
|
|
|
|
|
|
'If-Modified-Since' => '15', |
37
|
|
|
|
|
|
|
'Content-type' => '16', |
38
|
|
|
|
|
|
|
}; |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head1 NAME |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
HTTP::MHTTP - this library provides reasonably low level access to the HTTP protocol, for perl. This does not replace LWP (what possibly could :-) but is a cut for speed. |
45
|
|
|
|
|
|
|
It also supports all of HTTP 1.0, so you have GET, POST, PUT, HEAD, and DELETE. |
46
|
|
|
|
|
|
|
Some support of HTTP 1.1 is available - sepcifically Transfer-Encoding = chunked and the Keep-Alive extensions. |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
Additionally - rudimentary SSL support can be compiled in. This effectively enables negotiation of TLS, but does not validate the certificates. |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=head1 SYNOPSIS |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
use HTTP::MHTTP; |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
http_init(); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
http_add_headers( |
58
|
|
|
|
|
|
|
'User-Agent' => 'DVSGHTTP1/1', |
59
|
|
|
|
|
|
|
'Accept-Language' => 'en-gb', |
60
|
|
|
|
|
|
|
'Connection' => 'Keep-Alive', |
61
|
|
|
|
|
|
|
); |
62
|
|
|
|
|
|
|
if (http_call("GET", "http://localhost")){ |
63
|
|
|
|
|
|
|
if (http_status() == 200 ){ |
64
|
|
|
|
|
|
|
print http_response(); |
65
|
|
|
|
|
|
|
} else { |
66
|
|
|
|
|
|
|
print "MSG: ".http_reason(); |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
} else { |
69
|
|
|
|
|
|
|
print "call failed \n"; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=head1 DESCRIPTION |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
A way faster http access library that uses C extension based on mhttp |
76
|
|
|
|
|
|
|
to do the calls. |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 http_init() |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
initialise the mhttp library - must be called once to reset all internals, |
81
|
|
|
|
|
|
|
use http_reset() if you don't need to reset your headers before the next call. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=head2 http_set_protocol() |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
http_set_protocol(1); # now operating in HTTP 1.1 mode |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
Set the protocol level to use - either HTTP 1.0 or 1.1 by passing 0 or 1 - |
89
|
|
|
|
|
|
|
the default is 0 (HTTP 1.0). |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 http_reset() |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
reset the library internals for everything except the headers specified |
95
|
|
|
|
|
|
|
previously, and the debug switch. Call http_init() if you need to reset |
96
|
|
|
|
|
|
|
everything. |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head2 switch_debug() |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
switch_debug(<0 || 1>) |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Toggle the internal debugging on and off by passing either > 1 or 0. |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head2 http_add_headers() |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
http_add_headers( |
109
|
|
|
|
|
|
|
'User-Agent' => 'HTTP-MHTTP1/0', |
110
|
|
|
|
|
|
|
'Host' => 'localhost', |
111
|
|
|
|
|
|
|
'Accept-Language' => 'en-gb', |
112
|
|
|
|
|
|
|
); |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
pass in header/value pairs that will be set on the next http_call(). |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=head2 http_body() |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
http_body("this is the body"); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
Set the body of the next request via http_call(). |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=head2 http_call() |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
my $rc = http_call("GET", "http://localhost"); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
Do an http request. Returns either < 0 or 1 depending on whether the call was |
129
|
|
|
|
|
|
|
successful - remember to still check the http_status() code though. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Value < 0 are: |
132
|
|
|
|
|
|
|
-1 : an invalid action (HTTP verb) was supplied |
133
|
|
|
|
|
|
|
-2 : must supply an action (HTTP verb) |
134
|
|
|
|
|
|
|
-3 : must supply a url |
135
|
|
|
|
|
|
|
-4 : url must start with http:// or https:// |
136
|
|
|
|
|
|
|
-5 : write of headers to socket failed |
137
|
|
|
|
|
|
|
-6 : write of data to socket was short |
138
|
|
|
|
|
|
|
-7 : failed to write last line to socket |
139
|
|
|
|
|
|
|
-8 : something wrong with the Conent-Length header |
140
|
|
|
|
|
|
|
-11 : SSL_CTX_new failed - abort everything |
141
|
|
|
|
|
|
|
-12 : SSL_new failed - abort everything |
142
|
|
|
|
|
|
|
-13 : SSL_connect failed - abort everything |
143
|
|
|
|
|
|
|
-14 : SSL_get_peer_certificate failed - abort everything |
144
|
|
|
|
|
|
|
-15 : X509_get_subject_name failed - abort everything |
145
|
|
|
|
|
|
|
-16 : X509_get_issuer_name failed - abort everything |
146
|
|
|
|
|
|
|
-17 : cant find the next chunk for Transfer-encoding |
147
|
|
|
|
|
|
|
-18 : cant find end headers |
148
|
|
|
|
|
|
|
-19 : You must supply a Host header for HTTP/1.1 |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head2 http_status() |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Returns the last status code. |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head2 http_reason() |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Returns the last reason code. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=head2 http_headers() |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
Returns the headers of the last call, as a single string. |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head2 http_split_headers() |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Returns the split out array ref of array ref header value pairs of the last call. |
169
|
|
|
|
|
|
|
[ [ hdr, val], [hdr, val] ... ] |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 http_response_length() |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Returns the length of the body of the last call. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head2 http_response() |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Returns the body of the last call. |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head2 basic_authorization() |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
my $pass = basic_authorization($user, $password); |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Construct the basic authorization value to be passed in an "Authorization" |
187
|
|
|
|
|
|
|
header. |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head1 COPYRIGHT |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Copyright (c) 2003, Piers Harding. All Rights Reserved. |
193
|
|
|
|
|
|
|
This module is free software. It may be used, redistributed |
194
|
|
|
|
|
|
|
and/or modified under the same terms as Perl itself. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=head1 AUTHOR |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
Piers Harding, piers@ompa.net. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=head1 SEE ALSO |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
perl(1) |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=cut |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# export the open command, and initialise http::mhttp |
209
|
|
|
|
|
|
|
my @export_ok = ("http_reset", "http_init", "http_add_headers", "http_status", "http_reason", "http_call", "http_headers", "http_split_headers", "http_body", "http_response", "basic_authorization", "switch_debug", "http_response_length", "http_set_protocol" ); |
210
|
|
|
|
|
|
|
sub import { |
211
|
|
|
|
|
|
|
|
212
|
2
|
|
|
2
|
|
17
|
my ( $caller ) = caller; |
213
|
|
|
|
|
|
|
|
214
|
2
|
|
|
|
|
5
|
my ($me, $debug) = @_; |
215
|
|
|
|
|
|
|
|
216
|
2
|
|
|
2
|
|
13
|
no strict 'refs'; |
|
2
|
|
|
|
|
20
|
|
|
2
|
|
|
|
|
1018
|
|
217
|
2
|
|
|
|
|
13
|
foreach my $sub ( @export_ok ){ |
218
|
28
|
|
|
|
|
26
|
*{"${caller}::${sub}"} = \&{$sub}; |
|
28
|
|
|
|
|
5005
|
|
|
28
|
|
|
|
|
127
|
|
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub http_add_headers { |
225
|
2
|
|
|
2
|
1
|
5244105
|
my $hdrs = { @_ }; |
226
|
2
|
|
|
|
|
21
|
foreach my $header ( keys %$hdrs ){ |
227
|
8
|
50
|
|
|
|
20
|
if ( exists $headers->{$header} ){ |
228
|
8
|
|
|
|
|
36
|
add_header($header.": ".$hdrs->{$header}); |
229
|
|
|
|
|
|
|
} else { |
230
|
0
|
|
|
|
|
|
warn "Invalid header specified: $header - $hdrs->{$header} \n"; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
sub http_split_headers { |
237
|
|
|
|
|
|
|
|
238
|
0
|
|
|
0
|
1
|
|
my $headers = []; |
239
|
0
|
|
|
|
|
|
foreach my $h (split(/\n/,http_headers())){ |
240
|
0
|
0
|
|
|
|
|
next unless $h =~ /:/; |
241
|
0
|
|
|
|
|
|
my ($hdr,$val) = $h =~ /^(.*?):\s(.*?)$/; |
242
|
0
|
|
|
|
|
|
$val =~ s/[\n\r]//g; |
243
|
0
|
|
|
|
|
|
push (@$headers, [$hdr, $val]); |
244
|
|
|
|
|
|
|
#$headers->{$hdr} = $val; |
245
|
|
|
|
|
|
|
} |
246
|
0
|
|
|
|
|
|
return $headers; |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub basic_authorization{ |
252
|
0
|
|
|
0
|
1
|
|
my ( $user, $passwd ) = @_; |
253
|
0
|
|
|
|
|
|
return "Basic ".encode_base64( $user.':'.$passwd, "" ); |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
1; |