Apache Tomcat 5.5.26仕様変更対応(案)
イコール等を含むクッキーを使用しているWebアプリケーションはTomcat 5.5.26以降で正常に動作しないようになります。改修可能な場合はまだマシなのですが、改修不可能なパッケージ等の場合は深刻な影響が考えられます。
http://d.hatena.ne.jp/int128/20081008/1223480443
上記に対応するApache Tomcatモジュールを作ってみました。このモジュールはWebアプリケーションの処理前にHTTPヘッダを書き換える処理を行います。
public class TomcatCookieHeaderValve extends ValveBase { private Logger logger = Logger.getLogger(TomcatCookieHeaderValve.class.getName()); public void invoke(Request req, Response res) throws IOException, ServletException { String requestCookie = req.getHeader("Cookie"); if(requestCookie != null) { req.clearCookies(); for(String part : requestCookie.split("; *")) { String key = part.substring(0, part.indexOf('=')); String value = part.substring(part.indexOf('=')+1); Cookie cookie = new Cookie(key, value); req.addCookie(cookie); logger.info("Original request Cookie: " + requestCookie); logger.info("Fixed request Cookie: " + key + "=" + value); } } getNext().invoke(req, res); String responseCookie = res.getHeader("Set-Cookie"); if(responseCookie != null) { String fixed = responseCookie.replace("\"", ""); res.setHeader("Set-Cookie", fixed); logger.info("Original response Cookie: " + responseCookie); logger.info("Fixed response Cookie: " + fixed); } } }http://coderepos.org/share/browser/lang/java/misc/http-cookie-parser/trunk/src/org/hidetake/sandbox/TomcatCookieHeaderValve.java
プロジェクト全体をチェックアウトすると動作確認できます。server.xmlには下記を追記してください。
<Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Engine defaultHost="localhost" name="Catalina"> <!-- 追記 --> <Valve className="org.hidetake.sandbox.TomcatCookieHeaderValve"/> </Engine> </Service> </Server>
このモジュールは Valve を実装しているのですが、気になる一文が。
A Valve MUST NOT do any of the following things:
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/Valve.html#invoke(org.apache.catalina.connector.Request,%20org.apache.catalina.connector.Response)
- Change request properties that have already been used to direct the flow of processing control for this request (for instance, trying to change the virtual host to which a Request should be sent from a pipeline attached to a Host or Context in the standard implementation).
- Create a completed Response AND pass this Request and Response on to the next Valve in the pipeline.
- Consume bytes from the input stream associated with the Request, unless it is completely generating the response, or wrapping the request before passing it on.
- Modify the HTTP headers included with the Response after the invokeNext() method has returned.
- Perform any actions on the output stream associated with the specified Response after the invokeNext() method has returned.
invoke()の中で、Webアプリケーション処理後のHTTPヘッダを書き換えてはいけないと書いてあります。現状は動いてるけどルール違反だから無理なのかな。根の深い問題ですね。