1 package Net::HTTPS::Any;
5 use vars qw(@ISA @EXPORT_OK $ssl_module $skip_NetSSLeay);
10 @ISA = qw( Exporter );
11 @EXPORT_OK = qw( https_get https_post );
18 die if defined($skip_NetSSLeay) && $skip_NetSSLeay;
20 Net::SSLeay->VERSION(1.30);
23 # qw(get_https post_https make_form make_headers);
24 $ssl_module = 'Net::SSLeay';
29 require LWP::UserAgent;
30 require HTTP::Request::Common;
31 require Crypt::SSLeay;
33 #import HTTP::Request::Common qw(GET POST);
34 $ssl_module = 'Crypt::SSLeay';
38 unless ($ssl_module) {
39 die "One of Net::SSLeay (v1.30 or later)"
40 . " or Crypt::SSLeay (+LWP) is required";
47 Net::HTTPS::Any - Simple HTTPS class using whatever underlying module is available
55 our $VERSION = '0.09';
59 use Net::HTTPS::Any qw(https_get https_post);
61 ( $page, $response, %reply_headers )
63 { 'host' => 'secure.sisd.com',
65 'path' => '/freeside/index.html',
66 'args' => { 'field' => 'value' },
67 #'args' => [ 'field'=>'value' ], #order preserved
71 ( $page, $response, %reply_headers )
73 'host' => 'secure.sisd.com',
75 'path' => '/freeside/index.html',
76 'args' => { 'field' => 'value' },
77 #'args' => [ 'field'=>'value' ], #order preserved
84 This is a simple wrapper around either of the two available SSL
85 modules. It offers a unified API for send GET and POST requests over HTTPS
86 and receiving responses.
88 It depends on Net::SSLeay _or_ ( Crypt::SSLeay and LWP::UserAgent ).
92 =head2 https_get HASHREF | FIELD => VALUE, ...
94 Accepts parameters as either a hashref or a list of fields and values.
106 =item headers (hashref)
108 For example: { 'X-Header1' => 'value', ... }
112 For example: 'text/namevalue',
116 CGI arguments, eitehr as a hashref or a listref. In the latter case, ordering
117 is preserved (see L<Tie::IxHash> to do so when passing a hashref).
123 Returns a list consisting of the page content as a string, the HTTP
124 response code and message (i.e. "200 OK" or "404 Not Found"), and a list of
125 key/value pairs representing the HTTP response headers.
130 my $opts = ref($_[0]) ? shift : { @_ }; #hashref or list
132 # accept a hashref or a list (keep it ordered)
134 if ( exists($opts->{'args'}) && ref($opts->{'args'}) eq 'HASH' ) {
135 $post_data = $opts->{'args'};
136 } elsif ( exists($opts->{'args'}) && ref($opts->{'args'}) eq 'ARRAY' ) {
137 tie my %hash, 'Tie::IxHash', @{ $opts->{'args'} };
141 $opts->{'port'} ||= 443;
142 #$opts->{"Content-Type"} ||= "application/x-www-form-urlencoded";
146 if ( ref( $opts->{headers} ) eq "HASH" ) {
147 %headers = %{ $opts->{headers} };
149 $headers{'Host'} ||= $opts->{'host'};
151 my $path = $opts->{'path'};
152 if ( keys %$post_data ) {
155 map { uri_escape($_) . '=' . uri_escape( $post_data->{$_} ) }
159 if ( $ssl_module eq 'Net::SSLeay' ) {
161 import Net::SSLeay qw(get_https make_headers);
162 my $headers = make_headers(%headers);
164 $Net::SSLeay::trace = $opts->{'debug'}
165 if exists $opts->{'debug'} && $opts->{'debug'};
167 my( $res_page, $res_code, @res_headers ) =
168 get_https( $opts->{'host'},
173 $opts->{"Content-Type"},
176 return ( $res_page, $res_code, @res_headers );
178 } elsif ( $ssl_module eq 'Crypt::SSLeay' ) {
180 import HTTP::Request::Common qw(GET);
182 my $url = 'https://' . $opts->{'host'};
183 $url .= ':' . $opts->{'port'}
184 unless $opts->{'port'} == 443;
187 my $ua = new LWP::UserAgent;
188 foreach my $hdr ( keys %headers ) {
189 $ua->default_header( $hdr => $headers{$hdr} );
191 $ENV{HTTPS_DEBUG} = $opts->{'debug'} if exists $opts->{'debug'};
192 my $res = $ua->request( GET($url) );
194 my @res_headers = map { $_ => $res->header($_) }
195 $res->header_field_names;
197 return ( $res->content, $res->code. ' '. $res->message, @res_headers );
200 die "unknown SSL module $ssl_module";
205 =head2 https_post HASHREF | FIELD => VALUE, ...
207 Accepts parameters as either a hashref or a list of fields and values.
219 =item headers (hashref)
221 For example: { 'X-Header1' => 'value', ... }
225 For example: 'text/namevalue',
229 CGI arguments, eitehr as a hashref or a listref. In the latter case, ordering
230 is preserved (see L<Tie::IxHash> to do so when passing a hashref).
234 Raw content (overrides args). A simple scalar containing the raw content.
239 Returns a list consisting of the page content as a string, the HTTP
240 response code and message (i.e. "200 OK" or "404 Not Found"), and a list of
241 key/value pairs representing the HTTP response headers.
246 my $opts = ref($_[0]) ? shift : { @_ }; #hashref or list
248 # accept a hashref or a list (keep it ordered). or a scalar of content.
250 if ( exists($opts->{'args'}) && ref($opts->{'args'}) eq 'HASH' ) {
251 $post_data = $opts->{'args'};
252 } elsif ( exists($opts->{'args'}) && ref($opts->{'args'}) eq 'ARRAY' ) {
253 tie my %hash, 'Tie::IxHash', @{ $opts->{'args'} };
256 if ( exists $opts->{'content'} ) {
257 $post_data = $opts->{'content'};
260 $opts->{'port'} ||= 443;
261 $opts->{"Content-Type"} ||= "application/x-www-form-urlencoded";
265 if ( ref( $opts->{headers} ) eq "HASH" ) {
266 %headers = %{ $opts->{headers} };
268 $headers{'Host'} ||= $opts->{'host'};
270 if ( $ssl_module eq 'Net::SSLeay' ) {
272 import Net::SSLeay qw(post_https make_headers make_form);
273 my $headers = make_headers(%headers);
275 my $raw_data = ref($post_data) ? make_form(%$post_data) : $post_data;
277 $Net::SSLeay::trace = $opts->{'debug'}
278 if exists $opts->{'debug'} && $opts->{'debug'};
280 my( $res_page, $res_code, @res_headers ) =
281 post_https( $opts->{'host'},
286 $opts->{"Content-Type"},
289 return ( $res_page, $res_code, @res_headers );
291 } elsif ( $ssl_module eq 'Crypt::SSLeay' ) {
293 import HTTP::Request::Common qw(POST);
295 my $url = 'https://' . $opts->{'host'};
296 $url .= ':' . $opts->{'port'}
297 unless $opts->{'port'} == 443;
298 $url .= $opts->{'path'};
300 my $ua = new LWP::UserAgent;
301 foreach my $hdr ( keys %headers ) {
302 $ua->default_header( $hdr => $headers{$hdr} );
305 $ENV{HTTPS_DEBUG} = $opts->{'debug'} if exists $opts->{'debug'};
308 if ( ref($post_data) ) {
309 $res = $ua->request( POST( $url, [%$post_data] ) );
312 my $req = new HTTP::Request( 'POST' => $url );
313 $req->content_type( $opts->{"Content-Type"} );
314 $req->content($post_data);
315 $res = $ua->request($req);
318 my @res_headers = map { $_ => $res->header($_) }
319 $res->header_field_names;
321 return ( $res->content, $res->code. ' '. $res->message, @res_headers );
324 die "unknown SSL module $ssl_module";
331 Ivan Kohler, C<< <ivan-net-https-any at freeside.biz> >>
335 Please report any bugs or feature requests to C<bug-net-https-any at rt.cpan.org>, or through
336 the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-HTTPS-Any>. I will be notified, and then you'll
337 automatically be notified of progress on your bug as I make changes.
341 You can find documentation for this module with the perldoc command.
343 perldoc Net::HTTPS::Any
346 You can also look for information at:
350 =item * RT: CPAN's request tracker
352 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-HTTPS-Any>
354 =item * AnnoCPAN: Annotated CPAN documentation
356 L<http://annocpan.org/dist/Net-HTTPS-Any>
360 L<http://cpanratings.perl.org/d/Net-HTTPS-Any>
364 L<http://search.cpan.org/dist/Net-HTTPS-Any>
369 =head1 ACKNOWLEDGEMENTS
372 =head1 COPYRIGHT & LICENSE
374 Copyright 2008 Freeside Internet Services, Inc. (http://freeside.biz/)
377 This program is free software; you can redistribute it and/or modify it
378 under the same terms as Perl itself.