File Coverage

blib/lib/Gungho/Request.pm
Criterion Covered Total %
statement 18 18 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 24 24 100.0


line stmt bran cond sub pod time code
1             # $Id: /mirror/gungho/lib/Gungho/Request.pm 31624 2007-12-01T04:20:00.298198Z lestrrat $
2             #
3             # Copyright (c) 2007 Daisuke Maki <daisuke@endeworks.jp>
4             # All rights reserved.
5              
6             package Gungho::Request;
7 1     1   3 use strict;
  1         1  
  1         39  
8 1     1   4 use warnings;
  1         1  
  1         21  
9 1     1   11 use base qw(HTTP::Request);
  1         1  
  1         11  
10 1     1   14441 use Storable qw(dclone);
  1         1  
  1         44  
11 1     1   4 use UNIVERSAL::require;
  1         0  
  1         6  
12 1     1   441 use Regexp::Common qw(net);
  1         1769  
  1         3  
13              
14             our $DIGEST;
15              
16             sub _find_digest_class
17             {
18             $DIGEST ||= do {
19             my $pkg;
20             foreach my $x qw(SHA1 MD5) {
21             my $candidate = "Digest::$x";
22             if ($candidate->require()) {
23             $pkg = $candidate;
24             last;
25             }
26             }
27             $pkg;
28             };
29             }
30              
31             sub new
32             {
33             my $class = shift;
34             my $self = $class->SUPER::new(@_);
35             $self->id; # Forcefully make the ID here.
36             $self->{_notes} = {};
37             return $self;
38             }
39              
40             sub id
41             {
42             my $self = shift;
43              
44             local $@ = undef;
45             $self->{_id} ||= do {
46             my $pkg = _find_digest_class() || die "Could not find Digest class";
47             my $digest = $pkg->new;
48              
49             $digest->add(map { defined $_ ? $_ : '' } (time(), {}, rand(), $self->method, $self->uri, $self->protocol));
50             $self->headers->scan(sub {
51             $digest->add(join(':', $_[0], $_[1]));
52             });
53             $digest->hexdigest;
54             };
55             die $@ if $@;
56             $self->{_id};
57             }
58              
59             sub clone
60             {
61             my $self = shift;
62             my $clone = $self->SUPER::clone;
63              
64             my $cloned_notes = dclone $self->notes;
65             foreach my $note (keys %$cloned_notes) {
66             $clone->notes( $note => $cloned_notes->{$note} );
67             }
68             return $clone;
69             }
70              
71             sub notes
72             {
73             my $self = shift;
74             my $key = shift;
75              
76             return $self->{_notes} unless $key;
77              
78             my $value = $self->{_notes}{$key};
79             if (@_) {
80             $self->{_notes}{$key} = $_[0];
81             }
82             return $value;
83             }
84              
85             sub original_uri
86             {
87             my $self = shift;
88             my $uri = $self->uri->clone;
89             if (my $host = $self->notes('original_host')) {
90             $uri->host($host);
91             }
92             return $uri;
93             }
94              
95             sub requires_name_lookup
96             {
97             my $self = shift;
98             return ! $self->notes('resolved_ip') &&
99             ($self->uri->can('host') && $self->uri->host() !~ /^$RE{net}{IPv4}$/);
100             }
101              
102             sub format
103             {
104             my $self = shift;
105             my $scheme = $self->uri->scheme;
106             my $pkg = "Gungho::Request::$scheme";
107              
108             require Class::Inspector;
109             Class::Inspector->loaded($pkg) or $pkg->require or die;
110              
111             my $protocol = $pkg->new;
112             $protocol->format($self);
113             }
114              
115             1;
116              
117             __END__
118              
119             =head1 NAME
120              
121             Gungho::Request - A Gungho Request Object
122              
123             =head1 DESCRIPTION
124              
125             Currently this class is exactly the same as HTTP::Request, but we're
126             creating this separately in anticipation for a possible change
127              
128             =head1 METHODS
129              
130             =head2 new()
131              
132             Creates a new Gungho::Request instance
133              
134             =head2 id()
135              
136             Returns a Unique ID for this request
137              
138             =head2 clone()
139              
140             Clones the request.
141              
142             =head2 notes($key[, $value])
143              
144             Associate arbitrary notes to the request
145              
146             =head2 original_uri
147              
148             Returns a cloned copy of the request URI, with the host name swapped to
149             the original hostname before DNS substitution
150              
151             =head2 requires_name_lookup
152              
153             Returns true if the request object's uri host is not in an IP address format
154              
155             =head2 format
156              
157             Formats the request so that it's appropriate to send through a socket.
158              
159             =cut