引子
系统B反向代理了老系统A中的几个页面,最近系统B更新了一些东西,导致cookie超过了8k,请求到达老系统A时报了413错误。
分析与解决
更新了Nginx的两个配置(client_header_buffer_size和large_client_header_buffers)之后,仍然出错。估计老系统A使用的jetty做了限制,一查果然jetty默认的最大header size是8192. 于是打算快速更新一下jetty的配置然后收工,结果……
问题1
搜索了一下jetty对于header size限制的相关配置,对比了一下自带的配置文件,发现挺简单,在jetty.xml中添加下面配置即可。
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="requestHeaderSize"><Property name="jetty.request.header.size" default="81920" /></Set>
</New>
</Configure>
浏览了一下项目文件发现居然没有jetty.xml,项目路径下全局搜索jetty,几乎没有结果。想到本地是使用gretty插件启动项目进行调试的,于是翻了翻gretty相关文档,选择在项目路径下新建jetty文件夹放置jetty.xml文件。添加了上述代码后,启动,测试,结果没起作用……再次搜索了一下,发现大家都是这么做的,配置应该没问题啊,为什么没起作用呢?又回过头去研究jetty自带的默认的配置文件,感觉和Spring很像啊,就像在声明一个一个bean,同时还可以互相引用。


同时也去看了看Embedded的相关文档,意识到jetty要想正常运行,server和connector是必须要显示声明的,网上提到只添加上面的代码怕是针对的是完整的jetty server的形式。gretty插件估计应该是嵌入式的,猜测如果没有jetty.xml,gretty应该会生成一个默认的server和connector用于运行web app。那么我应该在jetty.xml中声明一个http connector,并且引用上述httpConfig对象才对。于是将配置扩展成
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="requestHeaderSize"><Property name="jetty.request.header.size" default="81920" /></Set>
</New>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
<Arg name="acceptors" type="int"><Property name="http.acceptors" default="-1"/></Arg>
<Arg name="selectors" type="int"><Property name="http.selectors" default="-1"/></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref refid="httpConfig" /></Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="acceptorPriorityDelta"><Property name="http.acceptorPriorityDelta" default="0"/></Set>
<Set name="selectorPriorityDelta"><Property name="http.selectorPriorityDelta" default="0"/></Set>
</New>
</Arg>
</Call>
</Configure>
启动,测试,配置生效了。
又去看了看gretty的源码,确定了一下推测。

如果jetty的xml配置文件存在则根据配置文件配置server,然后配置connectors,先看看server中是否已经配置了HttpConnector(来自于jetty xml文件),如果没有的话,使用默认的HttpConfiguration创建一个HttpConnector,然后让server添加它,如果有的话什么也不做。这就是之前只配置了HttpConfiguration没有生效的原因了。
问题2
本地开发改好了,但是测试环境,生产环境可不是用gretty启动的,使用的是一个可执行war包。有了之前的经验,直接去看打executable war包时的相关gradle代码。是之前的老哥自己写的插件,还是有那么五六个工程使用了这个插件的。原理么就是添加一个包含main方法的入口类,按照embedded jetty的写法,声明构建了server,connector。定义几个可配置的参数,并从系统的属性值处获取。于是又加上了一个jetty.request.header.size,齐活。
网友评论