Apache/mod_rewrite > Tomcat 编码 %26 和“&”

发布于 2024-08-25 11:11:55 字数 5681 浏览 3 评论 0原文

Apache 是我的 Web 应用程序的前端,然后我使用 mod_rewrite 将请求代理到 JBoss。到目前为止,这听起来很标准,但我遇到的问题是:如果我直接通过 jboss @ http://localhost:8080/app/page?raw=foo%26bar&page=1:

request.getParameter("raw") = foo&bar

如果我通过 Apache @ http://localhost/foo%26bar&page=1 访问应用程序,

request.getParameter("raw") = foo

那么在途中的某个地方,%26 会丢失并且替换为 & ,它会砍掉原始变量。

这是我的 Apache 重写规则。

RewriteRule ^/(.*) \
    http://localhost:8080/app/home?raw=$1 [L,P]

Apache 访问日志显示: http://localhost/foo%26bar&page=1

重写日志显示: http://localhost:8080/app/home?raw=foo& ;bar&page=1

但我希望请求为: http://localhost:8080/app/home?raw=foo%26bar&page=1

我很确定这也发生在斜杠 / 上,所以对我来说这是某种编码问题。有没有办法不受影响地代理 URL?这题好像想不通

编辑:

首先我想说的是感谢Gumbo给了我一些非常好的建议!根据这些建议,我简化了 Apache 配置以用于测试目的。

它是这样的:

ServerRoot "C:/apps/xampplite/apache"
Listen 80

LoadModule rewrite_module modules/mod_rewrite.so
LoadModule log_config_module modules/mod_log_config.so

ServerAdmin postmaster@localhost
ServerName localhost:80
DocumentRoot "C:/apps/xampplite/htdocs"
ErrorLog "logs/error.log"
LogLevel debug
DefaultType text/plain

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access.log" combined
</IfModule>

RewriteEngine On    
RewriteLog "C:/apps/xampplite/apache/logs/rewrite.log"
RewriteLogLevel 9 
RewriteMap escape int:escape
RewriteRule ^/(.*) http://localhost:8080/app/home?raw=${escape:$1} [L,P]

以下是我采取的步骤:启动 Apache,转到

http://localhost/foo%26bar&page=1

我的 Web 浏览器,停止 Apache。

访问日志条目:

::1 - - [15/Mar/2010:19:17:18 -0400] "GET /foo%26bar&page=1 HTTP/1.1" 403 224 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"

重写日志条目:

::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (2) init rewrite engine with requested uri /foo&bar&page=1
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (3) applying pattern '^/(.*)' to uri '/foo&bar&page=1'
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (5) map lookup OK: map=escape key=foo&bar&page=1 -> val=foo&bar&page=1
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (2) rewrite '/foo&bar&page=1' -> 'http://localhost:8080/app/home?raw=foo&bar&page=1'
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (3) split uri=http://localhost:8080/app/home?raw=foo&bar&page=1 -> uri=http://localhost:8080/app/home, args=raw=foo&bar&page=1
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (2) forcing proxy-throughput with http://localhost:8080/app/home

错误日志条目:

