root/lang/perl/HTTP-Engine/branches/moose/lib/HTTP/Engine/Request.pm @ 11094

Revision 11094, 5.7 kB (checked in by dann, 5 years ago)

use no Moose to clarify the place for moose keywords.

Line 
1package HTTP::Engine::Request;
2use Moose;
3with 'MooseX::Object::Pluggable';
4
5use Carp;
6use HTTP::Headers;
7use HTTP::Body;
8use HTTP::Engine::Types::Core qw( Uri Header );
9use IO::Socket qw[AF_INET inet_aton];
10
11# the IP address of the client
12has address => (
13    is  => 'rw',
14    isa => 'Str',
15);
16
17has context => (
18    is       => 'rw',
19    isa      => 'HTTP::Engine::Context',
20    weak_ref => 1,
21);
22
23has cookies => (
24    is      => 'rw',
25    isa     => 'HashRef',
26    default => sub { {} },
27);
28
29has method => (
30    is  => 'rw',
31    # isa => 'Str',
32);
33
34has protocol => (
35    is  => 'rw',
36    # isa => 'Str',
37);
38
39has query_parameters => (
40    is      => 'rw',
41    isa     => 'HashRef',
42    default => sub { {} },
43);
44
45# https or not?
46has secure => (
47    is      => 'rw',
48    isa     => 'Bool',
49    default => 0,
50);
51
52has uri => (
53    is     => 'rw',
54    isa    => 'Uri',
55    coerce => 1,
56);
57
58has user => ( is => 'rw', );
59
60has raw_body => (
61    is      => 'rw',
62    isa     => 'Str',
63    default => '',
64);
65
66has headers => (
67    is      => 'rw',
68    isa     => 'Header',
69    coerce  => 1,
70    default => sub { HTTP::Headers->new },
71    handles => [ qw(content_encoding content_length content_type header referer user_agent) ],
72);
73
74# Contains the URI base. This will always have a trailing slash.
75# If your application was queried with the URI C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
76has base => (
77    is      => 'rw',
78    isa     => 'URI',
79    trigger => sub {
80        my $self = shift;
81
82        if ( $self->uri ) {
83            $self->path; # clear cache.
84        }
85    },
86);
87
88has hostname => (
89    is      => 'rw',
90    isa     => 'Str',
91    lazy    => 1,
92    default => sub {
93        my $self = shift;
94        $self->context->env->{REMOTE_HOST} || gethostbyaddr( inet_aton( $self->address ), AF_INET );
95    },
96);
97
98has http_body => (
99    is      => 'rw',
100    isa     => 'HTTP::Body',
101    handles => {
102        body_parameters => 'param',
103        body            => 'body',
104    },
105);
106
107# contains body_params and query_params
108has parameters => (
109    is      => 'rw',
110    isa     => 'HashRef',
111    default => sub { +{} },
112);
113
114no Moose;
115
116# aliases
117*body_params  = \&body_parameters;
118*input        = \&body;
119*params       = \&parameters;
120*query_params = \&query_parameters;
121*path_info    = \&path;
122
123sub cookie {
124    my $self = shift;
125
126    return keys %{ $self->cookies } if @_ == 0;
127
128    if (@_ == 1) {
129        my $name = shift;
130        return undef unless exists $self->cookies->{$name}; ## no critic.
131        return $self->cookies->{$name};
132    }
133}
134
135sub param {
136    my $self = shift;
137
138    return keys %{ $self->parameters } if @_ == 0;
139
140    if (@_ == 1) {
141        my $param = shift;
142        return wantarray ? () : undef unless exists $self->parameters->{$param};
143
144        if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
145            return (wantarray)
146              ? @{ $self->parameters->{$param} }
147                  : $self->parameters->{$param}->[0];
148        } else {
149            return (wantarray)
150              ? ( $self->parameters->{$param} )
151                  : $self->parameters->{$param};
152        }
153    } elsif (@_ > 1) {
154        my $field = shift;
155        $self->parameters->{$field} = [@_];
156    }
157}
158
159
160sub path {
161    my ($self, $params) = @_;
162
163    if ($params) {
164        $self->uri->path($params);
165    } else {
166        return $self->{path} if $self->{path};
167    }
168
169    my $path     = $self->uri->path;
170    my $location = $self->base->path;
171    $path =~ s/^(\Q$location\E)?//;
172    $path =~ s/^\///;
173    $self->{path} = $path;
174
175    return $path;
176}
177
178sub upload {
179    my $self = shift;
180
181    return keys %{ $self->uploads } if @_ == 0;
182
183    if (@_ == 1) {
184        my $upload = shift;
185        return wantarray ? () : undef unless exists $self->uploads->{$upload};
186
187        if (ref $self->uploads->{$upload} eq 'ARRAY') {
188            return (wantarray)
189              ? @{ $self->uploads->{$upload} }
190          : $self->uploads->{$upload}->[0];
191        } else {
192            return (wantarray)
193              ? ( $self->uploads->{$upload} )
194          : $self->uploads->{$upload};
195        }
196    }
197
198    if (@_ > 1) {
199        while ( my($field, $upload) = splice(@_, 0, 2) ) {
200            if ( exists $self->uploads->{$field} ) {
201                for ( $self->uploads->{$field} ) {
202                    $_ = [$_] unless ref($_) eq "ARRAY";
203                    push(@{ $_ }, $upload);
204                }
205            } else {
206                $self->uploads->{$field} = $upload;
207            }
208        }
209    }
210}
211
212sub uploads {
213    my ($self, $uploads) = @_;
214    $self->context->engine->interface->prepare_body;
215    $self->{uploads} = $uploads if $uploads;
216    return $self->{uploads};
217}
218
219sub uri_with {
220    my($self, $args) = @_;
221   
222    carp( 'No arguments passed to uri_with()' ) unless $args;
223
224    for my $value (values %{ $args }) {
225        next unless defined $value;
226        for ( ref $value eq 'ARRAY' ? @{ $value } : $value ) {
227            $_ = "$_";
228            utf8::encode( $_ );
229        }
230    };
231   
232    my $uri = $self->uri->clone;
233   
234    $uri->query_form( {
235        %{ $uri->query_form_hash },
236        %{ $args },
237    } );
238    return $uri;
239}
240
241sub as_http_request {
242    my $self = shift;
243    HTTP::Request->new( $self->method, $self->uri, $self->headers, $self->raw_body );
244}
245
246sub absolute_url {
247    my ($self, $location) = @_;
248
249    unless ($location =~ m!^https?://!) {
250        my $base = $self->base;
251        my $url = sprintf '%s://%s', $base->scheme, $base->host;
252        unless (($base->scheme eq 'http' && $base->port eq '80') ||
253               ($base->scheme eq 'https' && $base->port eq '443')) {
254            $url .= ':' . $base->port;
255        }
256        $url .= $base->path;
257        $location = URI->new_abs($location, $url);
258    }
259    $location;
260}
261
262__PACKAGE__->meta->make_immutable;
263
2641;
Note: See TracBrowser for help on using the browser.