这个答案并没有解决问题,反而提出了新的问题。
在 apache 服务器后面使用 sitemesh3 时,会发生响应损坏。
如果我直接访问 tomcat 服务器,响应是干净的 304。
如果我通过 modjk/apache 访问,响应将包含意外数据。
意外数据的原因在于 sitemesh 的工作方式:发送响应时,在某些时候它会强制 struts 忽略任何“If-Modified-Since”标头,将请求的内容写入响应缓冲区。然后继续在缓冲区的开头添加 304 标头。
首先看一下
org.sitemesh.webapp.contentfilter.HttpServletRequestFilterable
org.apache.struts2.dispatcher.DefaultStaticContentLoader.process()
我不知道从这里该去哪里。这是一个错误吗?是 Apache Server 错误、Tomcat 错误、Struts 错误还是 Sitemesh 错误?!
要复制该问题,您需要在 apache 后面有一个 tomcat,运行一个带有 sitemesh 的 struts web 应用程序,并在 fiddler2 处于活动状态时获取此 url 两次:
http://[test.server.address]/struts/utils.js
小菜一碟o_O'
Edit:
如果我检查 modjk 日志,我可以清楚地看到传输回 Apache 服务器的文件:
: trying to connect socket 29 to 127.0.0.1:9009
: socket 29 [127.0.0.1:57195 -> 127.0.0.1:9009] connected
: sending to ajp13 pos=4 len=581 max=8192
.4.A....HTTP/1.1
.../struts/utils
.js...2.235.97.2
[...]
...Accept-Langua
ge..#en,en-US;q=
0.8,it-IT;q=0.6,
it;q=0.4....+JSE
SSIONID=B77369AB
D8239724A27A5CC5
6E06DED8...If-Mo
dified-Since...F
ri,.27.Jun.2014.
08:37:46.GMT....
.0....AJP_REMOTE
_PORT...19143...
.JK_LB_ACTIVATIO
N...............
: (rdp_worker) request body to send 0 - request body to resend 0
: received from ajp13 pos=0 len=20 max=8192
..0..Not.Modifie
d...............
: status = 304
: Number of headers is = 0
: received from ajp13 pos=0 len=4767 max=8192
.../*..*.$Id:.ut
ils.js.1240312.2
012-02-03.19:44:
51Z.jogep.$..*..
*.Licensed.to.th
e.Apache.Softwar
e.Foundation.(AS
F).under.one..*.
or.more.contribu
tor.license.agre
ements...See.the
[...]
the.ajaxValidati
on.interceptor.S
trutsUtils.getVa
lidationErrors.=
: ws_write::mod_jk.c (537): written 4763 out of 4763
: received from ajp13 pos=0 len=4 max=8192
................
: received from ajp13 pos=0 len=2 max=8192
................
: AJP13 protocol: Reuse is OK
当我直接访问 tomcat 并使用 tcpflow 转储 TCP 流量时,我没有看到任何虚假数据:
# tcpflow -p -s -c host xxx.xxx.xxx.xxx and port 8080
xxx.xxx.xxx.xxx.19292-yyy.yyy.yyy.yyy.08080: GET /rdp/struts/utils.js HTTP/1.1
Host: xxx.net:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en,en-US;q=0.8,it-IT;q=0.6,it;q=0.4
Cookie: JSESSIONID=B0F02CXXXEC3448F1B927C0E8C579A9B
If-Modified-Since: Fri, 27 Jun 2014 08:49:23 GMT
yyy.yyy.yyy.yyy.08080-xxx.xxx.xxx.xxx.19292: HTTP/1.1 304 Not Modified
Server: Apache-Coyote/1.1
Date: Fri, 27 Jun 2014 08:52:43 GMT
因此,将缓冲区返回到 ajp 端口和将其返回到网络套接字似乎有不同的行为。这对我来说太低了,无法进一步发展。
Edit:
解决方法
我实现的解决方法是让 Apache Server 处理 /struts 上下文:
- 从 struts 和 struts-jquery-plugin jars 中提取所有受影响的文件(分别是 org\apache\struts2\static 的内容和 template 的内容)
- 将这些文件复制到服务器上的目录中
- 在 apache 中创建一个别名,以便在遇到 /struts 路径时为该目录提供服务
- 从 modJK 取消映射 /struts 路径