[Mon Mar 15 19:16:56 2010] [notice] Apache/2.2.12 (Win32) configured -- resuming normal operations
[Mon Mar 15 19:16:56 2010] [notice] Server built: Jul 22 2009 11:35:54
[Mon Mar 15 19:16:56 2010] [notice] Parent: Created child process 2324
[Mon Mar 15 19:16:56 2010] [debug] mpm_winnt.c(487): Parent: Sent the scoreboard to the child
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Child process is running
[Mon Mar 15 19:16:57 2010] [debug] mpm_winnt.c(408): Child 2324: Retrieved our scoreboard from the parent.
[Mon Mar 15 19:16:57 2010] [info] Parent: Duplicating socket 148 and sending it to child process 2324
[Mon Mar 15 19:16:57 2010] [info] Parent: Duplicating socket 140 and sending it to child process 2324
[Mon Mar 15 19:16:57 2010] [debug] mpm_winnt.c(605): Parent: Sent 2 listeners to child 2324
[Mon Mar 15 19:16:57 2010] [debug] mpm_winnt.c(564): Child 2324: retrieved 2 listeners from parent
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Acquired the start mutex.
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Starting 64 worker threads.
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Starting thread to listen on port 80.
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Starting thread to listen on port 80.
[Mon Mar 15 19:17:18 2010] [error] [client ::1] attempt to make remote request from mod_rewrite without proxy enabled: proxy:http://localhost:8080/app/home
[Mon Mar 15 19:17:52 2010] [notice] Parent: Received shutdown signal -- Shutting down the server.
[Mon Mar 15 19:17:52 2010] [notice] Child 2324: Exit event signaled. Child process is ending.
[Mon Mar 15 19:17:52 2010] [info] Child 2324: Accept thread exiting.
[Mon Mar 15 19:17:53 2010] [notice] Child 2324: Released the start mutex
[Mon Mar 15 19:17:53 2010] [info] Child 2324: Accept thread exiting.
[Mon Mar 15 19:17:53 2010] [info] Child 2324: 64 threads blocked on the completion port
[Mon Mar 15 19:17:54 2010] [notice] Child 2324: All worker threads have exited.
[Mon Mar 15 19:17:54 2010] [notice] Child 2324: Child process is exiting
[Mon Mar 15 19:17:54 2010] [notice] Parent: Child process exited successfully.
[Mon Mar 15 19:17:54 2010] [info] removed PID file C:/apps/xampplite/apache/logs/httpd.pid (pid=1424)

有趣的是,访问日志中的第一个条目显示 %26,但它在重写日志的第一个条目中消失了。

对这个还是一头雾水……

Apache is the front-end to my web app then I use mod_rewrite to proxy the request to JBoss. So far this sounds pretty standard, but the problem I am having is: if I access the app directly through jboss @ http://localhost:8080/app/page?raw=foo%26bar&page=1:

request.getParameter("raw") = foo&bar

If I access the app through Apache @ http://localhost/foo%26bar&page=1

request.getParameter("raw") = foo

So somewhere along the way, the %26 is lost and replaced with an & which chops the raw variable.

This is my Apache rewrite rule.

RewriteRule ^/(.*) \
    http://localhost:8080/app/home?raw=$1 [L,P]

The Apache access log shows: http://localhost/foo%26bar&page=1

And the rewrite log shows: http://localhost:8080/app/home?raw=foo&bar&page=1

But I want the request to be: http://localhost:8080/app/home?raw=foo%26bar&page=1

I am pretty sure that this also occurs with slashes / too so to me this is some sort of encoding issue. Is there a way to proxy the URL untouched? Can't seem to figure this one out.

EDIT:

First thing I would like to say is thank you to Gumbo for giving me some very good suggestions! Based on those suggestions, I have simplified my Apache configuration for testing purposes.

This is what it looks like:

ServerRoot "C:/apps/xampplite/apache"
Listen 80

LoadModule rewrite_module modules/mod_rewrite.so
LoadModule log_config_module modules/mod_log_config.so

ServerAdmin postmaster@localhost
ServerName localhost:80
DocumentRoot "C:/apps/xampplite/htdocs"
ErrorLog "logs/error.log"
LogLevel debug
DefaultType text/plain

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access.log" combined
</IfModule>

RewriteEngine On    
RewriteLog "C:/apps/xampplite/apache/logs/rewrite.log"
RewriteLogLevel 9 
RewriteMap escape int:escape
RewriteRule ^/(.*) http://localhost:8080/app/home?raw=${escape:$1} [L,P]

Here are the steps I took: Start Apache, go to

http://localhost/foo%26bar&page=1

in my web browser, stop Apache.

Access log entries:

::1 - - [15/Mar/2010:19:17:18 -0400] "GET /foo%26bar&page=1 HTTP/1.1" 403 224 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"

Rewrite log entries:

