File Coverage

blib/lib/MojoX/UserAgent/Transaction.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             # Copyright (C) 2009, Pascal Gaudette.
2              
3             package MojoX::UserAgent::Transaction;
4              
5 1     1   28740 use warnings;
  1         3  
  1         39  
6 1     1   6 use strict;
  1         2  
  1         38  
7              
8 1     1   5 use base 'Mojo::Transaction::Single';
  1         6  
  1         1058  
9              
10             use Carp 'croak';
11              
12             __PACKAGE__->attr('done_cb');
13             __PACKAGE__->attr('hops' => 0);
14             __PACKAGE__->attr('id');
15             __PACKAGE__->attr('original_req');
16             __PACKAGE__->attr('ua');
17              
18             sub new {
19             my $self = shift->SUPER::new();
20              
21             my ($arg_ref) = @_;
22             my $req = $self->req;
23              
24             croak('Missing arguments')
25             if ( !defined($arg_ref->{url})
26             || !defined($arg_ref->{ua}));
27              
28             $self->res->code(999); # Default response status should not be 200
29              
30             my $url = $arg_ref->{url};
31             ref $url && $url->isa('Mojo::URL')
32             ? $req->url($url)
33             : $req->url->parse($url);
34              
35             $self->ua($arg_ref->{ua});
36              
37             $arg_ref->{callback}
38             ? $self->done_cb($arg_ref->{callback})
39             : $self->done_cb($self->ua->default_done_cb);
40              
41             if ($arg_ref->{headers}) {
42             my $headers = $arg_ref->{headers};
43             for my $name (keys %{$headers}) {
44             $req->headers->header($name, $headers->{$name});
45             }
46             }
47              
48             $req->method($arg_ref->{method}) if $arg_ref->{method};
49             $req->body($arg_ref->{body}) if $arg_ref->{body};
50              
51             $self->id($arg_ref->{id}) if $arg_ref->{id};
52              
53             # Not sure if I should allow hops or
54             # original_req in the constructor...
55             $self->hops($arg_ref->{hops}) if $arg_ref->{hops};
56             $self->original_req($arg_ref->{original_req}) if $arg_ref->{original_req};
57              
58             return $self;
59             }
60              
61             sub client_connect {
62             my $self = shift;
63              
64             my $ua = $self->ua;
65              
66             # Add default headers
67              
68             if (my $dh = $ua->default_headers) {
69             for my $name (keys %{$dh}) {
70             $self->req->headers->header($name, $dh->{$name})
71             unless $self->req->headers->header($name);
72             }
73             }
74              
75             # Add cookies
76             # (What if req already had some cookies?)
77              
78             my $cookies = $ua->cookies_for_url($self->req->url);
79             $self->req->cookies(@{$cookies});
80              
81             # Add User-Agent identification
82              
83             unless ($self->req->headers->user_agent) {
84             my $ua_str = $ua->agent;
85             $self->req->headers->user_agent($ua_str) if $ua_str;
86             }
87              
88             $self->SUPER::client_connect();
89             return $self;
90             }
91             1;
92              
93             =head1 NAME
94              
95             MojoX::UserAgent::Transaction - Basic building block of
96             L, encapsulates a single HTTP exchange.
97              
98             =head1 SYNOPSIS
99              
100             my $tx = MojoX::UserAgent::Transaction->new(
101             { url => 'http://www.some.host.com/bla/',
102             method => 'POST',
103             ua => $ua,
104             id => '123456',
105             headers => {
106             'Expect' => '100-continue',
107             'Content-Type' => 'text/plain'
108             },
109             body => 'Hello!',
110             callback => sub {
111             my ($ua, $tx) = @_;
112             ok(!$tx->has_error, 'Completed');
113             is($tx->id, '123456', 'Request ID');
114             is($tx->res->code, 200, 'Status 200');
115             }
116             }
117             };
118              
119             $ua->spool($tx);
120              
121              
122             =head1 DESCRIPTION
123              
124             A subclass of L, this class simply adds
125             the few extra elements that are needed by L.
126              
127              
128             =head1 ATTRIBUTES
129              
130             This class inherits all the attributes of L, and
131             adds the following.
132              
133             =head2 C
134              
135             The subroutine that will be called once the transaction is completed.
136             When invoked, this sub is passed two arguments: the UserAgent object
137             that performed the transaction and the transaction itself.
138              
139             =head2 C
140              
141             The number of hops (ie redirects) that this transaction has gone through.
142              
143             =head2 C
144              
145             An optional transaction identifier. Not used internally by the class,
146             but preserved across redirects and accessible to the callback.
147              
148             =head2 C
149              
150             If the transaction is redirected, this holds the original request object.
151              
152             =head2 C
153              
154             A pointer back to the L to which this transaction was
155             spooled.
156              
157              
158             =head1 METHODS
159              
160             L inherits all methods from
161             L and implements the following new ones.
162              
163              
164             =head2 C
165              
166             Constructor that accepts a reference to a hash of named arguments.
167             This hash must contain the following key/value pairs:
168              
169             =over 2
170              
171             =item *
172              
173             key: 'url' value: either a string or a L object;
174              
175             =item *
176              
177             key: 'ua' value: a reference to the L object
178             to which this transaction belongs.
179              
180             =back
181              
182             It may also contain any/all of the following:
183              
184             =over 7
185              
186             =item *
187              
188             key: 'callback' value: the callback subroutine that will be
189             called when this transaction is finished (see done_cb above);
190              
191             =item *
192              
193             key: 'headers' value: a reference to a hash of request headers
194             (see L);
195              
196             =item *
197              
198             key: 'method' value: the HTTP method to be used in the request;
199              
200             =item *
201              
202             key: 'body' value: the contents of the body of the request;
203              
204             =item *
205              
206             key: 'id' value: the value of the id attribute (see above);
207              
208             =item *
209              
210             key: 'hops' value: the value of the hops attribute (see above,
211             should only be set by the User-Agent);
212              
213             =item *
214              
215             key: 'original_req' value: the original L
216             object iff hops isn't 0.
217              
218             =back
219              
220             =head2 C
221              
222             Called when the transaction is about to be sent out, this method is
223             used to add the User-Agent and request cookies to the outgoing
224             request.
225              
226             =cut