使用 mod_proxy_ajp 在 Apache 后面正确设置 Tomcat

发布于 2024-10-27 10:32:20 字数 1571 浏览 1 评论 0原文

我一直在修改 Apache + Tomcat,以便我可以通过 apache(干净且清晰的 url 摇滚)为多个 tomcat 应用程序(在不同的机器中)提供服务。我已成功配置 mod_proxy_ajp & mod_rewrite 到我可以在不同的机器上提供两个 tomcat 应用程序的程度,几乎没有任何问题。

我发现的唯一问题是其中一个应用程序(我在 Struts2 中开发)有很多链接和表单,它们是用 生成的, 标记。这些标签生成的 URL 通常如下所示:

/WebApp/path/to/some.action

感谢 ModRewrite 的魔力,这通常不是一个问题,并且指向此类 URL 的超链接会被快速重写和删除。重定向到 /app/path/to/some.action (尽管我确实收到了大量 302 响应)。

真正的问题发生在执行 POST 请求时。大家可能都知道,我无法使用 mod_rewrite 重定向 POST 请求...所以最后...我的所有 POST 请求都不起作用,因为 mod_rewrite 重定向到正确的 url,但作为 GET 请求。

我已经阅读了一些关于 mod_proxy_html 的内容以及它如何帮助我重写 Tomcat Web 应用程序返回的 url...但感觉很麻烦。

这是我当前的 apache 配置:

## HACKING BEGINS RIGHT HERE

# cookies
ProxyPassReverseCookiePath /WebApp /app
# this is for CSS, IMGs, JS and redirecting urls with /WebApp*
RewriteRule ^/WebApp(.*)$ /app$1 [R,L]
<Location /app>
    ProxyPass ajp://localhost:8009/WebApp
    ProxyPassReverse ajp://localhost:8009/WebApp
    Order allow,deny
    Allow from all
</Location>

# the other app
ProxyPassReverseCookiePath /WebApp2 /other
<Location /other>
    ProxyPass ajp://200.9.4.6:8009/WebApp2
    ProxyPassReverse ajp://200.9.4.6:8009/WebApp2
    Order allow,deny
    Allow from all
</Location>

必须有一个解决方案来解决我的 POST 请求问题...有什么想法吗?我可以以某种方式配置一些东西,让 Struts2 输出正确的 url 吗?

感谢您的帮助。

I've been tinkering with Apache + Tomcat so that I can serve multiple tomcat apps (in different machines) through apache (clean & crisp urls rock). I've succesfully configured mod_proxy_ajp & mod_rewrite to the point where I can serve two tomcat apps in different machines with almost no troubles.

The only issue I've found is that one of the apps (which I'm developing in Struts2) has a lot of links and forms, which are generated with <s:a />, <s:url /> and <s:form /> tags. The urls generated by these tags generally are like this:

/WebApp/path/to/some.action

Thanks to the magic of ModRewrite, this is generally not a big issue and hyperlinks poiting to such urls are quickly rewriten & redirected to /app/path/to/some.action (although I do get tons of 302 responses).

The real problem occurs when performing POST requests. As you all might know, I cannot redirect POST requests with mod_rewrite... so in the end... all of my POST requests don't work because mod_rewrite redirects to the correct url but as a GET request.

I have already read a bit about mod_proxy_html and how it can help me rewrite the urls returned by the Tomcat web application... but it feels troublesome.

This is my current apache configuration:

## HACKING BEGINS RIGHT HERE

# cookies
ProxyPassReverseCookiePath /WebApp /app
# this is for CSS, IMGs, JS and redirecting urls with /WebApp*
RewriteRule ^/WebApp(.*)$ /app$1 [R,L]
<Location /app>
    ProxyPass ajp://localhost:8009/WebApp
    ProxyPassReverse ajp://localhost:8009/WebApp
    Order allow,deny
    Allow from all
</Location>

# the other app
ProxyPassReverseCookiePath /WebApp2 /other
<Location /other>
    ProxyPass ajp://200.9.4.6:8009/WebApp2
    ProxyPassReverse ajp://200.9.4.6:8009/WebApp2
    Order allow,deny
    Allow from all
</Location>

There must be a solution to my POST requests problem... Any ideas? Can I somehow configure something that will allow Struts2 to output correct urls?

Thanks for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云胡 2024-11-03 10:32:20

可能有几种方法可以解决这个问题。

