8174745: Httpclient source update for JDK 8
Reviewed-by: dfuchs
This commit is contained in:
parent
62274dc8df
commit
f7c7a3c8b2
jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http
@ -609,11 +609,13 @@ class AsyncSSLDelegate implements ExceptionallyCloseable, AsyncConnection {
|
||||
}
|
||||
|
||||
// SSLParameters.getApplicationProtocols() can't return null
|
||||
// JDK 8 EXCL START
|
||||
for (String approto : p.getApplicationProtocols()) {
|
||||
sb.append("\n application protocol: {")
|
||||
.append(params.size()).append("}");
|
||||
params.add(approto);
|
||||
}
|
||||
// JDK 8 EXCL END
|
||||
|
||||
if (p.getProtocols() != null) {
|
||||
for (String protocol : p.getProtocols()) {
|
||||
|
@ -91,11 +91,13 @@ class DefaultPublisher<T> implements Flow.Publisher<T> {
|
||||
for (long i = 0; i < nbItemsDemanded && !done.get(); i++) {
|
||||
try {
|
||||
Optional<T> item = Objects.requireNonNull(supplier.get());
|
||||
item.ifPresentOrElse(subscriber::onNext, () -> {
|
||||
if (item.isPresent()) {
|
||||
subscriber.onNext(item.get());
|
||||
} else {
|
||||
if (done.compareAndSet(false, true)) {
|
||||
subscriber.onComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
if (done.compareAndSet(false, true)) {
|
||||
subscriber.onError(e);
|
||||
|
@ -30,6 +30,8 @@ import java.io.UncheckedIOException;
|
||||
import java.net.URI;
|
||||
import jdk.incubator.http.ResponseProcessors.MultiFile;
|
||||
import jdk.incubator.http.ResponseProcessors.MultiProcessorImpl;
|
||||
import static jdk.incubator.http.internal.common.Utils.unchecked;
|
||||
import static jdk.incubator.http.internal.common.Utils.charsetFrom;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -269,19 +271,6 @@ public abstract class HttpResponse<T> {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Charset from the Content-encoding header. Defaults to
|
||||
* UTF_8
|
||||
*/
|
||||
private static Charset charsetFrom(HttpHeaders headers) {
|
||||
String encoding = headers.firstValue("Content-encoding")
|
||||
.orElse("UTF_8");
|
||||
try {
|
||||
return Charset.forName(encoding);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return StandardCharsets.UTF_8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code BodyHandler<Path>} that returns a
|
||||
@ -342,10 +331,6 @@ public abstract class HttpResponse<T> {
|
||||
};
|
||||
}
|
||||
|
||||
private static UncheckedIOException unchecked(IOException e) {
|
||||
return new UncheckedIOException(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code BodyHandler<Path>} that returns a
|
||||
* {@link BodyProcessor BodyProcessor}{@code <Path>} obtained from
|
||||
@ -743,48 +728,5 @@ public abstract class HttpResponse<T> {
|
||||
return asMap(pushHandler, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code MultiProcessor} which writes the response bodies to
|
||||
* files under a given root directory and which returns an aggregate
|
||||
* response map that is a {@code Map<HttpRequest, HttpResponse<Path>>}.
|
||||
* The keyset of the {@code Map} represents the original request and any
|
||||
* additional requests generated by the server. The values are the
|
||||
* responses containing the paths of the destination files. Each file
|
||||
* uses the URI path of the request relative to the destination parent
|
||||
* directorycprovided.
|
||||
*
|
||||
* <p>
|
||||
* All incoming additional requests (push promises) are accepted by this
|
||||
* multi response processor. Errors are effectively ignored and any
|
||||
* failed responses are simply omitted from the result {@code Map}.
|
||||
* Other implementations of {@code MultiProcessor} may handle these
|
||||
* situations.
|
||||
*
|
||||
* <p>
|
||||
* <b>Example usage</b>
|
||||
* <pre>
|
||||
* {@code
|
||||
* HttpClient client = ..
|
||||
* HttpRequest request = HttpRequest
|
||||
* .create(new URI("https://www.foo.com/"))
|
||||
* .version(Version.HTTP2)
|
||||
* .GET();
|
||||
*
|
||||
* Map<HttpRequest, HttpResponse<Path>>> map = client
|
||||
* .sendAsync(HttpResponse.MultiProcessor.multiFile("/usr/destination"))
|
||||
* .join();
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
* TEMPORARILY REMOVING THIS FROM API. MIGHT NOT BE NEEDED.
|
||||
*
|
||||
* @param destination the destination parent directory of all response
|
||||
* bodies
|
||||
* @return a MultiProcessor
|
||||
*/
|
||||
private static MultiProcessor<MultiMapResult<Path>,Path> multiFile(Path destination) {
|
||||
MultiFile mf = new MultiFile(destination);
|
||||
return new MultiProcessorImpl<Path>(mf::handlePush, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ class ResponseProcessors {
|
||||
|
||||
@Override
|
||||
public void onError(HttpRequest request, Throwable t) {
|
||||
results.put(request, CompletableFuture.failedFuture(t));
|
||||
results.put(request, MinimalFuture.failedFuture(t));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -449,9 +449,11 @@ class SSLDelegate {
|
||||
for (String cipher : p.getCipherSuites()) {
|
||||
System.out.printf("cipher: %s\n", cipher);
|
||||
}
|
||||
// JDK 8 EXCL START
|
||||
for (String approto : p.getApplicationProtocols()) {
|
||||
System.out.printf("application protocol: %s\n", approto);
|
||||
}
|
||||
// JDK 8 EXCL END
|
||||
for (String protocol : p.getProtocols()) {
|
||||
System.out.printf("protocol: %s\n", protocol);
|
||||
}
|
||||
|
1
jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/MinimalFuture.java
1
jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/MinimalFuture.java
@ -110,7 +110,6 @@ public final class MinimalFuture<T> extends CompletableFuture<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> MinimalFuture<U> newIncompleteFuture() {
|
||||
return new MinimalFuture<>();
|
||||
}
|
||||
|
@ -118,11 +118,13 @@ public class Queue<T> implements ExceptionallyCloseable {
|
||||
public synchronized void closeExceptionally(Throwable t) {
|
||||
if (exception == null) exception = t;
|
||||
else if (t != null && t != exception) {
|
||||
Stream.of(exception.getSuppressed())
|
||||
if (!Stream.of(exception.getSuppressed())
|
||||
.filter(x -> x == t)
|
||||
.findFirst()
|
||||
.ifPresentOrElse((x) -> {},
|
||||
() -> exception.addSuppressed(t));
|
||||
.isPresent())
|
||||
{
|
||||
exception.addSuppressed(t);
|
||||
}
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
@ -32,12 +32,14 @@ import javax.net.ssl.SSLParameters;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.NetPermission;
|
||||
import java.net.URI;
|
||||
import java.net.URLPermission;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
@ -54,6 +56,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.function.Predicate;
|
||||
import jdk.incubator.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* Miscellaneous utilities
|
||||
@ -259,9 +262,11 @@ public final class Utils {
|
||||
SSLParameters p1 = new SSLParameters();
|
||||
p1.setAlgorithmConstraints(p.getAlgorithmConstraints());
|
||||
p1.setCipherSuites(p.getCipherSuites());
|
||||
// JDK 8 EXCL START
|
||||
p1.setEnableRetransmissions(p.getEnableRetransmissions());
|
||||
p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
|
||||
p1.setMaximumPacketSize(p.getMaximumPacketSize());
|
||||
// JDK 8 EXCL END
|
||||
p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
|
||||
p1.setNeedClientAuth(p.getNeedClientAuth());
|
||||
String[] protocols = p.getProtocols();
|
||||
if (protocols != null) {
|
||||
@ -475,4 +480,21 @@ public final class Utils {
|
||||
return newb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Charset from the Content-encoding header. Defaults to
|
||||
* UTF_8
|
||||
*/
|
||||
public static Charset charsetFrom(HttpHeaders headers) {
|
||||
String encoding = headers.firstValue("Content-encoding")
|
||||
.orElse("UTF_8");
|
||||
try {
|
||||
return Charset.forName(encoding);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return StandardCharsets.UTF_8;
|
||||
}
|
||||
}
|
||||
|
||||
public static UncheckedIOException unchecked(IOException e) {
|
||||
return new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
package jdk.incubator.http.internal.websocket;
|
||||
|
||||
import jdk.incubator.http.WebSocket.MessagePart;
|
||||
import jdk.incubator.http.internal.common.Log;
|
||||
import jdk.incubator.http.internal.websocket.Frame.Opcode;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -33,13 +34,11 @@ import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.lang.System.Logger.Level.TRACE;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static jdk.incubator.http.internal.common.Utils.dump;
|
||||
import static jdk.incubator.http.internal.websocket.StatusCodes.NO_STATUS_CODE;
|
||||
import static jdk.incubator.http.internal.websocket.StatusCodes.checkIncomingCode;
|
||||
import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
|
||||
|
||||
/*
|
||||
* Consumes frame parts and notifies a message consumer, when there is
|
||||
@ -71,17 +70,13 @@ class FrameConsumer implements Frame.Consumer {
|
||||
|
||||
@Override
|
||||
public void fin(boolean value) {
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
logger.log(TRACE, "Reading fin: {0}", value);
|
||||
}
|
||||
Log.logTrace("Reading fin: {0}", value);
|
||||
fin = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rsv1(boolean value) {
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
logger.log(TRACE, "Reading rsv1: {0}", value);
|
||||
}
|
||||
Log.logTrace("Reading rsv1: {0}", value);
|
||||
if (value) {
|
||||
throw new FailWebSocketException("Unexpected rsv1 bit");
|
||||
}
|
||||
@ -89,9 +84,7 @@ class FrameConsumer implements Frame.Consumer {
|
||||
|
||||
@Override
|
||||
public void rsv2(boolean value) {
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
logger.log(TRACE, "Reading rsv2: {0}", value);
|
||||
}
|
||||
Log.logTrace("Reading rsv2: {0}", value);
|
||||
if (value) {
|
||||
throw new FailWebSocketException("Unexpected rsv2 bit");
|
||||
}
|
||||
@ -99,9 +92,7 @@ class FrameConsumer implements Frame.Consumer {
|
||||
|
||||
@Override
|
||||
public void rsv3(boolean value) {
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
logger.log(TRACE, "Reading rsv3: {0}", value);
|
||||
}
|
||||
Log.logTrace("Reading rsv3: {0}", value);
|
||||
if (value) {
|
||||
throw new FailWebSocketException("Unexpected rsv3 bit");
|
||||
}
|
||||
@ -109,7 +100,7 @@ class FrameConsumer implements Frame.Consumer {
|
||||
|
||||
@Override
|
||||
public void opcode(Opcode v) {
|
||||
logger.log(TRACE, "Reading opcode: {0}", v);
|
||||
Log.logTrace("Reading opcode: {0}", v);
|
||||
if (v == Opcode.PING || v == Opcode.PONG || v == Opcode.CLOSE) {
|
||||
if (!fin) {
|
||||
throw new FailWebSocketException("Fragmented control frame " + v);
|
||||
@ -137,9 +128,7 @@ class FrameConsumer implements Frame.Consumer {
|
||||
|
||||
@Override
|
||||
public void mask(boolean value) {
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
logger.log(TRACE, "Reading mask: {0}", value);
|
||||
}
|
||||
Log.logTrace("Reading mask: {0}", value);
|
||||
if (value) {
|
||||
throw new FailWebSocketException("Masked frame received");
|
||||
}
|
||||
@ -147,10 +136,7 @@ class FrameConsumer implements Frame.Consumer {
|
||||
|
||||
@Override
|
||||
public void payloadLen(long value) {
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
// Checked for being loggable because of autoboxing of 'value'
|
||||
logger.log(TRACE, "Reading payloadLen: {0}", value);
|
||||
}
|
||||
Log.logTrace("Reading payloadLen: {0}", value);
|
||||
if (opcode.isControl()) {
|
||||
if (value > 125) {
|
||||
throw new FailWebSocketException(
|
||||
@ -178,9 +164,7 @@ class FrameConsumer implements Frame.Consumer {
|
||||
|
||||
@Override
|
||||
public void payloadData(ByteBuffer data) {
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
logger.log(TRACE, "Reading payloadData: data={0}", data);
|
||||
}
|
||||
Log.logTrace("Reading payloadData: data={0}", data);
|
||||
unconsumedPayloadLen -= data.remaining();
|
||||
boolean isLast = unconsumedPayloadLen == 0;
|
||||
if (opcode.isControl()) {
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package jdk.incubator.http.internal.websocket;
|
||||
|
||||
import jdk.incubator.http.internal.common.Log;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
@ -32,10 +34,8 @@ import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static jdk.incubator.http.internal.common.Utils.EMPTY_BYTEBUFFER;
|
||||
import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
|
||||
|
||||
final class UTF8AccumulatingDecoder {
|
||||
|
||||
@ -74,9 +74,8 @@ final class UTF8AccumulatingDecoder {
|
||||
// Since it's UTF-8, the assumption is leftovers.remaining() < 4
|
||||
// (i.e. small). Otherwise a shared buffer should be used
|
||||
if (!(leftovers.remaining() < 4)) {
|
||||
logger.log(WARNING,
|
||||
"The size of decoding leftovers is greater than expected: {0}",
|
||||
leftovers.remaining());
|
||||
Log.logError("The size of decoding leftovers is greater than expected: {0}",
|
||||
leftovers.remaining());
|
||||
}
|
||||
b.position(b.limit()); // As if we always read to the end
|
||||
// Decoder promises that in the case of endOfInput == true:
|
||||
|
@ -26,6 +26,7 @@
|
||||
package jdk.incubator.http.internal.websocket;
|
||||
|
||||
import jdk.incubator.http.WebSocket;
|
||||
import jdk.incubator.http.internal.common.Log;
|
||||
import jdk.incubator.http.internal.common.Pair;
|
||||
import jdk.incubator.http.internal.websocket.OpeningHandshake.Result;
|
||||
import jdk.incubator.http.internal.websocket.OutgoingMessage.Binary;
|
||||
@ -47,8 +48,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
import static java.lang.System.Logger.Level.TRACE;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.concurrent.CompletableFuture.failedFuture;
|
||||
import static jdk.incubator.http.internal.common.Pair.pair;
|
||||
@ -61,8 +60,6 @@ import static jdk.incubator.http.internal.websocket.StatusCodes.checkOutgoingCod
|
||||
*/
|
||||
final class WebSocketImpl implements WebSocket {
|
||||
|
||||
static final System.Logger logger = System.getLogger("jdk.httpclient.WebSocket");
|
||||
|
||||
private final URI uri;
|
||||
private final String subprotocol;
|
||||
private final RawChannel channel;
|
||||
@ -142,7 +139,7 @@ final class WebSocketImpl implements WebSocket {
|
||||
try {
|
||||
channel.close();
|
||||
} catch (IOException e) {
|
||||
logger.log(ERROR, e);
|
||||
Log.logError(e);
|
||||
} finally {
|
||||
closed.set(true);
|
||||
}
|
||||
@ -168,14 +165,14 @@ final class WebSocketImpl implements WebSocket {
|
||||
private void signalError(Throwable error) {
|
||||
synchronized (lock) {
|
||||
if (lastMethodInvoked) {
|
||||
logger.log(ERROR, error);
|
||||
Log.logError(error);
|
||||
} else {
|
||||
lastMethodInvoked = true;
|
||||
receiver.close();
|
||||
try {
|
||||
listener.onError(this, error);
|
||||
} catch (Exception e) {
|
||||
logger.log(ERROR, e);
|
||||
Log.logError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,7 +187,7 @@ final class WebSocketImpl implements WebSocket {
|
||||
try {
|
||||
channel.shutdownInput();
|
||||
} catch (IOException e) {
|
||||
logger.log(ERROR, e);
|
||||
Log.logError(e);
|
||||
}
|
||||
boolean wasComplete = !closeReceived.complete(null);
|
||||
if (wasComplete) {
|
||||
@ -210,7 +207,7 @@ final class WebSocketImpl implements WebSocket {
|
||||
enqueueClose(new Close(code, ""))
|
||||
.whenComplete((r1, error1) -> {
|
||||
if (error1 != null) {
|
||||
logger.log(ERROR, error1);
|
||||
Log.logError(error1);
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -223,14 +220,14 @@ final class WebSocketImpl implements WebSocket {
|
||||
private CompletionStage<?> signalClose(int statusCode, String reason) {
|
||||
synchronized (lock) {
|
||||
if (lastMethodInvoked) {
|
||||
logger.log(TRACE, "Close: {0}, ''{1}''", statusCode, reason);
|
||||
Log.logTrace("Close: {0}, ''{1}''", statusCode, reason);
|
||||
} else {
|
||||
lastMethodInvoked = true;
|
||||
receiver.close();
|
||||
try {
|
||||
return listener.onClose(this, statusCode, reason);
|
||||
} catch (Exception e) {
|
||||
logger.log(ERROR, e);
|
||||
Log.logError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -289,7 +286,7 @@ final class WebSocketImpl implements WebSocket {
|
||||
try {
|
||||
channel.shutdownOutput();
|
||||
} catch (IOException e) {
|
||||
logger.log(ERROR, e);
|
||||
Log.logError(e);
|
||||
}
|
||||
boolean wasComplete = !closeSent.complete(null);
|
||||
if (wasComplete) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user