Path: blob/master/test/jdk/sun/net/www/protocol/http/HttpOnly.java
41159 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22/**23* @test24* @bug 7095980 800731525* @modules jdk.httpserver26* @library /test/lib27* @summary Ensure HttpURLConnection (and supporting APIs) don't expose28* HttpOnly cookies29* @run main HttpOnly30* @run main/othervm -Djava.net.preferIPv6Addresses=true HttpOnly31*/3233import java.io.IOException;34import java.net.CookieHandler;35import java.net.CookieManager;36import java.net.CookiePolicy;37import java.net.InetAddress;38import java.net.InetSocketAddress;39import java.net.Proxy;40import java.net.URI;41import java.net.HttpURLConnection;42import java.util.ArrayList;43import java.util.HashMap;44import java.util.List;45import java.util.Map;46import java.util.Set;47import com.sun.net.httpserver.Headers;48import com.sun.net.httpserver.HttpExchange;49import com.sun.net.httpserver.HttpHandler;50import com.sun.net.httpserver.HttpServer;5152import jdk.test.lib.net.URIBuilder;5354/*55* 1) start the HTTP server56* 2) populate cookie store with HttpOnly cookies57* 3) make HTTP request that should contain HttpOnly cookies58* 4) check HttpOnly cookies received by server59* 5) server reply with Set-Cookie containing HttpOnly cookie60* 6) check HttpOnly cookies are not accessible from Http client61* 7) check that non-null (empty string) values are returned for62scenario where all values are stripped from original key values63*/6465public class HttpOnly {6667static final String URI_PATH = "/xxyyzz/";68static final int SESSION_ID = 12345;6970void test(String[] args) throws Exception {71HttpServer server = startHttpServer();72CookieHandler previousHandler = CookieHandler.getDefault();73try {74InetSocketAddress address = server.getAddress();75URI uri = URIBuilder.newBuilder()76.scheme("http")77.host(address.getAddress())78.port(address.getPort())79.path(URI_PATH)80.build();81populateCookieStore(uri);82doClient(uri);83} finally {84CookieHandler.setDefault(previousHandler);85server.stop(0);86}87}8889void populateCookieStore(URI uri)90throws IOException {9192CookieManager cm = new CookieManager(null, CookiePolicy.ACCEPT_ALL);93CookieHandler.setDefault(cm);94Map<String,List<String>> header = new HashMap<>();95List<String> values = new ArrayList<>();96values.add("JSESSIONID=" + SESSION_ID + "; version=1; Path="97+ URI_PATH +"; HttpOnly");98values.add("CUSTOMER=WILE_E_COYOTE; version=1; Path=" + URI_PATH);99header.put("Set-Cookie", values);100cm.put(uri, header);101}102103void doClient(URI uri) throws Exception {104HttpURLConnection uc = (HttpURLConnection) uri.toURL().openConnection(Proxy.NO_PROXY);105int resp = uc.getResponseCode();106check(resp == 200,107"Unexpected response code. Expected 200, got " + resp);108109// TEST 1: check getRequestProperty doesn't return the HttpOnly cookie110// In fact, that it doesn't return any automatically set cookies.111String cookie = uc.getRequestProperty("Cookie");112check(cookie == null,113"Cookie header returned from getRequestProperty, value " + cookie);114115// TEST 2: check getRequestProperties doesn't return the HttpOnly cookie.116// In fact, that it doesn't return any automatically set cookies.117Map<String,List<String>> reqHeaders = uc.getRequestProperties();118Set<Map.Entry<String,List<String>>> entries = reqHeaders.entrySet();119for (Map.Entry<String,List<String>> entry : entries) {120String header = entry.getKey();121check(!"Cookie".equalsIgnoreCase(header),122"Cookie header returned from getRequestProperties, value " +123entry.getValue());124}125126// TEST 3: check getHeaderField doesn't return Set-Cookie with HttpOnly127String setCookie = uc.getHeaderField("Set-Cookie");128if (setCookie != null) {129debug("Set-Cookie:" + setCookie);130check(!setCookie.toLowerCase().contains("httponly"),131"getHeaderField returned Set-Cookie header with HttpOnly, " +132"value = " + setCookie);133}134135// TEST 3.5: check getHeaderField doesn't return Set-Cookie2 with HttpOnly136String setCookie2 = uc.getHeaderField("Set-Cookie2");137if (setCookie2 != null) {138debug("Set-Cookie2:" + setCookie2);139check(!setCookie2.toLowerCase().contains("httponly"),140"getHeaderField returned Set-Cookie2 header with HttpOnly, " +141"value = " + setCookie2);142}143144// TEST 4: check getHeaderFields doesn't return Set-Cookie145// or Set-Cookie2 headers with HttpOnly146Map<String,List<String>> respHeaders = uc.getHeaderFields();147Set<Map.Entry<String,List<String>>> respEntries = respHeaders.entrySet();148for (Map.Entry<String,List<String>> entry : respEntries) {149String header = entry.getKey();150if ("Set-Cookie".equalsIgnoreCase(header)) {151List<String> setCookieValues = entry.getValue();152debug("Set-Cookie:" + setCookieValues);153for (String value : setCookieValues)154check(!value.toLowerCase().contains("httponly"),155"getHeaderFields returned Set-Cookie header with HttpOnly, "156+ "value = " + value);157}158if ("Set-Cookie2".equalsIgnoreCase(header)) {159List<String> setCookieValues = entry.getValue();160debug("Set-Cookie2:" + setCookieValues);161for (String value : setCookieValues)162check(!value.toLowerCase().contains("httponly"),163"getHeaderFields returned Set-Cookie2 header with HttpOnly, "164+ "value = " + value);165}166}167168// Now add some user set cookies into the mix.169uc = (HttpURLConnection) uri.toURL().openConnection(Proxy.NO_PROXY);170uc.addRequestProperty("Cookie", "CUSTOMER_ID=CHEGAR;");171resp = uc.getResponseCode();172check(resp == 200,173"Unexpected response code. Expected 200, got " + resp);174175// TEST 5: check getRequestProperty doesn't return the HttpOnly cookie176cookie = uc.getRequestProperty("Cookie");177check(!cookie.toLowerCase().contains("httponly"),178"HttpOnly cookie returned from getRequestProperty, value " + cookie);179180// TEST 6: check getRequestProperties doesn't return the HttpOnly cookie.181reqHeaders = uc.getRequestProperties();182entries = reqHeaders.entrySet();183for (Map.Entry<String,List<String>> entry : entries) {184String header = entry.getKey();185if ("Cookie".equalsIgnoreCase(header)) {186for (String val : entry.getValue())187check(!val.toLowerCase().contains("httponly"),188"HttpOnly cookie returned from getRequestProperties," +189" value " + val);190}191}192193// TEST 7 : check that header keys containing empty key values don't return null194int i = 1;195String key = "";196String value = "";197198while (true) {199key = uc.getHeaderFieldKey(i);200value = uc.getHeaderField(i++);201if (key == null && value == null)202break;203204if (key != null)205check(value != null,206"Encountered a null value for key value : " + key);207}208209// TEST 7.5 similar test but use getHeaderFields210respHeaders = uc.getHeaderFields();211respEntries = respHeaders.entrySet();212for (Map.Entry<String,List<String>> entry : respEntries) {213String header = entry.getKey();214if (header != null) {215List<String> listValues = entry.getValue();216for (String value1 : listValues)217check(value1 != null,218"getHeaderFields returned null values for header:, "219+ header);220}221}222}223224// HTTP Server225HttpServer startHttpServer() throws IOException {226InetAddress localhost = InetAddress.getLocalHost();227HttpServer httpServer = HttpServer.create(new InetSocketAddress(localhost, 0), 0);228httpServer.createContext(URI_PATH, new SimpleHandler());229httpServer.start();230return httpServer;231}232233class SimpleHandler implements HttpHandler {234@Override235public void handle(HttpExchange t) throws IOException {236Headers reqHeaders = t.getRequestHeaders();237238// some small sanity check239List<String> cookies = reqHeaders.get("Cookie");240for (String cookie : cookies) {241if (!cookie.contains("JSESSIONID")242|| !cookie.contains("WILE_E_COYOTE"))243t.sendResponseHeaders(400, -1);244}245246// return some cookies so we can check getHeaderField(s)247Headers respHeaders = t.getResponseHeaders();248List<String> values = new ArrayList<>();249values.add("ID=JOEBLOGGS; version=1; Path=" + URI_PATH);250values.add("NEW_JSESSIONID=" + (SESSION_ID+1) + "; version=1; Path="251+ URI_PATH +"; HttpOnly");252values.add("NEW_CUSTOMER=WILE_E_COYOTE2; version=1; Path=" + URI_PATH);253respHeaders.put("Set-Cookie", values);254values = new ArrayList<>();255values.add("COOKIE2_CUSTOMER=WILE_E_COYOTE2; version=1; Path="256+ URI_PATH);257respHeaders.put("Set-Cookie2", values);258values.add("COOKIE2_JSESSIONID=" + (SESSION_ID+100)259+ "; version=1; Path=" + URI_PATH +"; HttpOnly");260respHeaders.put("Set-Cookie2", values);261262t.sendResponseHeaders(200, -1);263t.close();264}265}266267volatile int passed = 0, failed = 0;268boolean debug = false;269void pass() {passed++;}270void fail() {failed++;}271void fail(String msg) {System.err.println(msg); fail();}272void unexpected(Throwable t) {failed++; t.printStackTrace();}273void debug(String message) { if (debug) System.out.println(message); }274void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}275public static void main(String[] args) throws Throwable {276Class<?> k = new Object(){}.getClass().getEnclosingClass();277try {k.getMethod("instanceMain",String[].class)278.invoke( k.newInstance(), (Object) args);}279catch (Throwable e) {throw e.getCause();}}280public void instanceMain(String[] args) throws Throwable {281try {test(args);} catch (Throwable t) {unexpected(t);}282System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);283if (failed > 0) throw new AssertionError("Some tests failed");}284}285286287