< prev index next >
src/java.httpclient/share/classes/java/net/http/Http2ClientImpl.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2015, 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 21,33 ****
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
*/
package java.net.http;
class Http2ClientImpl {
! Http2ClientImpl(HttpClientImpl t) {}
! String getSettingsString() {return "";}
! void debugPrint() {}
! Http2Connection getConnectionFor(HttpRequestImpl r) {
return null;
}
}
--- 21,164 ----
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
*/
package java.net.http;
+ import java.io.IOException;
+ import java.net.InetSocketAddress;
+ import java.net.URI;
+ import static java.net.http.SettingsFrame.INITIAL_WINDOW_SIZE;
+ import static java.net.http.SettingsFrame.ENABLE_PUSH;
+ import static java.net.http.SettingsFrame.HEADER_TABLE_SIZE;
+ import static java.net.http.SettingsFrame.MAX_CONCURRENT_STREAMS;
+ import static java.net.http.SettingsFrame.MAX_FRAME_SIZE;
+ import java.util.Base64;
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Map;
+ import java.util.Set;
+
+ /**
+ * Http2 specific aspects of HttpClientImpl
+ */
class Http2ClientImpl {
!
! HttpClientImpl client;
!
! Http2ClientImpl(HttpClientImpl client) {
! this.client = client;
! }
!
! /* Map key is "scheme:host:port" */
! final Map<String,Http2Connection> connections =
! Collections.synchronizedMap(new HashMap<>());
!
! final Set<String> opening = Collections.synchronizedSet(new HashSet<>());
!
! synchronized boolean haveConnectionFor(URI uri, InetSocketAddress proxy) {
! return connections.containsKey(Http2Connection.keyFor(uri,proxy));
! }
!
! /*
! * Only one connection per destination is created. Blocks when opening
! * connection, or when waiting for connection to be opened.
! * First thread opens the connection and notifies the others when done.
! *
! * If the request is secure (https) then we open the connection here.
! * If not, then the more complicated upgrade from 1.1 to 2 happens (not here)
! * In latter case, when the Http2Connection is connected, putConnection() must
! * be called to store it.
! */
! Http2Connection getConnectionFor(HttpRequestImpl req)
! throws IOException, InterruptedException
! {
! URI uri = req.uri();
! InetSocketAddress proxy = req.proxy();
! String key = Http2Connection.keyFor(uri, proxy);
! Http2Connection connection;
! boolean createHere; // true if this thread is going to open connection
! synchronized (opening) {
! connection = connections.get(key);
! if (connection != null) {
! return connection;
! }
!
! if (!req.secure()) {
return null;
}
+
+ if (!opening.contains(key)) {
+ opening.add(key);
+ createHere = true;
+ } else {
+ createHere = false;
+ opening.wait();
+ }
+ }
+ if (createHere) {
+ connection = new Http2Connection(req);
+ synchronized(opening) {
+ connections.put(key, connection);
+ opening.remove(key);
+ opening.notifyAll();
+ }
+ }
+ return connection;
+ }
+
+ /*
+ * TODO: If there isn't a connection to the same destination, then
+ * store it. If there is already a connection, then close it
+ */
+ synchronized void putConnection(Http2Connection c) {
+ String key = c.key();
+ connections.put(key, c);
+ }
+
+ synchronized void deleteConnection(Http2Connection c) {
+ String key = c.key();
+ connections.remove(key);
+ }
+
+ /** Returns the client settings as a base64 (url) encoded string */
+ String getSettingsString() {
+ SettingsFrame sf = getClientSettings();
+ ByteBufferGenerator bg = new ByteBufferGenerator(client);
+ sf.writeOutgoing(bg);
+ byte[] settings = bg.asByteArray(9); // without the header
+ Base64.Encoder encoder = Base64.getUrlEncoder()
+ .withoutPadding();
+ return encoder.encodeToString(settings);
+ }
+
+ private static final int K = 1024;
+
+ SettingsFrame getClientSettings() {
+ SettingsFrame frame = new SettingsFrame();
+ frame.setParameter(HEADER_TABLE_SIZE, Utils.getIntegerNetProperty(
+ "sun.net.httpclient.hpack.maxheadertablesize", 16 * K));
+ frame.setParameter(ENABLE_PUSH, Utils.getIntegerNetProperty(
+ "sun.net.httpclient.enablepush", 1));
+ frame.setParameter(MAX_CONCURRENT_STREAMS, Utils.getIntegerNetProperty(
+ "sun.net.httpclient.maxstreams", 16));
+ frame.setParameter(INITIAL_WINDOW_SIZE, Utils.getIntegerNetProperty(
+ "sun.net.httpclient.windowsize", 32 * K));
+ frame.setParameter(MAX_FRAME_SIZE, Utils.getIntegerNetProperty(
+ "sun.net.httpclient.maxframesize", 16 * K));
+ frame.setLength();
+ return frame;
+ }
+
+ // these default settings only used until first Settings frame received
+ // from server.
+
+ SettingsFrame getServerSettings() {
+ SettingsFrame frame = new SettingsFrame();
+ frame.setParameter(HEADER_TABLE_SIZE, 4 * K);
+ frame.setParameter(ENABLE_PUSH, 0);
+ frame.setParameter(MAX_CONCURRENT_STREAMS, 8);
+ frame.setParameter(INITIAL_WINDOW_SIZE, 64 * K - 1);
+ frame.setParameter(MAX_FRAME_SIZE, 8 * K);
+ return frame;
+ }
}
< prev index next >