Apache/mod_rewrite > Tomcat 编码 %26 和“&”
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试使用 NE 标志 以防止该字符转义:
编辑 我想我弄错了。您需要强制转义,而不是阻止值被转义。尝试使用内部转义函数:
Try it with the NE flag to prevent escaping of that character:
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:
这应该有效:
就像这样:
This should work:
As should this: