First pass at adding key files
This commit is contained in:
263
site/slowtwitch.com/cgi-bin/articles/GT/WWW/http/Response.pm
Normal file
263
site/slowtwitch.com/cgi-bin/articles/GT/WWW/http/Response.pm
Normal file
@ -0,0 +1,263 @@
|
||||
# ====================================================================
|
||||
# Gossamer Threads Module Library - http://gossamer-threads.com/
|
||||
#
|
||||
# GT::WWW::http::Response
|
||||
# Author: Jason Rhinelander
|
||||
# CVS Info : 087,071,086,086,085
|
||||
# $Id: Response.pm,v 1.8 2004/08/04 19:23:07 jagerman Exp $
|
||||
#
|
||||
# Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved.
|
||||
# ====================================================================
|
||||
#
|
||||
# Description:
|
||||
# Response object for GT::WWW HTTP/HTTPS requests.
|
||||
#
|
||||
|
||||
package GT::WWW::http::Response;
|
||||
use strict;
|
||||
|
||||
use vars qw/$AUTOLOAD/;
|
||||
use overload
|
||||
'""' => \&content,
|
||||
bool => \&boolean,
|
||||
cmp => \&strcmp;
|
||||
use Carp;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
$class = ref $class if ref $class;
|
||||
|
||||
my $self = {};
|
||||
bless $self, $class;
|
||||
}
|
||||
|
||||
AUTOLOAD {
|
||||
my ($self, @args) = @_;
|
||||
my ($attr) = $AUTOLOAD =~ /([^:]+)$/;
|
||||
if (@args) {
|
||||
$self->{$attr} = shift @args;
|
||||
}
|
||||
$self->{$attr};
|
||||
}
|
||||
|
||||
sub content { $_[0]->{content} }
|
||||
|
||||
sub boolean { 1 } # So you can you do things like: $www->get() or die
|
||||
|
||||
sub status {
|
||||
my $self = shift;
|
||||
if (@_) {
|
||||
my ($num, $str) = @_;
|
||||
$self->{status} = GT::WWW::http::Response::Status->new($num, $str);
|
||||
}
|
||||
$self->{status};
|
||||
}
|
||||
|
||||
sub header {
|
||||
my $self = shift;
|
||||
if (@_) {
|
||||
$self->{header}->header(@_);
|
||||
}
|
||||
else {
|
||||
$self->{header};
|
||||
}
|
||||
}
|
||||
|
||||
sub strcmp { $_[2] ? $_[1] cmp $_[0]->{content} : $_[0]->{content} cmp $_[1] }
|
||||
|
||||
package GT::WWW::http::Response::Status;
|
||||
|
||||
use overload
|
||||
'""' => \&string,
|
||||
bool => \&boolean,
|
||||
'0+' => \&numeric,
|
||||
'+' => \&addition,
|
||||
'<=>' => \&numcmp,
|
||||
'cmp' => \&strcmp;
|
||||
|
||||
sub new {
|
||||
my ($class, $numeric, $string) = @_;
|
||||
my $self = [$numeric, $string];
|
||||
bless $self, $class;
|
||||
}
|
||||
|
||||
sub numeric { $_[0]->[0] }
|
||||
sub string { "$_[0]->[0] $_[0]->[1]" }
|
||||
sub boolean { substr($_[0]->[0], 0, 1) eq '2' }
|
||||
sub addition { int($_[0]) + int($_[1]) }
|
||||
sub numcmp { $_[2] ? $_[1] <=> $_[0]->[0] : $_[0]->[0] <=> $_[1] }
|
||||
sub strcmp { $_[2] ? $_[1] cmp $_[0]->[1] : $_[0]->[1] cmp $_[1] }
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
GT::WWW::http::Response and GT::WWW::http::Response::Status - Overloaded
|
||||
response objects for HTTP request data.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# ($www is continued from GT::WWW::http SYNOPSIS)
|
||||
|
||||
my $response = $www->get(); # or post(), or head()
|
||||
# -- or, after having called get(), post() or head(): --
|
||||
my $response = $www->response();
|
||||
|
||||
my $status = $response->status();
|
||||
|
||||
my $content = "$response";
|
||||
my $response_code = int($status); # i.e. 200, 404, 500
|
||||
my $response_str = "$status"; # i.e. 'OK', 'Not Found', 'Internal Server Error'
|
||||
if ($status) { # True for 2xx requests, false otherwise (e.g. 404, 500, etc.)
|
||||
...
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
GT::WWW::http::Response objects are returned by the L<C<get()>|GT::WWW/get>,
|
||||
L<C<post()>|GT::WWW/post>, and L<C<head()>|GT::WWW/head> methods of GT::WWW
|
||||
HTTP requests (and derivatives - i.e. HTTPS), or by calling
|
||||
L<C<response()>|GT::WWW::http/response> after having made such a request. The
|
||||
objects are overloaded in order to provide a simple interface to the response,
|
||||
while still having all the information available.
|
||||
|
||||
A response object always returns true in boolean context, allowing you to do
|
||||
things like C<$www-E<gt>get($url) or die;> - even when a page is empty, or
|
||||
contains just '0'.
|
||||
|
||||
=head1 CONTENT
|
||||
|
||||
In addition to the methods described below, the way to simply access the data
|
||||
returned by the server is to simply use it like a string - for example,
|
||||
printing it, concatenating it with another string, or quoting it.
|
||||
|
||||
You should, however, take note that when using the L<C<chunk()>|GT::WWW/chunk>
|
||||
option for an HTTP request, the content will not be available.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
For simple requests, often the content alone is enough. The following methods
|
||||
are used to determine any other information available about the response.
|
||||
|
||||
=head2 content
|
||||
|
||||
Returns the content of the HTTP response. Note that this returns the exact
|
||||
same value as using the object in double quotes.
|
||||
|
||||
=head2 status
|
||||
|
||||
Returns the response status object for the request. This object provides three
|
||||
pieces of information, and has no public methods. Instead, the data is
|
||||
retrieved based on the context of the object.
|
||||
|
||||
my $status = $response->status;
|
||||
|
||||
(N.B. Though the examples below use a C<$status> variable, there is no reason
|
||||
they couldn't be written to use C<$response-E<gt>status> instead.)
|
||||
|
||||
=over 4
|
||||
|
||||
=item numeric status
|
||||
|
||||
The numeric status of an HTTP request (e.g. 200, 404, 500) is available simply
|
||||
by using the status object as a number.
|
||||
|
||||
my $numeric_status = int $status;
|
||||
|
||||
=item string status
|
||||
|
||||
The string status of an HTTP request (e.g. "OK", "Not Found", "Internal Server
|
||||
Error") is available by using the status object as a string (e.g. printing it,
|
||||
or concatenating it with another string).
|
||||
|
||||
# Assign the status string to a variable:
|
||||
my $status_string = "$status";
|
||||
|
||||
# Print out the status string:
|
||||
print $status;
|
||||
|
||||
# To get a string such as "500 Internal Server Error":
|
||||
my $string = int($status) . " " . $status;
|
||||
|
||||
=item boolean status
|
||||
|
||||
In order to quickly determine whether or not a request was successful, you can
|
||||
use the status object in a boolean context.
|
||||
|
||||
Success is determined by the numeric status of the response. Any 2xx status
|
||||
(usually 200 OK, but there are others) counts as a successful response, while
|
||||
any other status counts as a failure.
|
||||
|
||||
if ($status) { print "Request successful!" }
|
||||
else { print "Request failed!" }
|
||||
|
||||
=back
|
||||
|
||||
=head2 header
|
||||
|
||||
This method, called without arguments, returns the
|
||||
L<header|GT::WWW::http::Header> object for the response.
|
||||
|
||||
my $header = $response->header;
|
||||
|
||||
If this method is called with arguments, those arguments are passed to the
|
||||
L<C<header()>|GT::WWW::http::Header/header> method of the header object. This
|
||||
allows this useful shortcut:
|
||||
|
||||
my $some_header_value = $response->header("Some-Header");
|
||||
|
||||
instead of the alternative (which also works):
|
||||
|
||||
my $some_header_value = $response->header->header("Some-Header");
|
||||
|
||||
Information on header object usage is contained in L<GT::WWW::http::Header>.
|
||||
|
||||
Note that although a header object allows for header manipulation, changing the
|
||||
headers of a response object should be considered bad practise, and is strongly
|
||||
discouraged.
|
||||
|
||||
=head1 CAVEATS
|
||||
|
||||
Although the response object _works_ like a string, keep in mind that it is
|
||||
still an object, and thus a reference. If you intend to pass the data to
|
||||
another subroutine expecting a string, it is recommended that you force the
|
||||
content into string form, either by quoting the variable (C<"$var">) or by
|
||||
calling the content() method (C<$var-E<gt>content>). Not doing so can lead to
|
||||
unexpected results, particularly in cases where another subroutine may
|
||||
differentiate between a string and a reference, and not just use the value as a
|
||||
string.
|
||||
|
||||
Also, in terms of speed, obtaining the content (not the object) into another
|
||||
variable (either via C<"$var"> or C<$var-E<gt>content>) can make quite a
|
||||
substantial difference when several string comparison operations are performed.
|
||||
The reason is simply that every time the object is used is a string, the
|
||||
content method is called, which can amount to a significant slowdown.
|
||||
|
||||
Although string operations that change the string (i.e. s///) appear to work,
|
||||
they in fact clobber the reference and turn your variable into an ordinary
|
||||
string. This should not be done - if the string needs to be modified, take a
|
||||
copy of it first, and modify the copy.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<GT::WWW>
|
||||
L<GT::WWW::http>
|
||||
L<GT::WWW::http::Header>
|
||||
RFC 2616: L<http://www.ietf.org/rfc/rfc2616.txt>
|
||||
|
||||
=head1 MAINTAINER
|
||||
|
||||
Jason Rhinelander
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved.
|
||||
http://www.gossamer-threads.com/
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Revision: $Id: Response.pm,v 1.8 2004/08/04 19:23:07 jagerman Exp $
|
||||
|
||||
=cut
|
Reference in New Issue
Block a user