1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.File; 25 import java.io.IOException; 26 import java.io.InputStream; 27 import java.io.OutputStream; 28 import java.net.URI; 29 import java.net.URISyntaxException; 30 import java.net.http.CustomHttp2Frame; 31 import java.net.http.Http2Handler; 32 import java.net.http.Http2TestExchange; 33 import java.net.http.Http2TestServer; 34 import java.net.http.HttpClient; 35 import java.net.http.HttpRequest; 36 import java.net.http.HttpResponse; 37 import java.net.http.HttpTimeoutException; 38 import java.nio.ByteBuffer; 39 import java.util.concurrent.TimeUnit; 40 41 /* 42 * @test 43 * @bug 8157104 44 * @modules java.httpclient 45 * @compile/module=java.httpclient java/net/http/Http2Handler.java 46 * @compile/module=java.httpclient java/net/http/Http2TestExchange.java 47 * @compile/module=java.httpclient java/net/http/Http2TestServer.java 48 * @compile/module=java.httpclient java/net/http/CustomHttp2Frame.java 49 * @run main/othervm SettingsTest 50 */ 51 public class SettingsTest { 52 53 private static final String KEYSTORE = System.getProperty("test.src") 54 + File.separator + "keystore.p12"; 55 private static final String PASSWORD = "password"; 56 private static final int TIMEOUT = 3; // in seconds 57 private static final int INVALID_STREAM_ID = Integer.MAX_VALUE; 58 private static final int INVALID_PARAMETERS_LENGTH = 16; 59 private static final int[] INVALID_PARAMETERS = new int[INVALID_PARAMETERS_LENGTH]; 60 61 public static void main(String[] args) throws Exception { 62 System.setProperty("java.net.http.HttpClient.log", 63 "ssl,requests,responses,errors"); 64 65 System.setProperty("javax.net.ssl.keyStore", KEYSTORE); 66 System.setProperty("javax.net.ssl.keyStorePassword", PASSWORD); 67 System.setProperty("javax.net.ssl.trustStore", KEYSTORE); 68 System.setProperty("javax.net.ssl.trustStorePassword", PASSWORD); 69 70 Handler handler = new Handler(); 71 72 try (Http2TestServer server = new Http2TestServer(true, 0, handler)) { 73 server.start(); 74 75 int port = server.getAddress().getPort(); 76 String uriString = "https://127.0.0.1:" + Integer.toString(port); 77 78 boolean success = true; 79 80 success &= expectSuccess( 81 "Test #1: run client, expect successful connection", 82 () -> connect(uriString)); 83 84 CustomSettingsFrame frame = new CustomSettingsFrame(); 85 frame.setStreamId(INVALID_STREAM_ID); 86 handler.setFrame(frame); 87 success &= expectFailure( 88 "Test #2: run client, " 89 + "server sends a frame with wrong stream id, " 90 + "expect connection failure", 91 () -> connect(uriString)); 92 93 frame = new CustomSettingsFrame(INVALID_PARAMETERS); 94 handler.setFrame(frame); 95 success &= expectFailure( 96 "Test #3: run client, " 97 + "server sends a frame with wrong parameters, " 98 + "expect connection failure", 99 () -> connect(uriString)); 100 101 if (success) { 102 System.out.println("Test passed"); 103 } else { 104 throw new RuntimeException("At least one test case failed"); 105 } 106 } 107 } 108 109 private static interface Test { 110 111 public void run() throws Exception; 112 } 113 114 private static class Handler implements Http2Handler { 115 116 private static final byte[] BODY = "Test response".getBytes(); 117 118 private volatile CustomSettingsFrame frame; 119 120 @Override 121 public void handle(Http2TestExchange t) throws IOException { 122 System.out.println("Handler: received request to " 123 + t.getRequestURI()); 124 125 if (frame != null) { 126 System.out.println("Handler: send a frame: " + frame); 127 t.sendFrame(frame); 128 } 129 130 try (InputStream is = t.getRequestBody()) { 131 byte[] body = is.readAllBytes(); 132 System.out.println("Handler: read " + body.length + " bytes of body: "); 133 System.out.println(new String(body)); 134 } 135 136 try (OutputStream os = t.getResponseBody()) { 137 t.sendResponseHeaders(200, BODY.length); 138 os.write(BODY); 139 } 140 } 141 142 void setFrame(CustomSettingsFrame frame) { 143 this.frame = frame; 144 } 145 } 146 147 private static class CustomSettingsFrame extends CustomHttp2Frame { 148 149 private final int[] parameters; 150 151 CustomSettingsFrame() { 152 this(null); 153 } 154 155 CustomSettingsFrame(int[] parameters) { 156 super(); 157 this.parameters = parameters != null 158 ? parameters.clone() : new int[0]; 159 setFrameType(SETTING_FRAME_TYPE); 160 } 161 162 @Override 163 public int customComputeLength() { 164 int length = 0; 165 for (int i : parameters) { 166 if (i != -1) { 167 length += 6; 168 } 169 } 170 return length; 171 } 172 173 @Override 174 public void customWriteOutgoing(ByteBuffer buf) { 175 for (int i = 0; i < parameters.length; i++) { 176 if (parameters[i] != -1) { 177 buf.putShort((short)(i+1)); 178 buf.putInt(parameters[i]); 179 } 180 } 181 } 182 183 } 184 185 private static void connect(String uriString) 186 throws URISyntaxException, IOException, InterruptedException { 187 188 String body = HttpClient.create() 189 .version(HttpClient.Version.HTTP_2) 190 .build() 191 .request(new URI(uriString)) 192 .timeout(TimeUnit.SECONDS, TIMEOUT) 193 .body(HttpRequest.fromString("body")) 194 .GET() 195 .response() 196 .body(HttpResponse.asString()); 197 198 System.out.println("Response: " + body); 199 } 200 201 private static boolean expectSuccess(String message, Test test) { 202 System.out.println(message); 203 try { 204 test.run(); 205 System.out.println("Passed"); 206 return true; 207 } catch (Exception e) { 208 System.out.println("Failed: unexpected exception:"); 209 e.printStackTrace(System.out); 210 return false; 211 } 212 } 213 214 private static boolean expectFailure(String message, Test test) { 215 System.out.println(message); 216 try { 217 test.run(); 218 System.out.println("Failed: unexpected successful connection"); 219 return false; 220 } catch (HttpTimeoutException e) { 221 System.out.println("Failed: unexpected HttpTimeoutException:"); 222 e.printStackTrace(System.out); 223 return false; 224 } catch (Exception e) { 225 System.out.println("Passed: expected exception: " + e); 226 e.printStackTrace(System.out); 227 return true; 228 } 229 } 230 231 }