なんだよソレ?どんな時だよ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



コメント