test/jdk/java/net/httpclient/http2/server/Http2TestServerConnection.java
branchhttp-client-branch
changeset 56009 cf8792f51dee
parent 55973 4d9b002587db
child 56019 2cb33775fc6f
equal deleted inserted replaced
56008:bbd688c6fbbb 56009:cf8792f51dee
     1 /*
     1 /*
     2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   267         if (Arrays.compare(clientPreface, bytes) != 0) {
   267         if (Arrays.compare(clientPreface, bytes) != 0) {
   268             throw new IOException("Invalid preface: " + new String(bytes, 0, len));
   268             throw new IOException("Invalid preface: " + new String(bytes, 0, len));
   269         }
   269         }
   270     }
   270     }
   271 
   271 
   272     String doUpgrade() throws IOException {
   272     Http1InitialRequest doUpgrade() throws IOException {
   273         String upgrade = readHttp1Request();
   273         Http1InitialRequest upgrade = readHttp1Request();
   274         String h2c = getHeader(upgrade, "Upgrade");
   274         String h2c = getHeader(upgrade.headers, "Upgrade");
   275         if (h2c == null || !h2c.equals("h2c")) {
   275         if (h2c == null || !h2c.equals("h2c")) {
   276             System.err.println("Server:HEADERS: " + upgrade);
   276             System.err.println("Server:HEADERS: " + upgrade);
   277             throw new IOException("Bad upgrade 1 " + h2c);
   277             throw new IOException("Bad upgrade 1 " + h2c);
   278         }
   278         }
   279 
   279 
   281                 "Upgrade", "h2c");
   281                 "Upgrade", "h2c");
   282 
   282 
   283         sendSettingsFrame();
   283         sendSettingsFrame();
   284         readPreface();
   284         readPreface();
   285 
   285 
   286         String clientSettingsString = getHeader(upgrade, "HTTP2-Settings");
   286         String clientSettingsString = getHeader(upgrade.headers, "HTTP2-Settings");
   287         clientSettings = getSettingsFromString(clientSettingsString);
   287         clientSettings = getSettingsFromString(clientSettingsString);
   288 
   288 
   289         return upgrade;
   289         return upgrade;
   290     }
   290     }
   291 
   291 
   311             throw new IOException("Expected SettingsFrame");
   311             throw new IOException("Expected SettingsFrame");
   312         return (SettingsFrame)frame;
   312         return (SettingsFrame)frame;
   313     }
   313     }
   314 
   314 
   315     void run() throws Exception {
   315     void run() throws Exception {
   316         String upgrade = null;
   316         Http1InitialRequest upgrade = null;
   317         if (!secure) {
   317         if (!secure) {
   318             upgrade = doUpgrade();
   318             upgrade = doUpgrade();
   319         } else {
   319         } else {
   320             readPreface();
   320             readPreface();
   321             sendSettingsFrame(true);
   321             sendSettingsFrame(true);
   460         }
   460         }
   461     }
   461     }
   462 
   462 
   463     // First stream (1) comes from a plaintext HTTP/1.1 request
   463     // First stream (1) comes from a plaintext HTTP/1.1 request
   464     @SuppressWarnings({"rawtypes","unchecked"})
   464     @SuppressWarnings({"rawtypes","unchecked"})
   465     void createPrimordialStream(String request) throws IOException {
   465     void createPrimordialStream(Http1InitialRequest request) throws IOException {
   466         HttpHeadersImpl headers = new HttpHeadersImpl();
   466         HttpHeadersImpl headers = new HttpHeadersImpl();
   467         String requestLine = getRequestLine(request);
   467         String requestLine = getRequestLine(request.headers);
   468         String[] tokens = requestLine.split(" ");
   468         String[] tokens = requestLine.split(" ");
   469         if (!tokens[2].equals("HTTP/1.1")) {
   469         if (!tokens[2].equals("HTTP/1.1")) {
   470             throw new IOException("bad request line");
   470             throw new IOException("bad request line");
   471         }
   471         }
   472         URI uri = null;
   472         URI uri = null;
   473         try {
   473         try {
   474             uri = new URI(tokens[1]);
   474             uri = new URI(tokens[1]);
   475         } catch (URISyntaxException e) {
   475         } catch (URISyntaxException e) {
   476             throw new IOException(e);
   476             throw new IOException(e);
   477         }
   477         }
   478         String host = getHeader(request, "Host");
   478         String host = getHeader(request.headers, "Host");
   479         if (host == null) {
   479         if (host == null) {
   480             throw new IOException("missing Host");
   480             throw new IOException("missing Host");
   481         }
   481         }
   482 
   482 
   483         headers.setHeader(":method", tokens[0]);
   483         headers.setHeader(":method", tokens[0]);
   484         headers.setHeader(":scheme", "http"); // always in this case
   484         headers.setHeader(":scheme", "http"); // always in this case
   485         headers.setHeader(":authority", host);
   485         headers.setHeader(":authority", host);
   486         headers.setHeader(":path", uri.getPath());
   486         headers.setHeader(":path", uri.getPath());
   487         Queue q = new Queue(sentinel);
   487         Queue q = new Queue(sentinel);
   488         String body = getRequestBody(request);
   488         byte[] body = getRequestBody(request);
   489         addHeaders(getHeaders(request), headers);
   489         addHeaders(getHeaders(request.headers), headers);
   490         headers.setHeader("Content-length", Integer.toString(body.length()));
   490         headers.setHeader("Content-length", Integer.toString(body.length));
   491 
   491 
   492         addRequestBodyToQueue(body, q);
   492         addRequestBodyToQueue(body, q);
   493         streams.put(1, q);
   493         streams.put(1, q);
   494         exec.submit(() -> {
   494         exec.submit(() -> {
   495             handleRequest(headers, q, 1, true /*complete request has been read*/);
   495             handleRequest(headers, q, 1, true /*complete request has been read*/);
   883     }
   883     }
   884 
   884 
   885     final static String CRLF = "\r\n";
   885     final static String CRLF = "\r\n";
   886     final static String CRLFCRLF = "\r\n\r\n";
   886     final static String CRLFCRLF = "\r\n\r\n";
   887 
   887 
   888     String readHttp1Request() throws IOException {
   888     static class Http1InitialRequest {
       
   889         final String headers;
       
   890         final byte[] body;
       
   891         Http1InitialRequest(String headers, byte[] body) {
       
   892             this.headers = headers;
       
   893             this.body = body.clone();
       
   894         }
       
   895     }
       
   896 
       
   897     Http1InitialRequest readHttp1Request() throws IOException {
   889         String headers = readUntil(CRLF + CRLF);
   898         String headers = readUntil(CRLF + CRLF);
   890         int clen = getContentLength(headers);
   899         int clen = getContentLength(headers);
   891         String te = getHeader(headers, "Transfer-encoding");
   900         String te = getHeader(headers, "Transfer-encoding");
   892         byte[] buf = new byte[0];
   901         byte[] buf = new byte[0];
   893         try {
   902         try {
   897                 is.readNBytes(buf, 0, clen);
   906                 is.readNBytes(buf, 0, clen);
   898             } else if ("chunked".equalsIgnoreCase(te)) {
   907             } else if ("chunked".equalsIgnoreCase(te)) {
   899                 //  HTTP/1.1 chunked data, read it
   908                 //  HTTP/1.1 chunked data, read it
   900                 buf = readChunkedInputStream(is);
   909                 buf = readChunkedInputStream(is);
   901             }
   910             }
   902             String body = new String(buf, StandardCharsets.US_ASCII);
   911             return new Http1InitialRequest(headers, buf);
   903             return headers + body;
       
   904         } catch (IOException e) {
   912         } catch (IOException e) {
   905             System.err.println("TestServer: headers read: [ " + headers + " ]");
   913             System.err.println("TestServer: headers read: [ " + headers + " ]");
   906             throw e;
   914             throw e;
   907         }
   915         }
   908     }
   916     }
   941     final static ByteBuffer[] bbarray = new ByteBuffer[0];
   949     final static ByteBuffer[] bbarray = new ByteBuffer[0];
   942 
   950 
   943     // wrapper around a BlockingQueue that throws an exception when it's closed
   951     // wrapper around a BlockingQueue that throws an exception when it's closed
   944     // Each stream has one of these
   952     // Each stream has one of these
   945 
   953 
   946     String getRequestBody(String request) {
   954     byte[] getRequestBody(Http1InitialRequest request) {
   947         int bodystart = request.indexOf(CRLF+CRLF);
   955         return request.body;
   948         String body;
       
   949         if (bodystart == -1)
       
   950             body = "";
       
   951         else
       
   952             body = request.substring(bodystart+4);
       
   953         return body;
       
   954     }
   956     }
   955 
   957 
   956     @SuppressWarnings({"rawtypes","unchecked"})
   958     @SuppressWarnings({"rawtypes","unchecked"})
   957     void addRequestBodyToQueue(String body, Queue q) throws IOException {
   959     void addRequestBodyToQueue(byte[] body, Queue q) throws IOException {
   958         ByteBuffer buf = ByteBuffer.wrap(body.getBytes(StandardCharsets.US_ASCII));
   960         ByteBuffer buf = ByteBuffer.wrap(body);
   959         DataFrame df = new DataFrame(1, DataFrame.END_STREAM, buf);
   961         DataFrame df = new DataFrame(1, DataFrame.END_STREAM, buf);
   960         // only used for primordial stream
   962         // only used for primordial stream
   961         q.put(df);
   963         q.put(df);
   962     }
   964     }
   963 
   965