Fixing HTTP.pm
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine / Test.pm
CommitLineData
e646f111 1package Catalyst::Engine::Test;
2
3use strict;
75fd617a 4use base 'Catalyst::Engine';
5
523d44ec 6use CGI::Cookie;
75fd617a 7use Class::Struct ();
8use HTTP::Headers::Util 'split_header_words';
9use HTTP::Request;
10use HTTP::Response;
11use IO::File;
12use URI;
13
14__PACKAGE__->mk_accessors(qw/lwp/);
15
16Class::Struct::struct 'Catalyst::Engine::Test::LWP' => {
17 request => 'HTTP::Request',
18 response => 'HTTP::Response',
19 hostname => '$',
20 address => '$'
21};
e646f111 22
23=head1 NAME
24
25Catalyst::Engine::Test - Catalyst Test Engine
26
27=head1 SYNOPSIS
28
c9afa5fc 29A script using the Catalyst::Engine::Test module might look like:
30
31 #!/usr/bin/perl -w
32
33 BEGIN {
34 $ENV{CATALYST_ENGINE} = 'Test';
35 }
36
37 use strict;
38 use lib '/path/to/MyApp/lib';
39 use MyApp;
40
41 MyApp->run('/a/path');
e646f111 42
43=head1 DESCRIPTION
44
45This is the Catalyst engine specialized for testing.
46
47=head1 OVERLOADED METHODS
48
75fd617a 49This class overloads some methods from C<Catalyst::Engine>.
e646f111 50
51=over 4
52
75fd617a 53=item $c->finalize_headers
54
55=cut
56
57sub finalize_headers {
58 my $c = shift;
59
1a80619d 60 $c->lwp->response->code( $c->response->status || 200 );
61
62 for my $name ( $c->response->headers->header_field_names ) {
63 $c->lwp->response->header( $name => $c->response->header($name) );
64 }
75fd617a 65
66 while ( my ( $name, $cookie ) = each %{ $c->response->cookies } ) {
523d44ec 67 my $cookie = CGI::Cookie->new(
75fd617a 68 -name => $name,
69 -value => $cookie->{value},
70 -expires => $cookie->{expires},
71 -domain => $cookie->{domain},
72 -path => $cookie->{path},
73 -secure => $cookie->{secure} || 0
74 );
75
1a80619d 76 $c->lwp->response->header( 'Set-Cookie' => $cookie->as_string );
75fd617a 77 }
75fd617a 78}
79
80=item $c->finalize_output
81
82=cut
83
84sub finalize_output {
85 my $c = shift;
86 $c->lwp->response->content_ref( \$c->response->{output} );
87}
88
89=item $c->prepare_connection
90
91=cut
92
93sub prepare_connection {
94 my $c = shift;
95 $c->req->hostname( $c->lwp->hostname );
96 $c->req->address( $c->lwp->address );
97}
98
99=item $c->prepare_cookies
100
101=cut
102
103sub prepare_cookies {
104 my $c = shift;
105
1a80619d 106 if ( my $header = $c->request->header('Cookie') ) {
523d44ec 107 $c->req->cookies( { CGI::Cookie->parse($header) } );
75fd617a 108 }
109}
110
111=item $c->prepare_headers
112
113=cut
114
115sub prepare_headers {
116 my $c = shift;
117 $c->req->method( $c->lwp->request->method );
118 $c->req->headers( $c->lwp->request->headers );
119}
120
121=item $c->prepare_parameters
122
123=cut
124
125sub prepare_parameters {
126 my $c = shift;
127
128 my @params = ();
129 my $request = $c->lwp->request;
130
131 push( @params, $request->uri->query_form );
132
133 if ( $request->content_type eq 'application/x-www-form-urlencoded' ) {
134 my $uri = URI->new('http:');
135 $uri->query( $request->content );
136 push( @params, $uri->query_form );
137 }
138
139 if ( $request->content_type eq 'multipart/form-data' ) {
140
141 for my $part ( $request->parts ) {
142
143 my $disposition = $part->header('Content-Disposition');
144 my %parameters = @{ ( split_header_words($disposition) )[0] };
145
146 if ( $parameters{filename} ) {
147
148 my $fh = IO::File->new_tmpfile;
149 $fh->write( $part->content ) or die $!;
150 $fh->seek( SEEK_SET, 0 ) or die $!;
151
152 $c->req->uploads->{ $parameters{filename} } = {
153 fh => $fh,
154 size => ( stat $fh )[7],
155 type => $part->content_type
156 };
157
158 push( @params, $parameters{filename}, $fh );
159 }
160 else {
161 push( @params, $parameters{name}, $part->content );
162 }
163 }
164 }
165
166 my $parameters = $c->req->parameters;
167
168 while ( my ( $name, $value ) = splice( @params, 0, 2 ) ) {
169
170 if ( exists $parameters->{$name} ) {
171 for ( $parameters->{$name} ) {
172 $_ = [$_] unless ref($_) eq "ARRAY";
173 push( @$_, $value );
174 }
175 }
176 else {
177 $parameters->{$name} = $value;
178 }
179 }
180}
181
182=item $c->prepare_path
183
184=cut
185
186sub prepare_path {
187 my $c = shift;
188
189 my $base;
190 {
191 my $scheme = $c->lwp->request->uri->scheme;
192 my $host = $c->lwp->request->uri->host;
193 my $port = $c->lwp->request->uri->port;
194
195 $base = URI->new;
196 $base->scheme($scheme);
197 $base->host($host);
198 $base->port($port);
199
200 $base = $base->canonical->as_string;
201 }
202
203 my $path = $c->lwp->request->uri->path || '/';
204 $path =~ s/^\///;
205
206 $c->req->base($base);
207 $c->req->path($path);
208}
209
210=item $c->prepare_request($r)
211
212=cut
213
214sub prepare_request {
215 my ( $c, $lwp ) = @_;
216 $c->lwp($lwp);
217}
218
219=item $c->prepare_uploads
220
221=cut
222
223sub prepare_uploads {
224 my $c = shift;
225}
226
e646f111 227=item $c->run
228
229=cut
230
231sub run {
232 my $class = shift;
233 my $request = shift || '/';
234
235 unless ( ref $request ) {
45374ac6 236
237 my $uri = ( $request =~ m/http/i )
238 ? URI->new($request)
239 : URI->new( 'http://localhost' . $request );
240
241 $request = $uri->canonical;
e646f111 242 }
45374ac6 243
e646f111 244 unless ( ref $request eq 'HTTP::Request' ) {
245 $request = HTTP::Request->new( 'GET', $request );
246 }
247
75fd617a 248 my $lwp = Catalyst::Engine::Test::LWP->new(
45374ac6 249 address => '127.0.0.1',
1a80619d 250 hostname => 'localhost',
251 request => $request,
252 response => HTTP::Response->new
45374ac6 253 );
e646f111 254
6f4e1683 255 $class->handler($lwp);
e646f111 256
6f4e1683 257 return $lwp->response;
e646f111 258}
259
260=back
261
262=head1 SEE ALSO
263
264L<Catalyst>.
265
266=head1 AUTHOR
267
268Sebastian Riedel, C<sri@cpan.org>
269Christian Hansen, C<ch@ngmedia.com>
270
271=head1 COPYRIGHT
272
273This program is free software, you can redistribute it and/or modify it under
274the same terms as Perl itself.
275
276=cut
277
2781;