24 */ |
24 */ |
25 |
25 |
26 package jdk.incubator.http; |
26 package jdk.incubator.http; |
27 |
27 |
28 import java.security.AccessControlContext; |
28 import java.security.AccessControlContext; |
|
29 import java.security.AccessController; |
29 import java.util.Objects; |
30 import java.util.Objects; |
30 import java.util.Optional; |
|
31 import java.util.concurrent.CompletableFuture; |
31 import java.util.concurrent.CompletableFuture; |
|
32 import jdk.incubator.http.HttpResponse.BodyHandler; |
32 import jdk.incubator.http.HttpResponse.PushPromiseHandler; |
33 import jdk.incubator.http.HttpResponse.PushPromiseHandler; |
33 import jdk.incubator.http.HttpResponse.UntrustedBodyHandler; |
34 import jdk.incubator.http.HttpResponse.UntrustedBodyHandler; |
34 import jdk.incubator.http.internal.common.MinimalFuture; |
35 import jdk.incubator.http.internal.common.MinimalFuture; |
35 import jdk.incubator.http.internal.common.Log; |
36 import jdk.incubator.http.internal.common.Log; |
36 |
37 |
72 if (pushPromiseHandler instanceof UntrustedBodyHandler) |
73 if (pushPromiseHandler instanceof UntrustedBodyHandler) |
73 ((UntrustedBodyHandler)this.pushPromiseHandler).setAccessControlContext(acc); |
74 ((UntrustedBodyHandler)this.pushPromiseHandler).setAccessControlContext(acc); |
74 this.acc = acc; |
75 this.acc = acc; |
75 } |
76 } |
76 |
77 |
77 static class Acceptor<T> { |
78 interface Acceptor<T> { |
78 final HttpRequest initiator, push; |
79 BodyHandler<T> bodyHandler(); |
79 volatile HttpResponse.BodyHandler<T> bodyHandler = null; |
80 CompletableFuture<HttpResponse<T>> cf(); |
80 volatile CompletableFuture<HttpResponse<T>> cf; |
81 boolean accepted(); |
|
82 } |
81 |
83 |
82 Acceptor(HttpRequest initiator, HttpRequest push) { |
84 private static class AcceptorImpl<T> implements Acceptor<T> { |
83 this.initiator = initiator; |
85 private volatile HttpResponse.BodyHandler<T> bodyHandler; |
84 this.push = push; |
86 private volatile CompletableFuture<HttpResponse<T>> cf; |
85 } |
|
86 |
87 |
87 CompletableFuture<HttpResponse<T>> accept(HttpResponse.BodyHandler<T> bodyHandler) { |
88 CompletableFuture<HttpResponse<T>> accept(BodyHandler<T> bodyHandler) { |
88 Objects.requireNonNull(bodyHandler); |
89 Objects.requireNonNull(bodyHandler); |
|
90 if (this.bodyHandler != null) |
|
91 throw new IllegalStateException("non-null bodyHandler"); |
|
92 this.bodyHandler = bodyHandler; |
89 cf = new MinimalFuture<>(); |
93 cf = new MinimalFuture<>(); |
90 if (this.bodyHandler != null) |
|
91 throw new IllegalStateException(); |
|
92 this.bodyHandler = bodyHandler; |
|
93 return cf; |
94 return cf; |
94 } |
95 } |
95 |
96 |
96 HttpResponse.BodyHandler<T> bodyHandler() { |
97 @Override public BodyHandler<T> bodyHandler() { return bodyHandler; } |
97 return bodyHandler; |
|
98 } |
|
99 |
98 |
100 CompletableFuture<HttpResponse<T>> cf() { |
99 @Override public CompletableFuture<HttpResponse<T>> cf() { return cf; } |
101 return cf; |
|
102 } |
|
103 |
100 |
104 boolean accepted() { |
101 @Override public boolean accepted() { return cf != null; } |
105 return cf != null; |
|
106 } |
|
107 } |
102 } |
108 |
103 |
109 Acceptor<T> acceptPushRequest(HttpRequest pushRequest) { |
104 Acceptor<T> acceptPushRequest(HttpRequest pushRequest) { |
110 Acceptor<T> acceptor = new Acceptor<>(initiatingRequest, pushRequest); |
105 AcceptorImpl<T> acceptor = new AcceptorImpl<>(); |
111 |
106 |
112 pushPromiseHandler.applyPushPromise(initiatingRequest, pushRequest, acceptor::accept); |
107 pushPromiseHandler.applyPushPromise(initiatingRequest, pushRequest, acceptor::accept); |
113 |
108 |
114 if (acceptor.accepted()) { |
109 if (acceptor.accepted()) { |
|
110 if (acceptor.bodyHandler instanceof UntrustedBodyHandler) { |
|
111 ((UntrustedBodyHandler)acceptor.bodyHandler).setAccessControlContext(acc); |
|
112 } |
115 numberOfPushes++; |
113 numberOfPushes++; |
116 remainingPushes++; |
114 remainingPushes++; |
117 } |
115 } |
118 return acceptor; |
116 return acceptor; |
119 |
117 |