--- old/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PushGroup.java 2017-11-30 04:04:08.091848940 -0800 +++ new/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PushGroup.java 2017-11-30 04:04:07.863829006 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,11 @@ package jdk.incubator.http; +import java.security.AccessControlContext; +import java.util.Optional; import java.util.concurrent.CompletableFuture; +import jdk.incubator.http.HttpResponse.BodyHandler; +import jdk.incubator.http.HttpResponse.UntrustedBodyHandler; import jdk.incubator.http.internal.common.MinimalFuture; import jdk.incubator.http.internal.common.Log; @@ -38,59 +42,82 @@ final CompletableFuture resultCF; final CompletableFuture noMorePushesCF; - volatile Throwable error; // any exception that occured during pushes + volatile Throwable error; // any exception that occurred during pushes // CF for main response final CompletableFuture> mainResponse; - // user's processor object - final HttpResponse.MultiProcessor multiProcessor; + // user's subscriber object + final HttpResponse.MultiSubscriber multiSubscriber; final HttpResponse.BodyHandler mainBodyHandler; + private final AccessControlContext acc; + int numberOfPushes; int remainingPushes; boolean noMorePushes = false; - PushGroup(HttpResponse.MultiProcessor multiProcessor, HttpRequestImpl req) { - this(multiProcessor, req, new MinimalFuture<>()); + PushGroup(HttpResponse.MultiSubscriber multiSubscriber, + HttpRequestImpl req, + AccessControlContext acc) { + this(multiSubscriber, req, new MinimalFuture<>(), acc); } // Check mainBodyHandler before calling nested constructor. - private PushGroup(HttpResponse.MultiProcessor multiProcessor, - HttpRequestImpl req, - CompletableFuture> mainResponse) { - this(multiProcessor, mainResponse, - multiProcessor.onRequest(req).orElseThrow( - () -> new IllegalArgumentException( - "A valid body processor for the main response is required"))); + private PushGroup(HttpResponse.MultiSubscriber multiSubscriber, + HttpRequestImpl req, + CompletableFuture> mainResponse, + AccessControlContext acc) { + this(multiSubscriber, + mainResponse, + multiSubscriber.onRequest(req), + acc); } - // This private constructor is called after all parameters have been - // checked. - private PushGroup(HttpResponse.MultiProcessor multiProcessor, + // This private constructor is called after all parameters have been checked. + private PushGroup(HttpResponse.MultiSubscriber multiSubscriber, CompletableFuture> mainResponse, - HttpResponse.BodyHandler mainBodyHandler) { + HttpResponse.BodyHandler mainBodyHandler, + AccessControlContext acc) { assert mainResponse != null; // A new instance is created above assert mainBodyHandler != null; // should have been checked above this.resultCF = new MinimalFuture<>(); this.noMorePushesCF = new MinimalFuture<>(); - this.multiProcessor = multiProcessor; + this.multiSubscriber = multiSubscriber; this.mainResponse = mainResponse.thenApply(r -> { - multiProcessor.onResponse(r); + multiSubscriber.onResponse(r); return r; }); this.mainBodyHandler = mainBodyHandler; + if (acc != null) { + // Restricts the file publisher with the senders ACC, if any + if (mainBodyHandler instanceof UntrustedBodyHandler) + ((UntrustedBodyHandler)this.mainBodyHandler).setAccessControlContext(acc); + } + this.acc = acc; } CompletableFuture groupResult() { return resultCF; } - HttpResponse.MultiProcessor processor() { - return multiProcessor; + HttpResponse.MultiSubscriber subscriber() { + return multiSubscriber; + } + + Optional> handlerForPushRequest(HttpRequest ppRequest) { + Optional> bh = multiSubscriber.onPushPromise(ppRequest); + if (acc != null && bh.isPresent()) { + // Restricts the file publisher with the senders ACC, if any + BodyHandler x = bh.get(); + if (x instanceof UntrustedBodyHandler) + ((UntrustedBodyHandler)x).setAccessControlContext(acc); + bh = Optional.of(x); + } + return bh; } HttpResponse.BodyHandler mainResponseHandler() { @@ -106,18 +133,11 @@ }); } - synchronized CompletableFuture> mainResponse() { - return mainResponse; - } - synchronized void addPush() { numberOfPushes++; remainingPushes++; } - synchronized int numberOfPushes() { - return numberOfPushes; - } // This is called when the main body response completes because it means // no more PUSH_PROMISEs are possible