配置在身后反向代理Mojolicious preFIX的URL(的ProxyPass) [英] Configure URLs with prefix in Mojolicious behind Reverse Proxy (ProxyPass)

查看:350
本文介绍了配置在身后反向代理Mojolicious preFIX的URL(的ProxyPass)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找配置Mojolicious运行Apache的背后反向代理下/应用程序,一个可靠的方式,使 url_for('/富')实际返回 /应用/富,而不是仅仅 /富(否则所有的链接将被打破)。

I'm looking for a reliable way to configure Mojolicious running behind an Apache reverse proxy under /app, so that url_for('/foo') actually returns /app/foo instead of just /foo (otherwise all the links would be broken).

借助文档显示了下/一切反向代理的例子。但是,这不是我所需要的,因为应用程序应该是在/应用程序。结果
谈到的ProxyPass / HTTP://本地主机:8080 / 的ProxyPass /应用HTTP://本地主机:8080 / 将导致此问题的 /应用程序 preFIX将从应用程序生成的所有URL会丢失。

The documentation shows a reverse proxy example for everything under /. But that's not what I need, since the application should be under /app.
Turning ProxyPass / http://localhost:8080/ into ProxyPass /app http://localhost:8080/ will cause the issue as the /app prefix would be missing from all urls generated by the application.

该文件也有一个重写部分,其中有一个例子一个before_dispatch挂钩,将采取请求URL的第一部分,并以此为基地。这需要preFIX要追加到的ProxyPass URL(的ProxyPass /应用HTTP://本地主机:8080 /应用/ 与斜线)在Apache的配置,这似乎并没有被该网页上提及,但也许它并不需要是(移动第一部分和路径的基本路径斜杠),因为这是显而易见的。这使得它可以调用的http://本地主机/应用/页,它变成的http://本地主机:8080 /应用/页(应用的勾去掉),其中 将返回/程序/富的http://本地主机/应用/富),这样的链接将是正确的(没有在规则的ProxyPass斜线,这将让 / apppage /富)。

The documentation also has a section on rewriting, which has an example of a before_dispatch hook that will take the first part of the request url and use it as base. This requires the prefix to be appended to the ProxyPass url (ProxyPass /app http://localhost:8080/app/ with trailing slash) in the Apache config, which does not seem to be mentioned on that page but maybe it does not need to be ("Move first part and slash from path to base path") because it's obvious. That makes it possible to call http://localhost/app/page, which turns into http://localhost:8080/app/page ('app' removed by the hook), where url_for('/foo') will return '/app/foo' (http://localhost/app/foo), so the links will be correct (without trailing slash in the ProxyPass rule, that would make /apppage/foo).

然而,在这个例子中,URL修改是的总是的生产模式进行的(如果APP->模式EQ生产) 。所以直接调用后端服务器(的http://本地主机:8080 / testpage )将不再工作,因为所有的URL将被打破。

However, in this example, the url modification is always made in production mode (if app->mode eq 'production'). So calling the backend server directly (http://localhost:8080/testpage) won't work anymore, since all the urls would be broken.

所以我想,我如果 X-转发,对于头设置(通过mod_proxy_http)检查来代替,这将始终是反向代理请求进行设置。而且,由于 Apache的mod_proxy文档提到,这个头可能已经在客户端请求设置(并最终包含多个值),我会从请求先删除它 - 因为客户端发送这个头应该不会导致该URL碱基修饰

So I thought, I'd check if the X-Forwarded-For header is set (by mod_proxy_http) instead, which would always be set for reverse proxy requests. And since the Apache mod_proxy documentation mentions that this header might already be set in the client request (and end up containing more than one value), I'd remove it from the request first - because a client sending this header should not cause the url base modification.

Apache的虚拟主机配置:

Apache VirtualHost configuration:

# ProxyPreserveHost: Mojo::URL::to_abs() not 127.0.0.1
ProxyPreserveHost On
<Location "/app/">
    # ProxyPass: prefix pass-thru
    ProxyPass http://localhost:3000/app/
    # RequestHeader: must not be set externally
    RequestHeader unset X-Forwarded-For
</Location>

胡克Mojolicious启动():

Hook in Mojolicious startup():

$self->hook('before_dispatch' => sub {
    my $c = shift;
    my $behind_proxy = !!$c->req->headers->header('X-Forwarded-Host');
    if ($behind_proxy) {
        push @{$c->req->url->base->path->trailing_slash(1)},
            shift @{$c->req->url->path->leading_slash(0)};
        $c->req->url->path->trailing_slash(0) # root 404
            unless @{$c->req->url->path->parts};
    }
});

这似乎是工作...

问:请问我的方法可靠地工作,在现实世界还是有缺陷

编辑:结果
请求根地址(的http://本地主机:3000 /应用/ )通过总是导致错误的反向代理404所以我添加了两行打开尾随在这种情况下削减了。因为我无法找到在该文档中,可能会有更好的办法。


Requesting the root address (http://localhost:3000/app/) through the reverse proxy always resulted in an error 404. So I've added two lines to turn the trailing slash off in that case. Since I can't find that in the docs, there may be a better way.

推荐答案

您需要设置基本路径为每个请求的URL的 before_dispatch 挂钩

You need to set base path for each request url in before_dispatch hook

$app->hook(before_dispatch => sub {
  my $c = shift;
  $c->req->url->base->path('/app/');
});

例如:

use Mojolicious::Lite;

app->hook(before_dispatch => sub {
  shift->req->url->base->path('/app/');
});


get '/' => sub {
  my $c = shift;
  $c->render(text => $c->url_for('test'));
};

get '/test/url' => sub { ... } => 'test';

app->start;

和结果是:

$ curl 127.0.0.1:3000
/app/test/url

这篇关于配置在身后反向代理Mojolicious preFIX的URL(的ProxyPass)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