< prev index next >

src/java.httpclient/share/classes/java/net/http/HttpRequestImpl.java

Print this page

        

@@ -28,20 +28,18 @@
 import java.net.ProxySelector;
 import java.net.URI;
 import java.net.http.HttpClient.Version;
 import java.net.http.HttpResponse.MultiProcessor;
 import java.util.concurrent.CompletableFuture;
-import java.net.SocketPermission;
 import java.security.AccessControlContext;
 import java.security.AccessController;
-import java.util.Set;
 import static java.net.http.HttpRedirectImpl.getRedirects;
 import java.util.Locale;
 
 class HttpRequestImpl extends HttpRequest {
 
-    private final HttpHeadersImpl userHeaders;
+    private final ImmutableHeaders userHeaders;
     private final HttpHeadersImpl systemHeaders;
     private final URI uri;
     private InetSocketAddress authority; // only used when URI not specified
     private final String method;
     private final HttpClientImpl client;

@@ -54,19 +52,20 @@
     private boolean isWebSocket;
     final MultiExchange exchange;
     private boolean receiving;
     private AccessControlContext acc;
     private final long timeval;
+    private Stream.PushGroup<?> pushGroup;
 
     public HttpRequestImpl(HttpClientImpl client,
                            String method,
                            HttpRequestBuilderImpl builder) {
         this.client = client;
         this.method = method == null? "GET" : method;
         this.userHeaders = builder.headers() == null ?
-                new HttpHeadersImpl() : builder.headers();
-        dropDisallowedHeaders();
+                new ImmutableHeaders() :
+                new ImmutableHeaders(builder.headers(), Utils.ALLOWED_HEADERS);
         this.followRedirects = getRedirects(builder.followRedirects() == null ?
                 client.followRedirects() : builder.followRedirects());
         this.systemHeaders = new HttpHeadersImpl();
         this.uri = builder.uri();
         this.proxy = builder.proxy();

@@ -88,13 +87,11 @@
                            HttpClientImpl client,
                            String method,
                            HttpRequestImpl other) {
         this.client = client;
         this.method = method == null? "GET" : method;
-        this.userHeaders = other.userHeaders == null ?
-                new HttpHeadersImpl() : other.userHeaders;
-        dropDisallowedHeaders();
+        this.userHeaders = other.userHeaders;
         this.followRedirects = getRedirects(other.followRedirects() == null ?
                 client.followRedirects() : other.followRedirects());
         this.systemHeaders = other.systemHeaders;
         this.uri = uri;
         this.expectContinue = other.expectContinue;

@@ -113,11 +110,11 @@
                     InetSocketAddress authority) {
         this.client = client;
         this.method = method;
         this.followRedirects = getRedirects(client.followRedirects());
         this.systemHeaders = new HttpHeadersImpl();
-        this.userHeaders = new HttpHeadersImpl();
+        this.userHeaders = new ImmutableHeaders();
         this.uri = null;
         this.proxy = null;
         this.requestProcessor = HttpRequest.noBody();
         this.version = java.net.http.HttpClient.Version.HTTP_1_1;
         this.authority = authority;

@@ -130,20 +127,59 @@
     @Override
     public HttpClientImpl client() {
         return client;
     }
 
+    /**
+     * Creates a HttpRequestImpl from the given set of Headers and the associated
+     * "parent" request. Fields not taken from the headers are taken from the
+     * parent.
+     *
+     * @param parent
+     * @param headers
+     * @return
+     * @throws IOException
+     */
+    static HttpRequestImpl createPushRequest(HttpRequestImpl parent, HttpHeadersImpl headers) throws IOException {
+        return new HttpRequestImpl(parent, headers);
+    }
+
+    // only used for push requests
+    private HttpRequestImpl(HttpRequestImpl parent, HttpHeadersImpl headers) throws IOException {
+        this.method = headers.firstValue(":method")
+                .orElseThrow(() -> new IOException("No method in Push Promise"));
+        String path = headers.firstValue(":path")
+                .orElseThrow(() -> new IOException("No path in Push Promise"));
+        String scheme = headers.firstValue(":scheme")
+                .orElseThrow(() -> new IOException("No scheme in Push Promise"));
+        String authority = headers.firstValue(":authority")
+                .orElseThrow(() -> new IOException("No authority in Push Promise"));
+        StringBuilder sb = new StringBuilder();
+        sb.append(scheme).append("://").append(authority).append(path);
+        this.uri = URI.create(sb.toString());
+
+        this.client = parent.client;
+        this.userHeaders = new ImmutableHeaders(headers, Utils.ALLOWED_HEADERS);
+        this.followRedirects = parent.followRedirects;
+        this.systemHeaders = parent.systemHeaders;
+        this.expectContinue = parent.expectContinue;
+        this.secure = parent.secure;
+        this.requestProcessor = parent.requestProcessor;
+        this.proxy = parent.proxy;
+        this.version = parent.version;
+        this.acc = parent.acc;
+        this.exchange = parent.exchange;
+        this.timeval = parent.timeval;
+    }
 
     @Override
     public String toString() {
-        return (uri == null ? "" : uri.toString()) + "/" + method + "("
-                + hashCode() + ")";
+        return (uri == null ? "" : uri.toString()) + " " + method;
     }
 
     @Override
     public HttpHeaders headers() {
-        userHeaders.makeUnmodifiable();
         return userHeaders;
     }
 
     InetSocketAddress authority() { return authority; }
 

@@ -152,32 +188,21 @@
         systemHeaders.setHeader("Connection", "Upgrade, HTTP2-Settings");
         systemHeaders.setHeader("Upgrade", "h2c");
         systemHeaders.setHeader("HTTP2-Settings", h2client.getSettingsString());
     }
 
-    private static final Set<String>  DISALLOWED_HEADERS_SET = Set.of(
-        "authorization", "connection", "cookie", "content-length",
-        "date", "expect", "from", "host", "origin", "proxy-authorization",
-        "referer", "user-agent", "upgrade", "via", "warning");
-
-
-    // we silently drop headers that are disallowed
-    private void dropDisallowedHeaders() {
-        Set<String> hdrnames = userHeaders.directMap().keySet();
-
-        hdrnames.removeIf((s) ->
-              DISALLOWED_HEADERS_SET.contains(s.toLowerCase())
-        );
-    }
-
     private synchronized void receiving() {
         if (receiving) {
             throw new IllegalStateException("already receiving response");
         }
         receiving = true;
     }
 
+    synchronized Stream.PushGroup<?> pushGroup() {
+        return pushGroup;
+    }
+
     /*
      * Response filters may result in a new HttpRequestImpl being created
      * (but still associated with the same API HttpRequest) and the process
      * is repeated.
      */

@@ -198,14 +223,29 @@
         }
         return exchange.responseAsync(null)
             .thenApply((r) -> (HttpResponse)r);
     }
 
