comparison variant_effect_predictor/Bio/Root/HTTPget.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1f6dce3d34e0
1 # $Id: HTTPget.pm,v 1.4 2002/10/22 07:38:37 lapp Exp $
2 #
3 # BioPerl module for fallback HTTP get operations.
4 # Module is proxy-aware
5 #
6 # Cared for by Chris Dagdigian <dag@sonsorol.org>
7 # but all of the good stuff was written by
8 # Lincoln Stein.
9 #
10 # You may distribute this module under the same terms as perl itself
11
12 # POD documentation - main docs before the code
13
14 =head1 NAME
15
16 Bio::Root::HTTPget - module for fallback HTTP get operations when
17 LWP:: is unavailable
18
19 =head1 SYNOPSIS
20
21 Use Bio::Root::HTTPget;
22
23 my $response = get('http://localhost');
24 $response = get('http://localhost/images');
25
26 $response = eval { get('http://fred:secret@localhost/ladies_only/')
27 } or warn $@;
28
29 $response = eval { get('http://jeff:secret@localhost/ladies_only/')
30 } or warn $@;
31
32 $response = get('http://localhost/images/navauthors.gif');
33 $response = get(-url=>'http://www.google.com',
34 -proxy=>'http://www.modperl.com');
35
36 =head1 DESCRIPTION
37
38 This is basically an last-chance module for doing network HTTP get requests in
39 situations where more advanced external CPAN modules such as LWP:: are not
40 installed.
41
42 The particular reason this module was developed was so that the Open Bio
43 Database Access code can fallback to fetching the default registry files
44 from http://open-bio.org/registry/ without having to depend on
45 external dependencies like Bundle::LWP for network HTTP access.
46
47 The core of this module was written by Lincoln Stein. It can handle proxies
48 and HTTP-based proxy authentication.
49
50 =head1 FEEDBACK
51
52 =head2 Mailing Lists
53
54 User feedback is an integral part of the evolution of this
55 and other Bioperl modules. Send your comments and suggestions preferably
56 to one of the Bioperl mailing lists.
57 Your participation is much appreciated.
58
59 bioperl-l@bioperl.org - General discussion
60 http://bio.perl.org/MailList.html - About the mailing lists
61
62 =head2 Reporting Bugs
63
64 Report bugs to the Bioperl bug tracking system to help us keep track
65 the bugs and their resolution.
66 Bug reports can be submitted via email or the web:
67
68 bioperl-bugs@bio.perl.org
69 http://bugzilla.bioperl.org/
70
71 =head1 AUTHOR - Lincoln Stein
72
73 Cared for by Chris Dagdigian <dag@sonsorol.org>
74
75 =head1 APPENDIX
76
77 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
78
79 =cut
80
81
82 # Let the code begin...
83
84 package Bio::Root::HTTPget;
85
86 use strict;
87 use Bio::Root::Root;
88 use IO::Socket qw(:DEFAULT :crlf);
89 use vars '@ISA';
90
91 @ISA = qw(Bio::Root::Root);
92
93
94 =head2 get
95
96 Title : get
97 Usage :
98 Function:
99 Example :
100 Returns : string
101 Args :
102
103 =cut
104
105 sub get {
106 my ($url,$proxy,$timeout,$auth_user,$auth_pass) =
107 __PACKAGE__->_rearrange([qw(URL PROXY TIMEOUT USER PASS)],@_);
108 my $dest = $proxy || $url;
109
110 my ($host,$port,$path,$user,$pass)
111 = _http_parse_url($dest) or __PACKAGE__->throw("invalid URL $url");
112 $auth_user ||= $user;
113 $auth_pass ||= $pass;
114 $path = $url if $proxy;
115
116 # set up the connection
117 my $socket = _http_connect($host,$port) or __PACKAGE__->throw("can't connect: $@");
118
119 # the request
120 print $socket "GET $path HTTP/1.0$CRLF";
121 print $socket "User-Agent: Bioperl fallback fetcher/1.0$CRLF";
122 # Support virtual hosts
123 print $socket "HOST: $host$CRLF";
124
125 if ($auth_user && $auth_pass) { # authentication information
126 my $token = _encode_base64("$auth_user:$auth_pass");
127 print $socket "Authorization: Basic $token$CRLF";
128 }
129 print $socket "$CRLF";
130
131 # read the response
132 my $response;
133 {
134 local $/ = "$CRLF$CRLF";
135 $response = <$socket>;
136 }
137
138 my ($status_line,@other_lines) = split $CRLF,$response;
139 my ($stat_code,$stat_msg) = $status_line =~ m!^HTTP/1\.[01] (\d+) (.+)!
140 or __PACKAGE__->throw("invalid response from web server: got $response");
141
142 my %headers = map {/^(\S+): (.+)/} @other_lines;
143 if ($stat_code == 302 || $stat_code == 301) { # redirect
144 my $location = $headers{Location} or __PACKAGE__->throw("invalid redirect: no Location header");
145 return get($location,$proxy,$timeout); # recursive call
146 }
147
148 elsif ($stat_code == 401) { # auth required
149 my $auth_required = $headers{'WWW-Authenticate'};
150 $auth_required =~ /^Basic realm="([^\"]+)"/
151 or __PACKAGE__->throw("server requires unknown type of authentication: $auth_required");
152 __PACKAGE__->throw("request failed: $status_line, realm = $1");
153 }
154
155 elsif ($stat_code != 200) {
156 __PACKAGE__->throw("request failed: $status_line");
157 }
158
159 $response = '';
160 while (1) {
161 my $bytes = read($socket,$response,2048,length $response);
162 last unless $bytes > 0;
163 }
164
165 $response;
166 }
167
168 =head2 getFH
169
170 Title : getFH
171 Usage :
172 Function:
173 Example :
174 Returns : string
175 Args :
176
177 =cut
178
179 sub getFH {
180 my ($url,$proxy,$timeout,$auth_user,$auth_pass) =
181 __PACKAGE__->_rearrange([qw(URL PROXY TIMEOUT USER PASS)],@_);
182 my $dest = $proxy || $url;
183
184 my ($host,$port,$path,$user,$pass)
185 = _http_parse_url($dest) or __PACKAGE__->throw("invalid URL $url");
186 $auth_user ||= $user;
187 $auth_pass ||= $pass;
188 $path = $url if $proxy;
189
190 # set up the connection
191 my $socket = _http_connect($host,$port) or __PACKAGE__->throw("can't connect: $@");
192
193 # the request
194 print $socket "GET $path HTTP/1.0$CRLF";
195 print $socket "User-Agent: Bioperl fallback fetcher/1.0$CRLF";
196 # Support virtual hosts
197 print $socket "HOST: $host$CRLF";
198
199 if ($auth_user && $auth_pass) { # authentication information
200 my $token = _encode_base64("$auth_user:$auth_pass");
201 print $socket "Authorization: Basic $token$CRLF";
202 }
203 print $socket "$CRLF";
204
205 # read the response
206 my $response;
207 {
208 local $/ = "$CRLF$CRLF";
209 $response = <$socket>;
210 }
211
212 my ($status_line,@other_lines) = split $CRLF,$response;
213 my ($stat_code,$stat_msg) = $status_line =~ m!^HTTP/1\.[01] (\d+) (.+)!
214 or __PACKAGE__->throw("invalid response from web server: got $response");
215
216 my %headers = map {/^(\S+): (.+)/} @other_lines;
217 if ($stat_code == 302 || $stat_code == 301) { # redirect
218 my $location = $headers{Location} or __PACKAGE__->throw("invalid redirect: no Location header");
219 return get($location,$proxy,$timeout); # recursive call
220 }
221
222 elsif ($stat_code == 401) { # auth required
223 my $auth_required = $headers{'WWW-Authenticate'};
224 $auth_required =~ /^Basic realm="([^\"]+)"/
225 or __PACKAGE__->throw("server requires unknown type of authentication: $auth_required");
226 __PACKAGE__->throw("request failed: $status_line, realm = $1");
227 }
228
229 elsif ($stat_code != 200) {
230 __PACKAGE__->throw("request failed: $status_line");
231 }
232
233 # Now that we are reasonably sure the socket and request
234 # are OK we pass the socket back as a filehandle so it can
235 # be processed by the caller...
236
237 $socket;
238
239 }
240
241
242 =head2 _http_parse_url
243
244 Title :
245 Usage :
246 Function:
247 Example :
248 Returns :
249 Args :
250
251 =cut
252
253 sub _http_parse_url {
254 my $url = shift;
255 my ($user,$pass,$hostent,$path) =
256 $url =~ m!^http://(?:([^:]+):([^:]+)@)?([^/]+)(/?[^\#]*)! or return;
257 $path ||= '/';
258 my ($host,$port) = split(':',$hostent);
259 return ($host,$port||80,$path,$user,$pass);
260 }
261
262 =head2 _http_connect
263
264 Title :
265 Usage :
266 Function:
267 Example :
268 Returns :
269 Args :
270
271 =cut
272
273 sub _http_connect {
274 my ($host,$port,$timeout) = @_;
275 my $sock = IO::Socket::INET->new(Proto => 'tcp',
276 Type => SOCK_STREAM,
277 PeerHost => $host,
278 PeerPort => $port,
279 Timeout => $timeout,
280 );
281 $sock;
282 }
283
284
285 =head2 _encode_base64
286
287 Title :
288 Usage :
289 Function:
290 Example :
291 Returns :
292 Args :
293
294 =cut
295
296 sub _encode_base64 {
297 my $res = "";
298 my $eol = $_[1];
299 $eol = "\n" unless defined $eol;
300 pos($_[0]) = 0; # ensure start at the beginning
301
302 $res = join '', map( pack('u',$_)=~ /^.(\S*)/, ($_[0]=~/(.{1,45})/gs));
303
304 $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
305 # fix padding at the end
306 my $padding = (3 - length($_[0]) % 3) % 3;
307 $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
308 # break encoded string into lines of no more than 76 characters each
309 if (length $eol) {
310 $res =~ s/(.{1,76})/$1$eol/g;
311 }
312 return $res;
313 }
314
315 1;