File Coverage

blib/lib/PlackX/Framework/Request.pm
Criterion Covered Total %
statement 87 110 79.0
branch 6 12 50.0
condition 7 13 53.8
subroutine 19 24 79.1
pod 16 20 80.0
total 135 179 75.4


line stmt bran cond sub pod time code
1 8     8   135373 use v5.36;
  8         28  
2             package PlackX::Framework::Request {
3 8     8   63 use parent 'Plack::Request';
  8         15  
  8         60  
4 8     8   787642 use Carp qw(croak);
  8         21  
  8         650  
5              
6 8     8   4938 use Plack::Util::Accessor qw(stash route_base route_parameters);
  8         2846  
  8         86  
7 0     0 1 0 sub GlobalRequest ($class) { ($class->app_namespace.'::Handler')->global_request }
  0         0  
  0         0  
  0         0  
8 7     7 1 21 sub max_reroutes { 16 }
9 0 0   0 0 0 sub app_base ($self) { eval {$self->app_namespace->uri_prefix} || '' }
  0         0  
  0         0  
  0         0  
  0         0  
10 1     1 1 230529 sub is_get ($self) { uc $self->method eq 'GET' }
  1         3  
  1         1  
  1         8  
11 1     1 1 222 sub is_post ($self) { uc $self->method eq 'POST' }
  1         1  
  1         4  
  1         3  
12 1     1 1 190 sub is_put ($self) { uc $self->method eq 'PUT' }
  1         1  
  1         2  
  1         3  
13 1     1 1 178 sub is_delete ($self) { uc $self->method eq 'DELETE' }
  1         2  
  1         1  
  1         3  
14 1   50 1 1 199 sub is_ajax ($self) { uc($self->header('X-Requested-With') || '') eq 'XMLHTTPREQUEST' }
  1         2  
  1         1  
  1         6  
15 112   33 112 1 969 sub destination ($self) { $self->{destination} // $self->path }
  112         183  
  112         162  
  112         654  
16 44     44 1 223 sub flash_cookie_name ($self) { PlackX::Framework::flash_cookie_name($self->app_namespace) }
  44         74  
  44         68  
  44         150  
17 14     14 1 1264 sub param ($self, $key) { scalar $self->parameters->{$key} } # faster than scalar $self->param($key)
  14         27  
  14         26  
  14         20  
  14         63  
18 1     1 1 281 sub cgi_param ($self, $key) { $self->SUPER::param($key) } # CGI.pm compatibile
  1         1  
  1         2  
  1         2  
  1         5  
19 6     6 1 410 sub route_param ($self, $key) { $self->{route_parameters}{$key} }
  6         11  
  6         13  
  6         11  
  6         31  
20 0     0 1 0 sub stash_param ($self, $key) { $self->{stash}{$key} }
  0         0  
  0         0  
  0         0  
  0         0  
21 2     2 0 397 sub abs_to ($self, $pth) { $self->base . with_leadslash($pth) }
  2         5  
  2         5  
  2         4  
  2         12  
22 0     0 0 0 sub rel_to ($self, $pth) { $self->abs_to($pth) =~ s|^https?://.+?/|/|ir }
  0         0  
  0         0  
  0         0  
  0         0  
23 0     0 1 0 sub urix ($self) { ($self->app_namespace.'::URIx')->new_from_pxfrequest($self) }
  0         0  
  0         0  
  0         0  
24 2 50   2 0 471 sub with_leadslash ($uri) { substr($uri, 0, 1) eq '/' ? $uri : '/'.$uri }
  2         3  
  2         5  
  2         17  
25             *uri_to = \&abs_to;
26              
27             # Send request somewhere else without issuing the client an HTTP redirect
28             # ::Handler will reprocess if it gets a request instead of response object
29 7     7 1 252 sub reroute ($self, $dest) {
  7         12  
  7         14  
  7         13  
30 7 50       25 croak "Specify reroute relative to application path"
31             if $dest =~ m/^http/;
32 7 50       39 croak "request->reroute path must start with /"
33             if substr($dest, 0, 1) ne '/';
34              
35 7   50     72 $self->{reroutes} //= [$self->path_info];
36 7         96 push @{$self->{reroutes}}, $dest;
  7         43  
37              
38             croak "Excessive reroutes:\n" . join("\n", $self->{reroutes}->@*)
39 7 50       35 if $self->{reroutes}->@* > $self->max_reroutes;
40              
41 7         29 my $orig_path_info = $self->path_info;
42 7   33     94 $self->{"pxf.orig.$_"} //= $self->env->{$_} for ('PATH_INFO', 'REQUEST_URI');
43 7         122 $self->env->{PATH_INFO} = $dest;
44 7         29 $self->env->{REQUEST_URI} =~ s|$orig_path_info|$dest|;
45              
46 7         165 return $self;
47             }
48              
49             # Maybe decode the flash from b64 json
50 44     44 1 330 sub flash ($self) {
  44         75  
  44         75  
51 44         160 my $cname = $self->flash_cookie_name;
52 44         251 my $content = $self->cookies->{$cname};
53 44         786 my $prefix = "$cname-ju64-";
54 44 100 100     166 return PXF::Util::decode_ju64(substr($content, length($prefix)))
55             if $content and substr($content, 0, length($prefix)) eq $prefix;
56 43         155 return $content;
57             }
58              
59             }
60              
61             1;
62              
63             =pod
64              
65             =head1 NAME
66              
67             PlackX::Framework::Request - A subclass of Plack::Request
68              
69              
70             =head1 Differences from Plack::Request
71              
72             This module adds some additional methods, and changes the behavior of the
73             param() method to only return a scalar. The original behavior is provided
74             by cgi_param().
75              
76             # Safe! param always returns scalar
77             my %okay_hash = (
78             key => $request->param('key')
79             );
80              
81             # Not safe! cgi_param may return empty list or multiple values!
82             my %bad_hash = (
83             key => $request->cgi_param('key')
84             );
85              
86             # ?color=red&color=green&color=blue
87             my @colors = $request->cgi_param('color'); # red, green, blue
88              
89             Please see the documentation for Plack::Request for more ways to get params,
90             e.g. the parameters() method, which is unchanged here.
91              
92             In addition, this class has a destination() method, which returns the path_info
93             or a path set manually via the reroute() method. See below.
94              
95              
96             =head1 CLASS METHODS
97              
98             =over 4
99              
100             =item max_reroutes()
101              
102             Returns the maximum number of PlackX::Framework "re-routes." By default, this
103             is 16. As this is a class method, the only way to change it is to override
104             the method in your subclass.
105              
106             package MyApp::Request {
107             sub max_reroutes() { 1 }
108             }
109              
110             =item GlobalRequest()
111              
112             If your app's subclass of PlackX::Framework::Handler overrides the
113             use_global_request_response() method to return a true value, PXF will set up
114             a global $request object, which can be accessed here.
115              
116             This feature is turned off by default to avoid action-at-a-distance bugs. It
117             is preferred to use the request object instance passed to the route's
118             subroutine.
119              
120             package MyApp { use PlackX::Framework; }
121             package MyApp::Handler { use_global_request_response { 1 } }
122             package MyApp::Routes {
123             use MyApp::Router;
124             route '/someroute' => sub ($request, $response) {
125             my $g_request = MyApp::Request->GlobalRequest();
126             # $request and $g_request "should" be the same object
127             ...
128             };
129             }
130              
131             Attempting to use this method when the feature is turned off will result in an
132             error, most like of the "not an arrayref" variety.
133              
134             =back
135              
136              
137             =head1 OBJECT METHODS
138              
139             =over 4
140              
141             =item param(NAME)
142              
143             Unlike Plack::Request, our param() method always returns a single scalar value.
144             If you want the original behavior, which was modeled after CGI.pm, you can call
145             cgi_param().
146              
147             =item cgi_param(NAME)
148              
149             Calls Plack::Request's param() method, which may return a scalar or list,
150             depending on context, like CGI.pm or the mod_perl Apache request object.
151              
152             =item route_param(NAME)
153              
154             Return's the value of a route parameter, parsed by PlackX::Framework's router
155             engine. For example:
156              
157             route '/{page_name}' => sub ($request, $response) {
158             my $page_name = $request->route_param('page_name');
159             };
160              
161             =item stash_param(NAME)
162              
163             Accesses the request/response cycle's stash hashref, returning the value based
164             on the given key. For example:
165              
166             # Somewhere, like a route filter
167             $request->stash->{session} = $session;
168              
169             # Somewhere else
170             my $session = $request->stash_param('session');
171              
172             # The above is just a shortcut for
173             my $session = $request->stash->{'session'};
174              
175             =item flash()
176              
177             Gets the content of the PXF app's flash cookie, if set on the previous request.
178              
179             =item flash_cookie_name()
180              
181             Returns the name of the PXF app's flash cookie, which should be unique per app,
182             as it is based on the md5 of the app's namespace. This method is used
183             internally, and there should be no need to access or override it in your app.
184              
185             =item is_get(), is_post(), is_put(), is_delete()
186              
187             Returns true if the HTTP request was a GET, POST, PUT, or DELETE request. This
188             is syntactic sugar for $request->method eq $verb;
189              
190             =item is_ajax()
191              
192             Returns true if the HTTP X-Requested-With header is set as expected for an AJAX
193             request.
194              
195              
196             =item destination()
197              
198             Returns the request's path_info, or the app's alternative destination, if set
199             using the reroute() method.
200              
201             =item reroute(URL)
202              
203             Sets the destination to URL and returns the modified request object.
204              
205             # In a route sub:
206             route '/old/url' => sub ($request, $response) {
207             return $request->reroute('/new/url');
208             };
209              
210             When PlackX::Framework::Handler receives a request object as a response,
211             instead of a response object, request processing will start over with the new
212             route. Think of this as an internal redirect (which does not issue an HTTP
213             redirect to the user).
214              
215             For debugging, you can access a list of reroutes through the
216             $request->{reroutes} hash key, which may be undefined or an arrayref. Routes
217             are remembered in order from oldest to newest.
218              
219             =item urix()
220              
221             Returns a new instance of a URI::Fast object, if you have the URI::Fast module
222             installed and your app turned on this feature.
223              
224             package MyApp {
225             use PlackX::Framework qw(:URIx); # or :all
226             use MyApp::Router;
227             route '/seomwhere' => sub ($request, $response) {
228             my $uri_fast = $request->urix;
229             ...
230             };
231             }
232              
233             =back
234              
235              
236             =head1 META
237              
238             For author, copyright, and license, see PlackX::Framework.