Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.net.http/share/classes/jdk/internal/net/http/HttpResponseImpl.java
41171 views
1
/*
2
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
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
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package jdk.internal.net.http;
27
28
import java.io.IOException;
29
import java.net.URI;
30
import java.nio.ByteBuffer;
31
import java.util.Optional;
32
import java.util.concurrent.CompletableFuture;
33
import java.util.function.Supplier;
34
import javax.net.ssl.SSLSession;
35
import java.net.http.HttpClient;
36
import java.net.http.HttpHeaders;
37
import java.net.http.HttpRequest;
38
import java.net.http.HttpResponse;
39
import jdk.internal.net.http.websocket.RawChannel;
40
41
/**
42
* The implementation class for HttpResponse
43
*/
44
class HttpResponseImpl<T> implements HttpResponse<T>, RawChannel.Provider {
45
46
final int responseCode;
47
final HttpRequest initialRequest;
48
final Optional<HttpResponse<T>> previousResponse;
49
final HttpHeaders headers;
50
final Optional<SSLSession> sslSession;
51
final URI uri;
52
final HttpClient.Version version;
53
final RawChannelProvider rawChannelProvider;
54
final T body;
55
56
public HttpResponseImpl(HttpRequest initialRequest,
57
Response response,
58
HttpResponse<T> previousResponse,
59
T body,
60
Exchange<T> exch) {
61
this.responseCode = response.statusCode();
62
this.initialRequest = initialRequest;
63
this.previousResponse = Optional.ofNullable(previousResponse);
64
this.headers = response.headers();
65
//this.trailers = trailers;
66
this.sslSession = Optional.ofNullable(response.getSSLSession());
67
this.uri = response.request().uri();
68
this.version = response.version();
69
this.rawChannelProvider = RawChannelProvider.create(response, exch);
70
this.body = body;
71
}
72
73
@Override
74
public int statusCode() {
75
return responseCode;
76
}
77
78
@Override
79
public HttpRequest request() {
80
return initialRequest;
81
}
82
83
@Override
84
public Optional<HttpResponse<T>> previousResponse() {
85
return previousResponse;
86
}
87
88
@Override
89
public HttpHeaders headers() {
90
return headers;
91
}
92
93
@Override
94
public T body() {
95
return body;
96
}
97
98
@Override
99
public Optional<SSLSession> sslSession() {
100
return sslSession;
101
}
102
103
@Override
104
public URI uri() {
105
return uri;
106
}
107
108
@Override
109
public HttpClient.Version version() {
110
return version;
111
}
112
// keepalive flag determines whether connection is closed or kept alive
113
// by reading/skipping data
114
115
/**
116
* Returns a RawChannel that may be used for WebSocket protocol.
117
* @implNote This implementation does not support RawChannel over
118
* HTTP/2 connections.
119
* @return a RawChannel that may be used for WebSocket protocol.
120
* @throws UnsupportedOperationException if getting a RawChannel over
121
* this connection is not supported.
122
* @throws IOException if an I/O exception occurs while retrieving
123
* the channel.
124
*/
125
@Override
126
public synchronized RawChannel rawChannel() throws IOException {
127
if (rawChannelProvider == null) {
128
throw new UnsupportedOperationException(
129
"RawChannel is only supported for WebSocket creation");
130
}
131
return rawChannelProvider.rawChannel();
132
}
133
134
/**
135
* Closes the RawChannel that may have been used for WebSocket protocol.
136
*
137
* @apiNote This method should be called to close the connection
138
* if an exception occurs during the websocket handshake, in cases where
139
* {@link #rawChannel() rawChannel().close()} would have been called.
140
* An unsuccessful handshake may prevent the creation of the RawChannel:
141
* if a RawChannel has already been created, this method wil close it.
142
* Otherwise, it will close the connection.
143
*
144
* @throws UnsupportedOperationException if getting a RawChannel over
145
* this connection is not supported.
146
* @throws IOException if an I/O exception occurs while closing
147
* the channel.
148
*/
149
@Override
150
public synchronized void closeRawChannel() throws IOException {
151
if (rawChannelProvider == null) {
152
throw new UnsupportedOperationException(
153
"RawChannel is only supported for WebSocket creation");
154
}
155
rawChannelProvider.closeRawChannel();
156
}
157
158
@Override
159
public String toString() {
160
StringBuilder sb = new StringBuilder();
161
String method = request().method();
162
URI uri = request().uri();
163
String uristring = uri == null ? "" : uri.toString();
164
sb.append('(')
165
.append(method)
166
.append(" ")
167
.append(uristring)
168
.append(") ")
169
.append(statusCode());
170
return sb.toString();
171
}
172
173
/**
174
* An auxiliary class used for RawChannel creation when creating a WebSocket.
175
* This avoids keeping around references to connection/exchange in the
176
* regular HttpResponse case. Only those responses corresponding to an
177
* initial WebSocket request have a RawChannelProvider.
178
*/
179
private static final class RawChannelProvider implements RawChannel.Provider {
180
private final HttpConnection connection;
181
private final Exchange<?> exchange;
182
private RawChannel rawchan;
183
RawChannelProvider(HttpConnection conn, Exchange<?> exch) {
184
connection = conn;
185
exchange = exch;
186
}
187
188
static RawChannelProvider create(Response resp, Exchange<?> exch) {
189
if (resp.request().isWebSocket()) {
190
return new RawChannelProvider(connection(resp, exch), exch);
191
}
192
return null;
193
}
194
195
@Override
196
public synchronized RawChannel rawChannel() {
197
if (rawchan == null) {
198
ExchangeImpl<?> exchImpl = exchangeImpl();
199
if (!(exchImpl instanceof Http1Exchange)) {
200
// RawChannel is only used for WebSocket - and WebSocket
201
// is not supported over HTTP/2 yet, so we should not come
202
// here. Getting a RawChannel over HTTP/2 might be supported
203
// in the future, but it would entail retrieving any left over
204
// bytes that might have been read but not consumed by the
205
// HTTP/2 connection.
206
throw new UnsupportedOperationException("RawChannel is not supported over HTTP/2");
207
}
208
// Http1Exchange may have some remaining bytes in its
209
// internal buffer.
210
Supplier<ByteBuffer> initial = ((Http1Exchange<?>) exchImpl)::drainLeftOverBytes;
211
rawchan = new RawChannelTube(connection, initial);
212
}
213
return rawchan;
214
}
215
216
public synchronized void closeRawChannel() throws IOException {
217
// close the rawChannel, if created, or the
218
// connection, if not.
219
if (rawchan != null) rawchan.close();
220
else connection.close();
221
}
222
223
private static HttpConnection connection(Response resp, Exchange<?> exch) {
224
if (exch == null || exch.exchImpl == null) {
225
assert resp.statusCode == 407;
226
return null; // case of Proxy 407
227
}
228
return exch.exchImpl.connection();
229
}
230
231
private ExchangeImpl<?> exchangeImpl() {
232
return exchange != null ? exchange.exchImpl : null;
233
}
234
235
}
236
}
237
238