Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/net/www/B8185898.java
38841 views
/*1* Copyright (c) 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*/2223/**24* @test25* @bug 818589826* @library /lib/testlibrary27* @run main/othervm B818589828* @summary setRequestProperty(key, null) results in HTTP header without colon in request29*/3031import java.io.*;32import java.net.*;33import java.util.Arrays;34import java.util.List;35import java.util.Map;36import java.util.HashMap;37import java.util.concurrent.ExecutorService;38import java.util.concurrent.Executors;39import java.util.stream.Collectors;40import java.util.Collections;4142import jdk.testlibrary.net.URIBuilder;43import sun.net.www.MessageHeader;44import com.sun.net.httpserver.HttpContext;45import com.sun.net.httpserver.HttpExchange;46import com.sun.net.httpserver.HttpHandler;47import com.sun.net.httpserver.HttpServer;4849import static java.nio.charset.StandardCharsets.ISO_8859_1;50import static java.nio.charset.StandardCharsets.UTF_8;5152/*53* Test checks that MessageHeader with key != null and value == null is set correctly54* and printed according to HTTP standard in the format <key>: <value>55* */56public class B8185898 {5758static HttpServer server;59static final String RESPONSE_BODY = "Test response body";60static final String H1 = "X-header1";61static final String H2 = "X-header2";62static final String VALUE = "This test value should appear";63static final List<String> oneList = Arrays.asList(VALUE);64static final List<String> zeroList = Arrays.asList("");65static int port;66static URL url;67static volatile Map<String, List<String>> headers;6869static class Handler implements HttpHandler {7071public void handle(HttpExchange t) throws IOException {72InputStream is = t.getRequestBody();73InetSocketAddress rem = t.getRemoteAddress();74headers = t.getRequestHeaders(); // Get request headers on the server side75while(is.read() != -1){}76is.close();7778OutputStream os = t.getResponseBody();79t.sendResponseHeaders(200, RESPONSE_BODY.length());80os.write(RESPONSE_BODY.getBytes(UTF_8));81t.close();82}83}8485public static void main(String[] args) throws Exception {86ExecutorService exec = Executors.newCachedThreadPool();87InetAddress loopback = InetAddress.getLoopbackAddress();8889try {90InetSocketAddress addr = new InetSocketAddress(loopback, 0);91server = HttpServer.create(addr, 100);92HttpHandler handler = new Handler();93HttpContext context = server.createContext("/", handler);94server.setExecutor(exec);95server.start();9697port = server.getAddress().getPort();98System.out.println("Server on port: " + port);99url = URIBuilder.newBuilder()100.scheme("http")101.loopback()102.port(port)103.path("/foo")104.toURLUnchecked();105System.out.println("URL: " + url);106testMessageHeader();107testMessageHeaderMethods();108testURLConnectionMethods();109} finally {110server.stop(0);111System.out.println("After server shutdown");112exec.shutdown();113}114}115116// Test message header with malformed message header and fake request line117static void testMessageHeader() {118final String badHeader = "This is not a request line for HTTP/1.1";119final String fakeRequestLine = "This /is/a/fake/status/line HTTP/2.0";120final String expectedHeaders = fakeRequestLine + "\r\n"121+ H1 + ": " + VALUE + "\r\n"122+ H2 + ": " + VALUE + "\r\n"123+ badHeader + ":\r\n\r\n";124125MessageHeader header = new MessageHeader();126header.add(H1, VALUE);127header.add(H2, VALUE);128header.add(badHeader, null);129header.prepend(fakeRequestLine, null);130ByteArrayOutputStream out = new ByteArrayOutputStream();131header.print(new PrintStream(out));132133if (!out.toString().equals(expectedHeaders)) {134throw new AssertionError("FAILED: expected: "135+ expectedHeaders + "\nReceived: " + out.toString());136} else {137System.out.println("PASSED: ::print returned correct "138+ "status line and headers:\n" + out.toString());139}140}141142// Test MessageHeader::print, ::toString, implicitly testing that143// MessageHeader::mergeHeader formats headers correctly for responses144static void testMessageHeaderMethods() throws IOException {145// {{inputString1, expectedToString1, expectedPrint1}, {...}}146String[][] strings = {147{"HTTP/1.1 200 OK\r\n"148+ "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"149+ "Connection: keep-alive\r\n"150+ "Host: 127.0.0.1:12345\r\n"151+ "User-agent: Java/12\r\n\r\nfoooo",152"pairs: {null: HTTP/1.1 200 OK}"153+ "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"154+ "{Connection: keep-alive}"155+ "{Host: 127.0.0.1:12345}"156+ "{User-agent: Java/12}",157"Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"158+ "Connection: keep-alive\r\n"159+ "Host: 127.0.0.1:12345\r\n"160+ "User-agent: Java/12\r\n\r\n"},161{"HTTP/1.1 200 OK\r\n"162+ "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"163+ "Connection: keep-alive\r\n"164+ "Host: 127.0.0.1:12345\r\n"165+ "User-agent: Java/12\r\n"166+ "X-Header:\r\n\r\n",167"pairs: {null: HTTP/1.1 200 OK}"168+ "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"169+ "{Connection: keep-alive}"170+ "{Host: 127.0.0.1:12345}"171+ "{User-agent: Java/12}"172+ "{X-Header: }",173"Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"174+ "Connection: keep-alive\r\n"175+ "Host: 127.0.0.1:12345\r\n"176+ "User-agent: Java/12\r\n"177+ "X-Header: \r\n\r\n"},178};179180System.out.println("Test custom message headers");181for (String[] s : strings) {182// Test MessageHeader::toString183MessageHeader header = new MessageHeader(184new ByteArrayInputStream(s[0].getBytes(ISO_8859_1)));185if (!header.toString().endsWith(s[1])) {186throw new AssertionError("FAILED: expected: "187+ s[1] + "\nReceived: " + header);188} else {189System.out.println("PASSED: ::toString returned correct "190+ "status line and headers:\n" + header);191}192193// Test MessageHeader::print194ByteArrayOutputStream out = new ByteArrayOutputStream();195header.print(new PrintStream(out));196if (!out.toString().equals(s[2])) {197throw new AssertionError("FAILED: expected: "198+ s[2] + "\nReceived: " + out.toString());199} else {200System.out.println("PASSED: ::print returned correct "201+ "status line and headers:\n" + out.toString());202}203}204}205206// Test methods URLConnection::getRequestProperties,207// ::getHeaderField, ::getHeaderFieldKey208static void testURLConnectionMethods() throws IOException {209HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);210urlConn.setRequestProperty(H1, "");211urlConn.setRequestProperty(H1, VALUE);212urlConn.setRequestProperty(H2, null); // Expected to contain ':' between key and value213Map<String, List<String>> props = urlConn.getRequestProperties();214Map<String, List<String>> expectedMap = new HashMap<String, List<String>>();215expectedMap.put(H1, oneList);216expectedMap.put(H2, Arrays.asList((String)null));217218// Test request properties219System.out.println("Client request properties");220StringBuilder sb = new StringBuilder();221props.forEach((k, v) -> sb.append(k + ": "222+ v.stream().collect(Collectors.joining()) + "\n"));223System.out.println(sb);224225if (!props.equals(expectedMap)) {226throw new AssertionError("Unexpected properties returned: "227+ props);228} else {229System.out.println("Properties returned as expected");230}231232// Test header fields233String headerField = urlConn.getHeaderField(0);234if (!headerField.contains("200 OK")) {235throw new AssertionError("Expected headerField[0]: status line. "236+ "Received: " + headerField);237} else {238System.out.println("PASSED: headerField[0] contains status line: "239+ headerField);240}241242String headerFieldKey = urlConn.getHeaderFieldKey(0);243if (headerFieldKey != null) {244throw new AssertionError("Expected headerFieldKey[0]: null. "245+ "Received: " + headerFieldKey);246} else {247System.out.println("PASSED: headerFieldKey[0] is null");248}249250// Check that test request headers are included with correct format251try (252BufferedReader in = new BufferedReader(253new InputStreamReader(urlConn.getInputStream()))254) {255if (!headers.keySet().contains(H1)) {256throw new AssertionError("Expected key not found: "257+ H1 + ": " + VALUE);258} else if (!headers.get(H1).equals(oneList)) {259throw new AssertionError("Unexpected key-value pair: "260+ H1 + ": " + headers.get(H1));261} else {262System.out.println("PASSED: " + H1 + " included in request headers");263}264265if (!headers.keySet().contains(H2)) {266throw new AssertionError("Expected key not found: "267+ H2 + ": ");268// Check that empty list is returned269} else if (!headers.get(H2).equals(zeroList)) {270throw new AssertionError("Unexpected key-value pair: "271+ H2 + ": " + headers.get(H2));272} else {273System.out.println("PASSED: " + H2 + " included in request headers");274}275276String inputLine;277while ((inputLine = in.readLine()) != null) {278System.out.println(inputLine);279}280}281}282}283284285