-    public <U> CompletableFuture<U>
-    sendAsyncMulti(HttpResponse.MultiProcessor<U> rspproc) {
-        // To change body of generated methods, choose Tools | Templates.
-        throw new UnsupportedOperationException("Not supported yet.");
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public synchronized <U> CompletableFuture<U>
+    multiResponseAsync(MultiProcessor<U> rspproc) {
+        if (System.getSecurityManager() != null) {
+            acc = AccessController.getContext();
+        }
+        this.pushGroup = new Stream.PushGroup<>(rspproc, this);
+        CompletableFuture<HttpResponse> cf = pushGroup.mainResponse();
+        responseAsync()
+            .whenComplete((HttpResponse r, Throwable t) -> {
+                if (r != null)
+                    cf.complete(r);
+                else
+                    cf.completeExceptionally(t);
+                pushGroup.pushError(t);
+            });
+        return (CompletableFuture<U>)pushGroup.groupResult();
     }
 
     @Override
     public boolean expectContinue() { return expectContinue; }
 

@@ -253,11 +293,11 @@
     public String method() { return method; }
 
     @Override
     public URI uri() { return uri; }
 
-    HttpHeadersImpl getUserHeaders() { return userHeaders; }
+    HttpHeaders getUserHeaders() { return userHeaders; }
 
     HttpHeadersImpl getSystemHeaders() { return systemHeaders; }
 
     HttpClientImpl getClient() { return client; }
 

@@ -273,13 +313,6 @@
     void setSystemHeader(String name, String value) {
         systemHeaders.setHeader(name, value);
     }
 
     long timeval() { return timeval; }
-
-    @Override
-    public <U> CompletableFuture<U>
-    multiResponseAsync(MultiProcessor<U> rspproc) {
-        //To change body of generated methods, choose Tools | Templates.
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
 }
< prev index next >