なんだよソレ?どんな時だよw って話はおいといて…。
ブラウザってこんな事してんのかなーってのがちょっと垣間見れたのでメモ的な。
■ 事象
諸事情で異なるVIPを経由して裏からとあるサービスにアクセスして、
HTTPClientを作ってマッシュアップ的な事をしたい、と。
■ Cookieドメイン指定
呼び出し先の各サービスはCookieを発行する際はドメインを設定してレスポンスするので、
↓こんなんが出てしまったりします。この警告嫌なので、、、
警告: Cookie rejected: "$Version=0; hoge=hage; $Path=/; $Domain=.shinodogg.com". Illegal domain attribute ".shinodogg.com". Domain of origin: "shinodogg.intra.com"
■ とりあえずCookieを吐くだけのサーブレット作ります。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ Cookie cookie; cookie = new Cookie("hoge", "hage"); cookie.setDomain(".shinodogg.com"); ★ ドメイン指定します cookie.setPath("/"); cookie.setMaxAge(60*5); response.addCookie(cookie); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hello World!</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Hello World!</h1>"); out.println("</body>"); out.println("</html>"); }
■ 上記サーブレットを呼び出すHTTPクライアント。(ライブラリは commons-httpclient-3.1.jar )
HttpClient httpClient = new HttpClient(); int status = httpClient.executeMethod(new GetMethod("http://localhost:8080/CookiePolicy/servlet/set")); System.out.println("status:" + status);
■ commons-httpclient-3.1.jarのソースが欲しかったんだけど…orz
なんかMavenでイイ感じに取れないので、、、
C:eclipseworkspacehttp_client_test>C:apache-maven-2.2.1binmvn dependency:sources 〜略〜 [INFO] The following files have NOT been resolved: [INFO] commons-codec:commons-codec:java-source:sources:1.2 [INFO] commons-httpclient:commons-httpclient:java-source:sources:3.1
ググったら↓が出てきたのでコレをアタッチする感じで。
http://www.docjar.com/jar_detail/com.springsource.org.apache.commons.httpclient-sources-3.1.0.jar.html
■ RFC2109Spec()をみると
↓こんな事やってます、と。
if (host.indexOf('.') >= 0) { if (!host.endsWith(cookie.getDomain())) { throw new MalformedCookieException( "Illegal domain attribute "" + cookie.getDomain() + "". Domain of origin: "" + host + """); } // host minus domain may not contain any dots String hostWithoutDomain = host.substring(0, host.length() - cookie.getDomain().length()); if (hostWithoutDomain.indexOf('.') != -1) { throw new MalformedCookieException("Domain attribute "" + cookie.getDomain() + "" violates RFC 2109: host minus domain may not contain any dots"); } } }
■ ってことでRFC2109Specを継承して…
public class HogeSpec extends RFC2109Spec{ public void validate(String host, int port, String path, boolean secure, final Cookie cookie) throws MalformedCookieException { System.out.println("HogeSpac is called"); } }
■ HttpClientにvalidateしないSpecをセット
HttpMethod method = new GetMethod("http://localhost:8080/CookiePolicy/servlet/set"); CookiePolicy.registerCookieSpec(CookiePolicy.DEFAULT, HogeSpec.class); method.getParams().setCookiePolicy(CookiePolicy.DEFAULT);
動かしてみると、下記のように呼ばれました、と。
Hello World! HogeSpac is called status:200
■ ところが、
RFC2109Specのvalidateメソッドをパクってきて上記のとこだけ
コメントアウトすれば動くのかと思ったのですが、、
// Perform generic validation super.validate(host, port, path, secure, cookie); // Perform RFC 2109 specific validation
って事になってて、CookieSpecBaseのvalidateが呼ばれてます、と。
CookieSpecBaseでは以下のようにドメインチェックしてました。
// Validate the cookies domain attribute. NOTE: Domains without // any dots are allowed to support hosts on private LANs that don't // have DNS names. Since they have no dots, to domain-match the // request-host and domain must be identical for the cookie to sent // back to the origin-server. if (host.indexOf(".") >= 0) { // Not required to have at least two dots. RFC 2965. // A Set-Cookie2 with Domain=ajax.com will be accepted. // domain must match host if (!host.endsWith(cookie.getDomain())) { String s = cookie.getDomain(); if (s.startsWith(".")) { s = s.substring(1, s.length()); } if (!host.equals(s)) { throw new MalformedCookieException( "Illegal domain attribute "" + cookie.getDomain() + "". Domain of origin: "" + host + """); } } } else { if (!host.equals(cookie.getDomain())) { throw new MalformedCookieException( "Illegal domain attribute "" + cookie.getDomain() + "". Domain of origin: "" + host + """); } }
■ ということでHogeSpecはCookieSpecBaseを継承することにして、
System.out.println( "Hello World!" ); HttpClient httpClient = new HttpClient(); HttpMethod method = new GetMethod("http://localhost:8080/CookiePolicy/servlet/set"); CookiePolicy.registerCookieSpec(CookiePolicy.DEFAULT, HogeSpec.class); int status = httpClient.executeMethod(method); System.out.println("status:" + status);
以下のように狙った結果になったので、まぁメデタシな感じです。
Hello World! HogeSpac is called status:200
特定のホストの時だけ握り潰す、と。 # あんまりこういうことしたくないけど…
public class HogeSpec extends CookieSpecBase { public void validate(String host, int port, String path, boolean secure, final Cookie cookie) throws MalformedCookieException { System.out.println("HogeSpac is called"); LOG.trace("enter CookieSpecBase.validate(" + "String, port, path, boolean, Cookie)"); if (host == null) { throw new IllegalArgumentException("Host of origin may not be null"); } if (host.trim().equals("")) { throw new IllegalArgumentException( "Host of origin may not be blank"); } if (port < 0) { throw new IllegalArgumentException("Invalid port: " + port); } if (path == null) { throw new IllegalArgumentException( "Path of origin may not be null."); } if (path.trim().equals("")) { path = PATH_DELIM; } host = host.toLowerCase(); // check version if (cookie.getVersion() = 0) { // Not required to have at least two dots. RFC 2965. // A Set-Cookie2 with Domain=ajax.com will be accepted. /* domainのワーニングが出ないように */ if(!host.equals("shinodogg01.intra.com") && !host.equals("shinodogg02.intra.com)) { /* 特定のホストはスキップする */ // domain must match host if (!host.endsWith(cookie.getDomain())) { String s = cookie.getDomain(); if (s.startsWith(".")) { s = s.substring(1, s.length()); } if (!host.equals(s)) { throw new MalformedCookieException( "Illegal domain attribute "" + cookie.getDomain() + "". Domain of origin: "" + host + """); } } /* スキップ */ } /* ここまで */ } else { /* ローカル開発時にdomainのワーニングが出ないように */ if (!host.equals("localhost")) { /* localhostはスキップする */ if (!host.equals(cookie.getDomain())) { throw new MalformedCookieException( "Illegal domain attribute "" + cookie.getDomain() + "". Domain of origin: "" + host + """); } /* スキップ */ } /* ここまで */ } // another security check... we musn't allow the server to give us a // cookie that doesn't match this path if (!path.startsWith(cookie.getPath())) { throw new MalformedCookieException("Illegal path attribute "" + cookie.getPath() + "". Path of origin: "" + path + """); } } }
オライリージャパン
売り上げランキング: 281927
コメント