如果您能够使用 URL 中使用的相同名称将应用程序部署到 Tomcat,那将是最简单的。因此,您的应用程序 app 将是 /webapps/app[.war] 而不是 /webapps/WebApp,这将完全避免重写。

否则,以下内容应该有效,并且应该位于当前重写规则之前。 [PT] 应该允许 Apache 仍然代理请求(这在使用 mod_jk 时有效,不确定我是否使用/测试过它mod_proxy_ajp):

RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^/WebApp(.*)$ /app$1 [PT,L]

一旦您的 Bean 处理了 POST 请求,您就可以将该请求发送到将被重定向的 URL。最后,POST URL 对用户来说并不重要,因此它不必是一个漂亮的 URL。

下面的编辑:

我在 Apache mod_proxy 上看到,ProxyPassReverse 应该与 [PT] 标志一起使用。我能够复制您遇到的问题,下面的配置对我有用,它使用一个基本的 JSP 页面,其中包含一个发布到另一个 JSP 页面的表单。

<VirtualHost *:80>
    ServerName localhost
    RewriteEngine On

    RewriteCond %{REQUEST_METHOD} !POST
    RewriteRule /WebApp/(.*) /app/$1 [R,L] 

    RewriteCond %{REQUEST_METHOD} POST
    RewriteRule /WebApp/(.*) /app/$1 [PT,L]

    <Location /app>
        ProxyPass ajp://localhost:8109/WebApp
        ProxyPassReverse ajp://localhost:8109/WebApp
    </Location>
</VirtualHost>

There may be a couple ways to go about this.

If you are able to deploy your app to Tomcat under the same name that you are using in the URL, that would be the easiest. So your application app would be /webapps/app[.war] instead of /webapps/WebApp, this would avoid the rewrite altogether.

Otherwise, the following should work, and should go before your current rewrite rule. The [PT] should allow Apache to still proxy the request (this works when using mod_jk, not sure I've used/tested it with mod_proxy_ajp):

RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^/WebApp(.*)$ /app$1 [PT,L]

Once your bean has processed the POST request, you could then send the request to a URL that would be redirected. In the end, the POST URL doesn't matter to the user, so it doesn't have to be a pretty URL.

Edits Below:

I saw on the Apache mod_proxy, that ProxyPassReverse should work with the [PT] flag. And I was able to replicate the issue you're having, and the below config worked for me with a basic JSP page with a form that posted to another JSP page.

<VirtualHost *:80>
    ServerName localhost
    RewriteEngine On

    RewriteCond %{REQUEST_METHOD} !POST
    RewriteRule /WebApp/(.*) /app/$1 [R,L] 

    RewriteCond %{REQUEST_METHOD} POST
    RewriteRule /WebApp/(.*) /app/$1 [PT,L]

    <Location /app>
        ProxyPass ajp://localhost:8109/WebApp
        ProxyPassReverse ajp://localhost:8109/WebApp
    </Location>
</VirtualHost>
深巷少女 2024-11-03 10:32:20

这是webapp设置的问题;可能有一种方法可以在 httpd 配置中解决它,但是修复原始的不一致与围绕它进行黑客攻击相比会更干净。

还值得一提的是,Struts 试图通过为您提供上下文感知的非相对 URL 来帮助您;如果你只是让路径匹配,你可以依赖它(而不是与之对抗......)。

因此,只需将 Struts webapp 部署到 /app 和 /other,而不是 /WebApp 和 /WebApp2。 (可能有某种原因这是不可能的——比如如果你实际上没有控制那些其他服务器——但听起来这并不适用)。

This is a problem with the webapp setup; there may be a way to work around it in httpd config, but it's cleaner to fix the original inconsistency vs. hacking around it.

Also worth mentioning that Struts is trying to help you by giving you context-aware, non-relative URLs; if you just make the paths match, you can rely on that (instead of fighting it...).

So, just deploy the Struts webapp to /app and /other, instead of /WebApp and /WebApp2. (There might be some reason this isn't possible -- like if you don't actually control those other servers -- but it sounds like that doesn't apply).

快乐很简单 2024-11-03 10:32:20

我会避免 URL 重写。它只是打开像这样的蠕虫罐头,让你查看 mod_proxy_html 等,这当然只是更多的蠕虫。相反,只需在 Tomcat 中部署您的应用程序,并使用您可以接受的外部可见的真实 URL。

I would avoid URL rewriting. It just opens cans of worms like this, makes you look into mod_proxy_html, etc, which of course are just yet more worms. Instead just deploy your apps in Tomcat with real URLs you can live with as being visible externally.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文