test/jdk/java/net/httpclient/HttpServerAdapters.java
branchhttp-client-branch
changeset 56619 57f17e890a40
parent 56451 9585061fdb04
child 56795 03ece2518428
equal deleted inserted replaced
56618:e4022357f852 56619:57f17e890a40
    25 import com.sun.net.httpserver.Headers;
    25 import com.sun.net.httpserver.Headers;
    26 import com.sun.net.httpserver.HttpContext;
    26 import com.sun.net.httpserver.HttpContext;
    27 import com.sun.net.httpserver.HttpExchange;
    27 import com.sun.net.httpserver.HttpExchange;
    28 import com.sun.net.httpserver.HttpHandler;
    28 import com.sun.net.httpserver.HttpHandler;
    29 import com.sun.net.httpserver.HttpServer;
    29 import com.sun.net.httpserver.HttpServer;
       
    30 import jdk.internal.net.http.common.HttpHeadersBuilder;
    30 
    31 
    31 import java.net.InetAddress;
    32 import java.net.InetAddress;
    32 import java.io.ByteArrayInputStream;
    33 import java.io.ByteArrayInputStream;
    33 import java.net.http.HttpClient.Version;
    34 import java.net.http.HttpClient.Version;
    34 import jdk.internal.net.http.common.HttpHeadersImpl;
       
    35 import java.io.ByteArrayOutputStream;
    35 import java.io.ByteArrayOutputStream;
    36 import java.io.IOException;
    36 import java.io.IOException;
    37 import java.io.InputStream;
    37 import java.io.InputStream;
    38 import java.io.OutputStream;
    38 import java.io.OutputStream;
    39 import java.io.PrintStream;
    39 import java.io.PrintStream;
    40 import java.io.UncheckedIOException;
    40 import java.io.UncheckedIOException;
    41 import java.math.BigInteger;
    41 import java.math.BigInteger;
    42 import java.net.InetSocketAddress;
    42 import java.net.InetSocketAddress;
    43 import java.net.URI;
    43 import java.net.URI;
       
    44 import java.net.http.HttpHeaders;
    44 import java.util.List;
    45 import java.util.List;
    45 import java.util.ListIterator;
    46 import java.util.ListIterator;
    46 import java.util.Map;
    47 import java.util.Map;
    47 import java.util.Optional;
    48 import java.util.Optional;
    48 import java.util.Set;
    49 import java.util.Set;
    93         out.println(prefix + bytes.length + " "
    94         out.println(prefix + bytes.length + " "
    94                     + new BigInteger(bigbytes).toString(16));
    95                     + new BigInteger(bigbytes).toString(16));
    95     }
    96     }
    96 
    97 
    97     /**
    98     /**
    98      * A version agnostic adapter class for HTTP Headers.
    99      * A version agnostic adapter class for HTTP request Headers.
    99      */
   100      */
   100     public static abstract class HttpTestHeaders {
   101     public static abstract class HttpTestRequestHeaders {
   101         public abstract Optional<String> firstValue(String name);
   102         public abstract Optional<String> firstValue(String name);
   102         public abstract void addHeader(String name, String value);
       
   103         public abstract Set<String> keySet();
   103         public abstract Set<String> keySet();
   104         public abstract Set<Map.Entry<String, List<String>>> entrySet();
   104         public abstract Set<Map.Entry<String, List<String>>> entrySet();
   105         public abstract List<String> get(String name);
   105         public abstract List<String> get(String name);
   106         public abstract boolean containsKey(String name);
   106         public abstract boolean containsKey(String name);
   107 
   107 
   108         public static HttpTestHeaders of(Headers headers) {
   108         public static HttpTestRequestHeaders of(Headers headers) {
   109             return new Http1TestHeaders(headers);
   109             return new Http1TestRequestHeaders(headers);
   110         }
   110         }
   111         public static HttpTestHeaders of(HttpHeadersImpl headers) {
   111 
   112             return new Http2TestHeaders(headers);
   112         public static HttpTestRequestHeaders of(HttpHeaders headers) {
   113         }
   113             return new Http2TestRequestHeaders(headers);
   114 
   114         }
   115         private final static class Http1TestHeaders extends HttpTestHeaders {
   115 
       
   116         private static final class Http1TestRequestHeaders extends HttpTestRequestHeaders {
   116             private final Headers headers;
   117             private final Headers headers;
   117             Http1TestHeaders(Headers h) { this.headers = h; }
   118             Http1TestRequestHeaders(Headers h) { this.headers = h; }
   118             @Override
   119             @Override
   119             public Optional<String> firstValue(String name) {
   120             public Optional<String> firstValue(String name) {
   120                 if (headers.containsKey(name)) {
   121                 if (headers.containsKey(name)) {
   121                     return Optional.ofNullable(headers.getFirst(name));
   122                     return Optional.ofNullable(headers.getFirst(name));
   122                 }
   123                 }
   123                 return Optional.empty();
   124                 return Optional.empty();
   124             }
   125             }
   125             @Override
   126             @Override
       
   127             public Set<String> keySet() { return headers.keySet(); }
       
   128             @Override
       
   129             public Set<Map.Entry<String, List<String>>> entrySet() {
       
   130                 return headers.entrySet();
       
   131             }
       
   132             @Override
       
   133             public List<String> get(String name) {
       
   134                 return headers.get(name);
       
   135             }
       
   136             @Override
       
   137             public boolean containsKey(String name) {
       
   138                 return headers.containsKey(name);
       
   139             }
       
   140         }
       
   141         private static final class Http2TestRequestHeaders extends HttpTestRequestHeaders {
       
   142             private final HttpHeaders headers;
       
   143             Http2TestRequestHeaders(HttpHeaders h) { this.headers = h; }
       
   144             @Override
       
   145             public Optional<String> firstValue(String name) {
       
   146                 return headers.firstValue(name);
       
   147             }
       
   148             @Override
       
   149             public Set<String> keySet() { return headers.map().keySet(); }
       
   150             @Override
       
   151             public Set<Map.Entry<String, List<String>>> entrySet() {
       
   152                 return headers.map().entrySet();
       
   153             }
       
   154             @Override
       
   155             public List<String> get(String name) {
       
   156                 return headers.allValues(name);
       
   157             }
       
   158             @Override
       
   159             public boolean containsKey(String name) {
       
   160                 return headers.firstValue(name).isPresent();
       
   161             }
       
   162         }
       
   163     }
       
   164 
       
   165     /**
       
   166      * A version agnostic adapter class for HTTP response Headers.
       
   167      */
       
   168     public static abstract class HttpTestResponseHeaders {
       
   169         public abstract void addHeader(String name, String value);
       
   170 
       
   171         public static HttpTestResponseHeaders of(Headers headers) {
       
   172             return new Http1TestResponseHeaders(headers);
       
   173         }
       
   174         public static HttpTestResponseHeaders of(HttpHeadersBuilder headersBuilder) {
       
   175             return new Http2TestResponseHeaders(headersBuilder);
       
   176         }
       
   177 
       
   178         private final static class Http1TestResponseHeaders extends HttpTestResponseHeaders {
       
   179             private final Headers headers;
       
   180             Http1TestResponseHeaders(Headers h) { this.headers = h; }
       
   181             @Override
   126             public void addHeader(String name, String value) {
   182             public void addHeader(String name, String value) {
   127                 headers.add(name, value);
   183                 headers.add(name, value);
   128             }
   184             }
   129 
   185         }
   130             @Override
   186         private final static class Http2TestResponseHeaders extends HttpTestResponseHeaders {
   131             public Set<String> keySet() { return headers.keySet(); }
   187             private final HttpHeadersBuilder headersBuilder;
   132             @Override
   188             Http2TestResponseHeaders(HttpHeadersBuilder hb) { this.headersBuilder = hb; }
   133             public Set<Map.Entry<String, List<String>>> entrySet() {
       
   134                 return headers.entrySet();
       
   135             }
       
   136             @Override
       
   137             public List<String> get(String name) {
       
   138                 return headers.get(name);
       
   139             }
       
   140             @Override
       
   141             public boolean containsKey(String name) {
       
   142                 return headers.containsKey(name);
       
   143             }
       
   144         }
       
   145         private final static class Http2TestHeaders extends HttpTestHeaders {
       
   146             private final HttpHeadersImpl headers;
       
   147             Http2TestHeaders(HttpHeadersImpl h) { this.headers = h; }
       
   148             @Override
       
   149             public Optional<String> firstValue(String name) {
       
   150                 return headers.firstValue(name);
       
   151             }
       
   152             @Override
   189             @Override
   153             public void addHeader(String name, String value) {
   190             public void addHeader(String name, String value) {
   154                 headers.addHeader(name, value);
   191                 headersBuilder.addHeader(name, value);
   155             }
       
   156             public Set<String> keySet() { return headers.map().keySet(); }
       
   157             @Override
       
   158             public Set<Map.Entry<String, List<String>>> entrySet() {
       
   159                 return headers.map().entrySet();
       
   160             }
       
   161             @Override
       
   162             public List<String> get(String name) {
       
   163                 return headers.allValues(name);
       
   164             }
       
   165             @Override
       
   166             public boolean containsKey(String name) {
       
   167                 return headers.firstValue(name).isPresent();
       
   168             }
   192             }
   169         }
   193         }
   170     }
   194     }
   171 
   195 
   172     /**
   196     /**
   175     public static abstract class HttpTestExchange {
   199     public static abstract class HttpTestExchange {
   176         public abstract Version getServerVersion();
   200         public abstract Version getServerVersion();
   177         public abstract Version getExchangeVersion();
   201         public abstract Version getExchangeVersion();
   178         public abstract InputStream   getRequestBody();
   202         public abstract InputStream   getRequestBody();
   179         public abstract OutputStream  getResponseBody();
   203         public abstract OutputStream  getResponseBody();
   180         public abstract HttpTestHeaders getRequestHeaders();
   204         public abstract HttpTestRequestHeaders getRequestHeaders();
   181         public abstract HttpTestHeaders getResponseHeaders();
   205         public abstract HttpTestResponseHeaders getResponseHeaders();
   182         public abstract void sendResponseHeaders(int code, int contentLength) throws IOException;
   206         public abstract void sendResponseHeaders(int code, int contentLength) throws IOException;
   183         public abstract URI getRequestURI();
   207         public abstract URI getRequestURI();
   184         public abstract String getRequestMethod();
   208         public abstract String getRequestMethod();
   185         public abstract void close();
   209         public abstract void close();
   186         public void serverPush(URI uri, HttpTestHeaders headers, byte[] body) {
   210         public void serverPush(URI uri, HttpHeaders headers, byte[] body) {
   187             ByteArrayInputStream bais = new ByteArrayInputStream(body);
   211             ByteArrayInputStream bais = new ByteArrayInputStream(body);
   188             serverPush(uri, headers, bais);
   212             serverPush(uri, headers, bais);
   189         }
   213         }
   190         public void serverPush(URI uri, HttpTestHeaders headers, InputStream body) {
   214         public void serverPush(URI uri, HttpHeaders headers, InputStream body) {
   191             throw new UnsupportedOperationException("serverPush with " + getExchangeVersion());
   215             throw new UnsupportedOperationException("serverPush with " + getExchangeVersion());
   192         }
   216         }
   193         public boolean serverPushAllowed() {
   217         public boolean serverPushAllowed() {
   194             return false;
   218             return false;
   195         }
   219         }
   219             @Override
   243             @Override
   220             public OutputStream getResponseBody() {
   244             public OutputStream getResponseBody() {
   221                 return exchange.getResponseBody();
   245                 return exchange.getResponseBody();
   222             }
   246             }
   223             @Override
   247             @Override
   224             public HttpTestHeaders getRequestHeaders() {
   248             public HttpTestRequestHeaders getRequestHeaders() {
   225                 return HttpTestHeaders.of(exchange.getRequestHeaders());
   249                 return HttpTestRequestHeaders.of(exchange.getRequestHeaders());
   226             }
   250             }
   227             @Override
   251             @Override
   228             public HttpTestHeaders getResponseHeaders() {
   252             public HttpTestResponseHeaders getResponseHeaders() {
   229                 return HttpTestHeaders.of(exchange.getResponseHeaders());
   253                 return HttpTestResponseHeaders.of(exchange.getResponseHeaders());
   230             }
   254             }
   231             @Override
   255             @Override
   232             public void sendResponseHeaders(int code, int contentLength) throws IOException {
   256             public void sendResponseHeaders(int code, int contentLength) throws IOException {
   233                 if (contentLength == 0) contentLength = -1;
   257                 if (contentLength == 0) contentLength = -1;
   234                 else if (contentLength < 0) contentLength = 0;
   258                 else if (contentLength < 0) contentLength = 0;
   266             @Override
   290             @Override
   267             public OutputStream getResponseBody() {
   291             public OutputStream getResponseBody() {
   268                 return exchange.getResponseBody();
   292                 return exchange.getResponseBody();
   269             }
   293             }
   270             @Override
   294             @Override
   271             public HttpTestHeaders getRequestHeaders() {
   295             public HttpTestRequestHeaders getRequestHeaders() {
   272                 return HttpTestHeaders.of(exchange.getRequestHeaders());
   296                 return HttpTestRequestHeaders.of(exchange.getRequestHeaders());
   273             }
   297             }
   274             @Override
   298 
   275             public HttpTestHeaders getResponseHeaders() {
   299             @Override
   276                 return HttpTestHeaders.of(exchange.getResponseHeaders());
   300             public HttpTestResponseHeaders getResponseHeaders() {
       
   301                 return HttpTestResponseHeaders.of(exchange.getResponseHeaders());
   277             }
   302             }
   278             @Override
   303             @Override
   279             public void sendResponseHeaders(int code, int contentLength) throws IOException {
   304             public void sendResponseHeaders(int code, int contentLength) throws IOException {
   280                 if (contentLength == 0) contentLength = -1;
   305                 if (contentLength == 0) contentLength = -1;
   281                 else if (contentLength < 0) contentLength = 0;
   306                 else if (contentLength < 0) contentLength = 0;
   284             @Override
   309             @Override
   285             public boolean serverPushAllowed() {
   310             public boolean serverPushAllowed() {
   286                 return exchange.serverPushAllowed();
   311                 return exchange.serverPushAllowed();
   287             }
   312             }
   288             @Override
   313             @Override
   289             public void serverPush(URI uri, HttpTestHeaders headers, InputStream body) {
   314             public void serverPush(URI uri, HttpHeaders headers, InputStream body) {
   290                 HttpHeadersImpl headersImpl;
   315                 exchange.serverPush(uri, headers, body);
   291                 if (headers instanceof HttpTestHeaders.Http2TestHeaders) {
       
   292                     headersImpl = ((HttpTestHeaders.Http2TestHeaders)headers).headers.deepCopy();
       
   293                 } else {
       
   294                     headersImpl = new HttpHeadersImpl();
       
   295                     for (Map.Entry<String, List<String>> e : headers.entrySet()) {
       
   296                         String name = e.getKey();
       
   297                         for (String v : e.getValue()) {
       
   298                             headersImpl.addHeader(name, v);
       
   299                         }
       
   300                     }
       
   301                 }
       
   302                 exchange.serverPush(uri, headersImpl, body);
       
   303             }
   316             }
   304             void doFilter(Filter.Chain filter) throws IOException {
   317             void doFilter(Filter.Chain filter) throws IOException {
   305                 throw new IOException("cannot use HTTP/1.1 filter with HTTP/2 server");
   318                 throw new IOException("cannot use HTTP/1.1 filter with HTTP/2 server");
   306             }
   319             }
   307             @Override
   320             @Override
   361             }
   374             }
   362         }
   375         }
   363     }
   376     }
   364 
   377 
   365     public static boolean expectException(HttpTestExchange e) {
   378     public static boolean expectException(HttpTestExchange e) {
   366         HttpTestHeaders h = e.getRequestHeaders();
   379         HttpTestRequestHeaders h = e.getRequestHeaders();
   367         Optional<String> expectException = h.firstValue("X-expect-exception");
   380         Optional<String> expectException = h.firstValue("X-expect-exception");
   368         if (expectException.isPresent()) {
   381         if (expectException.isPresent()) {
   369             return expectException.get().equalsIgnoreCase("true");
   382             return expectException.get().equalsIgnoreCase("true");
   370         }
   383         }
   371         return false;
   384         return false;