::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (2) init rewrite engine with requested uri /foo&bar&page=1
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (3) applying pattern '^/(.*)' to uri '/foo&bar&page=1'
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (5) map lookup OK: map=escape key=foo&bar&page=1 -> val=foo&bar&page=1
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (2) rewrite '/foo&bar&page=1' -> 'http://localhost:8080/app/home?raw=foo&bar&page=1'
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (3) split uri=http://localhost:8080/app/home?raw=foo&bar&page=1 -> uri=http://localhost:8080/app/home, args=raw=foo&bar&page=1
::1 - - [15/Mar/2010:19:17:18 --0400] [localhost/sid#54d160][rid#5e1360/initial] (2) forcing proxy-throughput with http://localhost:8080/app/home

Error log entries:

[Mon Mar 15 19:16:56 2010] [notice] Apache/2.2.12 (Win32) configured -- resuming normal operations
[Mon Mar 15 19:16:56 2010] [notice] Server built: Jul 22 2009 11:35:54
[Mon Mar 15 19:16:56 2010] [notice] Parent: Created child process 2324
[Mon Mar 15 19:16:56 2010] [debug] mpm_winnt.c(487): Parent: Sent the scoreboard to the child
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Child process is running
[Mon Mar 15 19:16:57 2010] [debug] mpm_winnt.c(408): Child 2324: Retrieved our scoreboard from the parent.
[Mon Mar 15 19:16:57 2010] [info] Parent: Duplicating socket 148 and sending it to child process 2324
[Mon Mar 15 19:16:57 2010] [info] Parent: Duplicating socket 140 and sending it to child process 2324
[Mon Mar 15 19:16:57 2010] [debug] mpm_winnt.c(605): Parent: Sent 2 listeners to child 2324
[Mon Mar 15 19:16:57 2010] [debug] mpm_winnt.c(564): Child 2324: retrieved 2 listeners from parent
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Acquired the start mutex.
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Starting 64 worker threads.
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Starting thread to listen on port 80.
[Mon Mar 15 19:16:57 2010] [notice] Child 2324: Starting thread to listen on port 80.
[Mon Mar 15 19:17:18 2010] [error] [client ::1] attempt to make remote request from mod_rewrite without proxy enabled: proxy:http://localhost:8080/app/home
[Mon Mar 15 19:17:52 2010] [notice] Parent: Received shutdown signal -- Shutting down the server.
[Mon Mar 15 19:17:52 2010] [notice] Child 2324: Exit event signaled. Child process is ending.
[Mon Mar 15 19:17:52 2010] [info] Child 2324: Accept thread exiting.
[Mon Mar 15 19:17:53 2010] [notice] Child 2324: Released the start mutex
[Mon Mar 15 19:17:53 2010] [info] Child 2324: Accept thread exiting.
[Mon Mar 15 19:17:53 2010] [info] Child 2324: 64 threads blocked on the completion port
[Mon Mar 15 19:17:54 2010] [notice] Child 2324: All worker threads have exited.
[Mon Mar 15 19:17:54 2010] [notice] Child 2324: Child process is exiting
[Mon Mar 15 19:17:54 2010] [notice] Parent: Child process exited successfully.
[Mon Mar 15 19:17:54 2010] [info] removed PID file C:/apps/xampplite/apache/logs/httpd.pid (pid=1424)

Interestingly enough the first entry in the access log shows the %26 and it is gone in the first entry of the rewrite log.

Still puzzled by this one...

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

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

发布评论

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

评论(2

胡渣熟男 2024-09-01 11:11:55

尝试使用 NE 标志 以防止该字符转义:

RewriteRule ^/(.*) http://localhost:8080/app/home?raw=$1 [NE,L,P]

编辑    我想我弄错了。您需要强制转义,而不是阻止值被转义。尝试使用内部转义函数:

RewriteMap escape int:escape
RewriteRule ^/(.*) http://localhost:8080/app/home?raw=${escape:$1} [L,P]

Try it with the NE flag to prevent escaping of that character:

RewriteRule ^/(.*) http://localhost:8080/app/home?raw=$1 [NE,L,P]

Edit    I think I got that wrong. Rather than preventing the value to be escaped you need to enforce escaping. Try it with the internal escape function:

RewriteMap escape int:escape
RewriteRule ^/(.*) http://localhost:8080/app/home?raw=${escape:$1} [L,P]
凑诗 2024-09-01 11:11:55

这应该有效:

RewriteRule ^/(.*) http://localhost:8080/app/home?raw=$1 [B,NE,L,P]

就像这样:

RewriteCond %{REQUEST_URI} ^/(.*)
RewriteRule ^/(.*) http://localhost:8080/app/home?raw=%1 [L,P]

This should work:

RewriteRule ^/(.*) http://localhost:8080/app/home?raw=$1 [B,NE,L,P]

As should this:

RewriteCond %{REQUEST_URI} ^/(.*)
RewriteRule ^/(.*) http://localhost:8080/app/home?raw=%1 [L,P]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文