Reputation: 708
I am trying to get the request header in a mojolicious template. I need to get a custom header. In Flask I would use
{{request.headers['customheader] }}
How do I achieve the same in Mojolicious? There is a Mojo::Message::Request
package.
So are what I have isn't working.
% use Mojo::Message::Request;
% my $req = Mojo::Message::Request->new;
<%= $req->headers->header('customheader') %>
If I only print $req
I get a giant hash.
I have also tried to use
% use Mojo::Headers;
% my $headers = Mojo::Headers->new;
<%= $headers->parse('X-Forwarded-For') %>
Upvotes: 1
Views: 1092
Reputation: 1706
Since mojolicious injects the controller object as the local variable $c
and $self
into your view, you can easily access the request headers:
# Your Template-Code
Some-Header: <strong><%= $c->req->headers->header("Some-header") %></strong>
$c->req->headers
is a Mojo::Headers object and contains all headers from the current request.
Upvotes: 1
Reputation: 132918
Your particular problem is that you are not using any of the objects created by the request. You're making new, empty objects and not finding anything in them. You need to give your templates the data the controller already knows.
Here's how it would work with a new app:
% mojo generate app
% cd app
In the template, I have access to the controller through the $c
variable. I change the templates/example/welcome.html.ep template to include a new paragraph:
<p>
The value of X-Bender is <%= $c->req->headers->header( 'X-Bender' ) %>
</p>
But, I don't particularly like handing the view a bunch of stuff it might not need; that's how data leakage happens. The controller object will still be there, but I won't use it (so some social control measures are necessary). Instead, I target the particular header I care about:
$self->stash(
bender_header => $self->req->headers->header( 'X-Bender' )
);
And in the template:
<p>
The value of X-Bender is <%= $bender_header %>
</p>
But what am I really adding to my page? What is X-Bender
is <script ...>
? The template will automatically escape things for you, but I don't like relying on the view to handle that. Even if it's escaped, it's still a mess. It's not only validating data; it's ensuring that sensitive data doesn't get out:
my $bender = $self->req->headers->header( 'X-Bender' );
# sanitize
$bender = 'Invalid' unless $bender =~ /\A[A-Z0-9\s]+\z/;
$self->stash(
bender_header => $bender
);
Start the server and make a request:
% ./script/my_app daemon
% curl -H "X-Bender: Kill all humans" http://127.0.0.1:3000
You can use Ojo for this too, but it's a bit more involved:
% perl -Mojo -E "say g( 'http://127.0.0.1:3000' => { 'X-Bender' => 'Kill all humans' } )->body"
Either way, the response body echos the X-Bender
header:
<!DOCTYPE html>
<html>
<head><title>Welcome</title></head>
<body><h2>Welcome to the Mojolicious real-time web framework!</h2>
<p>
This page was generated from the template "templates/example/welcome.html.ep"
and the layout "templates/layouts/default.html.ep",
<a href="/">click here</a> to reload the page or
<a href="/index.html">here</a> to move forward to a static page.
</p>
<p>
The value of X-Bender is Kill all humans
</p>
</body>
</html>
Upvotes: 1