how to make Mojolicious's url_for()->to_abs() return correct scheme (http or https) behind nginx

74 views
Skip to first unread message

Geunyoung Park

unread,
Oct 30, 2017, 3:06:59 AM10/30/17
to Mojolicious
I'm not good at English, sorry.

Here is my situation:

1) Nginx listens both 80 and 443 port and forwards a request to Mojolicious app.

    upstream ssltest {
        server
127.0.0.1:9000;
   
}


    server
{
        listen
80;
        listen
443 ssl;


        server_name ssltest
.server.com;


        location
/ {
            proxy_pass http
://ssltest/;
            proxy_set_header
Upgrade $http_upgrade;
            proxy_set_header
Connection "upgrade";
            proxy_set_header
Host $host;
            proxy_set_header X
-Forwarded-For $proxy_add_x_forwarded_for;
       
}
   
}


2) In the Mojolicious app, I put this code:

    get '/' => sub {
     
my $c = shift;
   
      warn $c
->url_for('/somepath')->to_abs;  # HERE
   
      $c
->render(template => 'index');
   
};


I want that `url_for('/somepath')->to_abs` returns `https://ssltest.server.com/somepath` or `http://.../somepath`, depending on which protocol I use in my browser. But it always returns `http`

(There is some reason that I have to create an absolute path, rather than relative path)


So, I've tried to search in web.


This link taught me I can pass the current protocol(http or https) to the Mojo app via a custom header `X-Forward-Proto`. However, url_for() still returned only `http`.

Then I tried such code:

    warn $c->url_for('/somepath')->to_abs->scheme(
      $c
->req->headers->header('X-Forwarded-Proto')
   
);


It worked! But now I have to modify every occurrences of `url_for->to_abs` in the code.

which uses a hook to modify `$c->req->url->base` itself. I tried to apply it:

    # change 'scheme' of request url
    hook
'before_dispatch' => sub {
     
my $c = shift;
      $c
->req->url->base->scheme( $c->req->headers->header('X-Forwarded-Proto'));
   
};
   
   
get '/' => sub {
     
my $c = shift;
   
     
# url_for() seems to refer the request url to determine new url
      warn $c
->url_for('/somepath')->to_abs;
   
      $c
->render(template => 'index');
   
};


It worked very well.

Now I want to know whether this is a correct way or not. Is there any problem that would occur? Is there a better or the best way to acquire my goal?

Any advice would be appreciated.

Luc Didry

unread,
Oct 30, 2017, 3:54:48 AM10/30/17
to mojol...@googlegroups.com, Geunyoung Park
lundi 30 octobre 2017, 00:06:59 CET Geunyoung Park wrote:
> I'm not good at English, sorry.
>
> Here is my situation:
>
> 1) Nginx listens both 80 and 443 port and forwards a request to Mojolicious
> app.
>
> upstream ssltest {
> server 127.0.0.1:9000;
> }
>
>
> server {
> listen 80;
> listen 443 ssl;
>
>
> server_name ssltest.server.com;
>
>
> location / {
> proxy_pass http://ssltest/;
> proxy_set_header Upgrade $http_upgrade;
> proxy_set_header Connection "upgrade";
> proxy_set_header Host $host;
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> }
> }
>
>
> 2) In the Mojolicious app, I put this code:
>
> get '/' => sub {
> my $c = shift;
>
> warn $c->url_for('/somepath')->to_abs; # HERE
>
> $c->render(template => 'index');
> };
>
>
> I want that `url_for('/somepath')->to_abs` returns
> `https://ssltest.server.com/somepath` or `http://.../somepath`, depending
> on which protocol I use in my browser. *But it always returns `http`*
> *Now I want to know whether this is a correct way or not. Is there any
> problem that would occur? Is there a better or the best way to acquire my
> goal?*
>
> Any advice would be appreciated.
>
>

Did you add the `proxy => 1` in hypnotoad configuration?
http://mojolicious.org/perldoc/Mojo/Server/Hypnotoad#proxy
--
Luc
https://fiat-tux.fr/
https://luc.frama.io/
Internet n'est pas compliqué, Internet est ce que vous en faites.

Geunyoung Park

unread,
Oct 30, 2017, 8:03:24 PM10/30/17
to Mojolicious


2017년 10월 30일 월요일 오후 4시 54분 48초 UTC+9, Luc Didry 님의 말:
Thanks for your reply.

My app is running on Plackup with Starlet. And today, I found MOJO_REVERSE_PROXY=1 did the same role.

Thank you again!

G.Y.Park

Reply all
Reply to author
Forward
0 new messages