newdeveloper
newdeveloper

Reputation: 708

Mojolicious request header in template

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

Answers (2)

Sven Eppler
Sven Eppler

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

brian d foy
brian d foy

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

Related Questions