1
0
mirror of https://github.com/square/okhttp.git synced 2025-11-27 18:21:14 +03:00

Rename FramedConnection to Http2Connection.

Also rename HttpStream to HttpCodec. This is the interface implemented
for both HTTP/1.1 and HTTP/2. The HTTP/2 codec creates a stream when
it is used.
This commit is contained in:
jwilson
2016-07-09 18:08:02 -04:00
parent 33660bf58b
commit 3d43a8dba8
49 changed files with 708 additions and 753 deletions

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -38,14 +38,14 @@ import okio.Source;
import static okhttp3.internal.platform.Platform.INFO; import static okhttp3.internal.platform.Platform.INFO;
/** A basic HTTP_2 server that serves the contents of a local directory. */ /** A basic HTTP/2 server that serves the contents of a local directory. */
public final class FramedServer extends FramedConnection.Listener { public final class Http2Server extends Http2Connection.Listener {
static final Logger logger = Logger.getLogger(FramedServer.class.getName()); static final Logger logger = Logger.getLogger(Http2Server.class.getName());
private final File baseDirectory; private final File baseDirectory;
private final SSLSocketFactory sslSocketFactory; private final SSLSocketFactory sslSocketFactory;
public FramedServer(File baseDirectory, SSLSocketFactory sslSocketFactory) { public Http2Server(File baseDirectory, SSLSocketFactory sslSocketFactory) {
this.baseDirectory = baseDirectory; this.baseDirectory = baseDirectory;
this.sslSocketFactory = sslSocketFactory; this.sslSocketFactory = sslSocketFactory;
} }
@@ -65,11 +65,11 @@ public final class FramedServer extends FramedConnection.Listener {
if (protocol != Protocol.HTTP_2) { if (protocol != Protocol.HTTP_2) {
throw new ProtocolException("Protocol " + protocol + " unsupported"); throw new ProtocolException("Protocol " + protocol + " unsupported");
} }
FramedConnection framedConnection = new FramedConnection.Builder(false) Http2Connection connection = new Http2Connection.Builder(false)
.socket(sslSocket) .socket(sslSocket)
.listener(this) .listener(this)
.build(); .build();
framedConnection.start(); connection.start();
} catch (IOException e) { } catch (IOException e) {
logger.log(Level.INFO, "FramedServer connection failure: " + e); logger.log(Level.INFO, "FramedServer connection failure: " + e);
Util.closeQuietly(socket); Util.closeQuietly(socket);
@@ -90,7 +90,7 @@ public final class FramedServer extends FramedConnection.Listener {
return sslSocket; return sslSocket;
} }
@Override public void onStream(final FramedStream stream) throws IOException { @Override public void onStream(final Http2Stream stream) throws IOException {
try { try {
List<Header> requestHeaders = stream.getRequestHeaders(); List<Header> requestHeaders = stream.getRequestHeaders();
String path = null; String path = null;
@@ -120,7 +120,7 @@ public final class FramedServer extends FramedConnection.Listener {
} }
} }
private void send404(FramedStream stream, String path) throws IOException { private void send404(Http2Stream stream, String path) throws IOException {
List<Header> responseHeaders = Arrays.asList( List<Header> responseHeaders = Arrays.asList(
new Header(":status", "404"), new Header(":status", "404"),
new Header(":version", "HTTP/1.1"), new Header(":version", "HTTP/1.1"),
@@ -132,7 +132,7 @@ public final class FramedServer extends FramedConnection.Listener {
out.close(); out.close();
} }
private void serveDirectory(FramedStream stream, File[] files) throws IOException { private void serveDirectory(Http2Stream stream, File[] files) throws IOException {
List<Header> responseHeaders = Arrays.asList( List<Header> responseHeaders = Arrays.asList(
new Header(":status", "200"), new Header(":status", "200"),
new Header(":version", "HTTP/1.1"), new Header(":version", "HTTP/1.1"),
@@ -147,7 +147,7 @@ public final class FramedServer extends FramedConnection.Listener {
out.close(); out.close();
} }
private void serveFile(FramedStream stream, File file) throws IOException { private void serveFile(Http2Stream stream, File file) throws IOException {
List<Header> responseHeaders = Arrays.asList( List<Header> responseHeaders = Arrays.asList(
new Header(":status", "200"), new Header(":status", "200"),
new Header(":version", "HTTP/1.1"), new Header(":version", "HTTP/1.1"),
@@ -181,7 +181,7 @@ public final class FramedServer extends FramedConnection.Listener {
return; return;
} }
FramedServer server = new FramedServer(new File(args[0]), Http2Server server = new Http2Server(new File(args[0]),
SslClient.localhost().sslContext.getSocketFactory()); SslClient.localhost().sslContext.getSocketFactory());
server.run(); server.run();
} }

View File

@@ -20,7 +20,7 @@ import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import okhttp3.Headers; import okhttp3.Headers;
import okhttp3.internal.Internal; import okhttp3.internal.Internal;
import okhttp3.internal.framed.Settings; import okhttp3.internal.http2.Settings;
import okhttp3.ws.WebSocketListener; import okhttp3.ws.WebSocketListener;
import okio.Buffer; import okio.Buffer;

View File

@@ -61,12 +61,12 @@ import okhttp3.Response;
import okhttp3.internal.Internal; import okhttp3.internal.Internal;
import okhttp3.internal.NamedRunnable; import okhttp3.internal.NamedRunnable;
import okhttp3.internal.Util; import okhttp3.internal.Util;
import okhttp3.internal.framed.ErrorCode;
import okhttp3.internal.framed.FramedConnection;
import okhttp3.internal.framed.FramedStream;
import okhttp3.internal.framed.Header;
import okhttp3.internal.framed.Settings;
import okhttp3.internal.http.HttpMethod; import okhttp3.internal.http.HttpMethod;
import okhttp3.internal.http2.ErrorCode;
import okhttp3.internal.http2.Header;
import okhttp3.internal.http2.Http2Connection;
import okhttp3.internal.http2.Http2Stream;
import okhttp3.internal.http2.Settings;
import okhttp3.internal.platform.Platform; import okhttp3.internal.platform.Platform;
import okhttp3.internal.ws.RealWebSocket; import okhttp3.internal.ws.RealWebSocket;
import okhttp3.internal.ws.WebSocketProtocol; import okhttp3.internal.ws.WebSocketProtocol;
@@ -125,8 +125,8 @@ public final class MockWebServer implements TestRule {
private final Set<Socket> openClientSockets = private final Set<Socket> openClientSockets =
Collections.newSetFromMap(new ConcurrentHashMap<Socket, Boolean>()); Collections.newSetFromMap(new ConcurrentHashMap<Socket, Boolean>());
private final Set<FramedConnection> openFramedConnections = private final Set<Http2Connection> openConnections =
Collections.newSetFromMap(new ConcurrentHashMap<FramedConnection, Boolean>()); Collections.newSetFromMap(new ConcurrentHashMap<Http2Connection, Boolean>());
private final AtomicInteger requestCount = new AtomicInteger(); private final AtomicInteger requestCount = new AtomicInteger();
private long bodyLimit = Long.MAX_VALUE; private long bodyLimit = Long.MAX_VALUE;
private ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault(); private ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault();
@@ -352,7 +352,7 @@ public final class MockWebServer implements TestRule {
Util.closeQuietly(s.next()); Util.closeQuietly(s.next());
s.remove(); s.remove();
} }
for (Iterator<FramedConnection> s = openFramedConnections.iterator(); s.hasNext(); ) { for (Iterator<Http2Connection> s = openConnections.iterator(); s.hasNext(); ) {
Util.closeQuietly(s.next()); Util.closeQuietly(s.next());
s.remove(); s.remove();
} }
@@ -451,12 +451,12 @@ public final class MockWebServer implements TestRule {
if (protocol == Protocol.HTTP_2) { if (protocol == Protocol.HTTP_2) {
FramedSocketHandler framedSocketListener = new FramedSocketHandler(socket, protocol); FramedSocketHandler framedSocketListener = new FramedSocketHandler(socket, protocol);
FramedConnection framedConnection = new FramedConnection.Builder(false) Http2Connection connection = new Http2Connection.Builder(false)
.socket(socket) .socket(socket)
.listener(framedSocketListener) .listener(framedSocketListener)
.build(); .build();
framedConnection.start(); connection.start();
openFramedConnections.add(framedConnection); openConnections.add(connection);
openClientSockets.remove(socket); openClientSockets.remove(socket);
return; return;
} else if (protocol != Protocol.HTTP_1_1) { } else if (protocol != Protocol.HTTP_1_1) {
@@ -842,7 +842,7 @@ public final class MockWebServer implements TestRule {
} }
/** Processes HTTP requests layered over framed protocols. */ /** Processes HTTP requests layered over framed protocols. */
private class FramedSocketHandler extends FramedConnection.Listener { private class FramedSocketHandler extends Http2Connection.Listener {
private final Socket socket; private final Socket socket;
private final Protocol protocol; private final Protocol protocol;
private final AtomicInteger sequenceNumber = new AtomicInteger(); private final AtomicInteger sequenceNumber = new AtomicInteger();
@@ -852,7 +852,7 @@ public final class MockWebServer implements TestRule {
this.protocol = protocol; this.protocol = protocol;
} }
@Override public void onStream(FramedStream stream) throws IOException { @Override public void onStream(Http2Stream stream) throws IOException {
MockResponse peekedResponse = dispatcher.peek(); MockResponse peekedResponse = dispatcher.peek();
if (peekedResponse.getSocketPolicy() == RESET_STREAM_AT_START) { if (peekedResponse.getSocketPolicy() == RESET_STREAM_AT_START) {
try { try {
@@ -880,7 +880,7 @@ public final class MockWebServer implements TestRule {
} }
} }
private RecordedRequest readRequest(FramedStream stream) throws IOException { private RecordedRequest readRequest(Http2Stream stream) throws IOException {
List<Header> streamHeaders = stream.getRequestHeaders(); List<Header> streamHeaders = stream.getRequestHeaders();
Headers.Builder httpHeaders = new Headers.Builder(); Headers.Builder httpHeaders = new Headers.Builder();
String method = "<:method omitted>"; String method = "<:method omitted>";
@@ -909,7 +909,7 @@ public final class MockWebServer implements TestRule {
sequenceNumber.getAndIncrement(), socket); sequenceNumber.getAndIncrement(), socket);
} }
private void writeResponse(FramedStream stream, MockResponse response) throws IOException { private void writeResponse(Http2Stream stream, MockResponse response) throws IOException {
Settings settings = response.getSettings(); Settings settings = response.getSettings();
if (settings != null) { if (settings != null) {
stream.getConnection().setSettings(settings); stream.getConnection().setSettings(settings);
@@ -944,7 +944,7 @@ public final class MockWebServer implements TestRule {
} }
} }
private void pushPromises(FramedStream stream, List<PushPromise> promises) throws IOException { private void pushPromises(Http2Stream stream, List<PushPromise> promises) throws IOException {
for (PushPromise pushPromise : promises) { for (PushPromise pushPromise : promises) {
List<Header> pushedHeaders = new ArrayList<>(); List<Header> pushedHeaders = new ArrayList<>();
pushedHeaders.add(new Header(Header.TARGET_AUTHORITY, url(pushPromise.path()).host())); pushedHeaders.add(new Header(Header.TARGET_AUTHORITY, url(pushPromise.path()).host()));
@@ -959,7 +959,7 @@ public final class MockWebServer implements TestRule {
requestQueue.add(new RecordedRequest(requestLine, pushPromise.headers(), chunkSizes, 0, requestQueue.add(new RecordedRequest(requestLine, pushPromise.headers(), chunkSizes, 0,
new Buffer(), sequenceNumber.getAndIncrement(), socket)); new Buffer(), sequenceNumber.getAndIncrement(), socket));
boolean hasBody = pushPromise.response().getBody() != null; boolean hasBody = pushPromise.response().getBody() != null;
FramedStream pushedStream = Http2Stream pushedStream =
stream.getConnection().pushStream(stream.getId(), pushedHeaders, hasBody); stream.getConnection().pushStream(stream.getId(), pushedHeaders, hasBody);
writeResponse(pushedStream, pushPromise.response()); writeResponse(pushedStream, pushPromise.response());
} }

View File

@@ -45,8 +45,8 @@ import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.internal.Util; import okhttp3.internal.Util;
import okhttp3.internal.framed.Http2;
import okhttp3.internal.http.StatusLine; import okhttp3.internal.http.StatusLine;
import okhttp3.internal.http2.Http2;
import okio.BufferedSource; import okio.BufferedSource;
import okio.Okio; import okio.Okio;
import okio.Sink; import okio.Sink;
@@ -274,7 +274,7 @@ public class Main extends HelpOption implements Runnable {
} }
private static void enableHttp2FrameLogging() { private static void enableHttp2FrameLogging() {
frameLogger = Logger.getLogger(Http2.class.getName() + "$FrameLogger"); frameLogger = Logger.getLogger(Http2.class.getName());
frameLogger.setLevel(Level.FINE); frameLogger.setLevel(Level.FINE);
ConsoleHandler handler = new ConsoleHandler(); ConsoleHandler handler = new ConsoleHandler();
handler.setLevel(Level.FINE); handler.setLevel(Level.FINE);

View File

@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.util.Collection; import java.util.Collection;
import okhttp3.internal.framed.hpackjson.Story; import okhttp3.internal.http2.hpackjson.Story;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import static okhttp3.internal.framed.hpackjson.HpackJsonUtil.storiesForCurrentDraft; import static okhttp3.internal.http2.hpackjson.HpackJsonUtil.storiesForCurrentDraft;
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class HpackDecodeInteropTest extends HpackDecodeTestBase { public class HpackDecodeInteropTest extends HpackDecodeTestBase {

View File

@@ -13,15 +13,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import okhttp3.internal.framed.hpackjson.Case; import okhttp3.internal.framed.Header;
import okhttp3.internal.framed.hpackjson.HpackJsonUtil; import okhttp3.internal.framed.Hpack;
import okhttp3.internal.framed.hpackjson.Story; import okhttp3.internal.http2.hpackjson.Case;
import okhttp3.internal.http2.hpackjson.HpackJsonUtil;
import okhttp3.internal.http2.hpackjson.Story;
import okio.Buffer; import okio.Buffer;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;

View File

@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.util.Collection; import java.util.Collection;
import okhttp3.internal.framed.hpackjson.Case; import okhttp3.internal.framed.Hpack;
import okhttp3.internal.framed.hpackjson.Story; import okhttp3.internal.http2.hpackjson.Case;
import okhttp3.internal.http2.hpackjson.Story;
import okio.Buffer; import okio.Buffer;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed.hpackjson; package okhttp3.internal.http2.hpackjson;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed.hpackjson; package okhttp3.internal.http2.hpackjson;
import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi; import com.squareup.moshi.Moshi;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed.hpackjson; package okhttp3.internal.http2.hpackjson;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -18,9 +18,7 @@ package okhttp3;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.internal.tls.SslClient; import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.MockWebServer;

View File

@@ -22,8 +22,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import okhttp3.internal.Internal; import okhttp3.internal.Internal;
import okhttp3.internal.framed.Header; import okhttp3.internal.http2.Header;
import okhttp3.internal.http.Http2xStream; import okhttp3.internal.http2.Http2Codec;
import org.junit.Test; import org.junit.Test;
import static okhttp3.TestUtil.headerEntries; import static okhttp3.TestUtil.headerEntries;
@@ -43,7 +43,7 @@ public final class HeadersTest {
":version", "HTTP/1.1", ":version", "HTTP/1.1",
"connection", "close"); "connection", "close");
Request request = new Request.Builder().url("http://square.com/").build(); Request request = new Request.Builder().url("http://square.com/").build();
Response response = Http2xStream.readHttp2HeadersList(headerBlock).request(request).build(); Response response = Http2Codec.readHttp2HeadersList(headerBlock).request(request).build();
Headers headers = response.headers(); Headers headers = response.headers();
assertEquals(1, headers.size()); assertEquals(1, headers.size());
assertEquals(":version", headers.name(0)); assertEquals(":version", headers.name(0));
@@ -61,7 +61,7 @@ public final class HeadersTest {
":path", "/", ":path", "/",
":authority", "square.com", ":authority", "square.com",
":scheme", "http"); ":scheme", "http");
assertEquals(expected, Http2xStream.http2HeadersList(request)); assertEquals(expected, Http2Codec.http2HeadersList(request));
} }
@Test public void ofTrims() { @Test public void ofTrims() {

View File

@@ -4,7 +4,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import okhttp3.internal.SingleInetAddressDns; import okhttp3.internal.SingleInetAddressDns;
import okhttp3.internal.framed.Header; import okhttp3.internal.http2.Header;
public final class TestUtil { public final class TestUtil {
private TestUtil() { private TestUtil() {

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@@ -22,7 +22,7 @@ import okio.ByteString;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
class BaseTestHandler implements FrameReader.Handler { class BaseTestHandler implements Http2Reader.Handler {
@Override public void data(boolean inFinished, int streamId, BufferedSource source, int length) @Override public void data(boolean inFinished, int streamId, BufferedSource source, int length)
throws IOException { throws IOException {
fail(); fail();

View File

@@ -13,77 +13,75 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.junit.Test; import org.junit.Test;
import static okhttp3.internal.framed.Http2.FLAG_ACK; import static okhttp3.internal.http2.Http2.FLAG_ACK;
import static okhttp3.internal.framed.Http2.FLAG_END_HEADERS; import static okhttp3.internal.http2.Http2.FLAG_END_HEADERS;
import static okhttp3.internal.framed.Http2.FLAG_END_STREAM; import static okhttp3.internal.http2.Http2.FLAG_END_STREAM;
import static okhttp3.internal.framed.Http2.FLAG_NONE; import static okhttp3.internal.http2.Http2.FLAG_NONE;
import static okhttp3.internal.framed.FrameLogger.formatFlags; import static okhttp3.internal.http2.Http2.TYPE_CONTINUATION;
import static okhttp3.internal.framed.FrameLogger.formatHeader; import static okhttp3.internal.http2.Http2.TYPE_DATA;
import static okhttp3.internal.framed.Http2.TYPE_CONTINUATION; import static okhttp3.internal.http2.Http2.TYPE_GOAWAY;
import static okhttp3.internal.framed.Http2.TYPE_DATA; import static okhttp3.internal.http2.Http2.TYPE_HEADERS;
import static okhttp3.internal.framed.Http2.TYPE_GOAWAY; import static okhttp3.internal.http2.Http2.TYPE_PING;
import static okhttp3.internal.framed.Http2.TYPE_HEADERS; import static okhttp3.internal.http2.Http2.TYPE_PUSH_PROMISE;
import static okhttp3.internal.framed.Http2.TYPE_PING; import static okhttp3.internal.http2.Http2.TYPE_SETTINGS;
import static okhttp3.internal.framed.Http2.TYPE_PUSH_PROMISE; import static okhttp3.internal.http2.Http2.frameLog;
import static okhttp3.internal.framed.Http2.TYPE_SETTINGS;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public final class Http2FrameLoggerTest { public final class FrameLogTest {
/** Real stream traffic applied to the log format. */ /** Real stream traffic applied to the log format. */
@Test public void exampleStream() { @Test public void exampleStream() {
assertEquals(">> 0x00000000 5 SETTINGS ", assertEquals(">> 0x00000000 5 SETTINGS ",
formatHeader(false, 0, 5, TYPE_SETTINGS, FLAG_NONE)); frameLog(false, 0, 5, TYPE_SETTINGS, FLAG_NONE));
assertEquals(">> 0x00000003 100 HEADERS END_HEADERS", assertEquals(">> 0x00000003 100 HEADERS END_HEADERS",
formatHeader(false, 3, 100, TYPE_HEADERS, FLAG_END_HEADERS)); frameLog(false, 3, 100, TYPE_HEADERS, FLAG_END_HEADERS));
assertEquals(">> 0x00000003 0 DATA END_STREAM", assertEquals(">> 0x00000003 0 DATA END_STREAM",
formatHeader(false, 3, 0, TYPE_DATA, FLAG_END_STREAM)); frameLog(false, 3, 0, TYPE_DATA, FLAG_END_STREAM));
assertEquals("<< 0x00000000 15 SETTINGS ", assertEquals("<< 0x00000000 15 SETTINGS ",
formatHeader(true, 0, 15, TYPE_SETTINGS, FLAG_NONE)); frameLog(true, 0, 15, TYPE_SETTINGS, FLAG_NONE));
assertEquals(">> 0x00000000 0 SETTINGS ACK", assertEquals(">> 0x00000000 0 SETTINGS ACK",
formatHeader(false, 0, 0, TYPE_SETTINGS, FLAG_ACK)); frameLog(false, 0, 0, TYPE_SETTINGS, FLAG_ACK));
assertEquals("<< 0x00000000 0 SETTINGS ACK", assertEquals("<< 0x00000000 0 SETTINGS ACK",
formatHeader(true, 0, 0, TYPE_SETTINGS, FLAG_ACK)); frameLog(true, 0, 0, TYPE_SETTINGS, FLAG_ACK));
assertEquals("<< 0x00000003 22 HEADERS END_HEADERS", assertEquals("<< 0x00000003 22 HEADERS END_HEADERS",
formatHeader(true, 3, 22, TYPE_HEADERS, FLAG_END_HEADERS)); frameLog(true, 3, 22, TYPE_HEADERS, FLAG_END_HEADERS));
assertEquals("<< 0x00000003 226 DATA END_STREAM", assertEquals("<< 0x00000003 226 DATA END_STREAM",
formatHeader(true, 3, 226, TYPE_DATA, FLAG_END_STREAM)); frameLog(true, 3, 226, TYPE_DATA, FLAG_END_STREAM));
assertEquals(">> 0x00000000 8 GOAWAY ", assertEquals(">> 0x00000000 8 GOAWAY ",
formatHeader(false, 0, 8, TYPE_GOAWAY, FLAG_NONE)); frameLog(false, 0, 8, TYPE_GOAWAY, FLAG_NONE));
} }
@Test public void flagOverlapOn0x1() { @Test public void flagOverlapOn0x1() {
assertEquals("<< 0x00000000 0 SETTINGS ACK", assertEquals("<< 0x00000000 0 SETTINGS ACK",
formatHeader(true, 0, 0, TYPE_SETTINGS, (byte) 0x1)); frameLog(true, 0, 0, TYPE_SETTINGS, (byte) 0x1));
assertEquals("<< 0x00000000 8 PING ACK", assertEquals("<< 0x00000000 8 PING ACK",
formatHeader(true, 0, 8, TYPE_PING, (byte) 0x1)); frameLog(true, 0, 8, TYPE_PING, (byte) 0x1));
assertEquals("<< 0x00000003 0 HEADERS END_STREAM", assertEquals("<< 0x00000003 0 HEADERS END_STREAM",
formatHeader(true, 3, 0, TYPE_HEADERS, (byte) 0x1)); frameLog(true, 3, 0, TYPE_HEADERS, (byte) 0x1));
assertEquals("<< 0x00000003 0 DATA END_STREAM", assertEquals("<< 0x00000003 0 DATA END_STREAM",
formatHeader(true, 3, 0, TYPE_DATA, (byte) 0x1)); frameLog(true, 3, 0, TYPE_DATA, (byte) 0x1));
} }
@Test public void flagOverlapOn0x4() { @Test public void flagOverlapOn0x4() {
assertEquals("<< 0x00000003 10000 HEADERS END_HEADERS", assertEquals("<< 0x00000003 10000 HEADERS END_HEADERS",
formatHeader(true, 3, 10000, TYPE_HEADERS, (byte) 0x4)); frameLog(true, 3, 10000, TYPE_HEADERS, (byte) 0x4));
assertEquals("<< 0x00000003 10000 CONTINUATION END_HEADERS", assertEquals("<< 0x00000003 10000 CONTINUATION END_HEADERS",
formatHeader(true, 3, 10000, TYPE_CONTINUATION, (byte) 0x4)); frameLog(true, 3, 10000, TYPE_CONTINUATION, (byte) 0x4));
assertEquals("<< 0x00000004 10000 PUSH_PROMISE END_PUSH_PROMISE", assertEquals("<< 0x00000004 10000 PUSH_PROMISE END_PUSH_PROMISE",
formatHeader(true, 4, 10000, TYPE_PUSH_PROMISE, (byte) 0x4)); frameLog(true, 4, 10000, TYPE_PUSH_PROMISE, (byte) 0x4));
} }
@Test public void flagOverlapOn0x20() { @Test public void flagOverlapOn0x20() {
assertEquals("<< 0x00000003 10000 HEADERS PRIORITY", assertEquals("<< 0x00000003 10000 HEADERS PRIORITY",
formatHeader(true, 3, 10000, TYPE_HEADERS, (byte) 0x20)); frameLog(true, 3, 10000, TYPE_HEADERS, (byte) 0x20));
assertEquals("<< 0x00000003 10000 DATA COMPRESSED", assertEquals("<< 0x00000003 10000 DATA COMPRESSED",
formatHeader(true, 3, 10000, TYPE_DATA, (byte) 0x20)); frameLog(true, 3, 10000, TYPE_DATA, (byte) 0x20));
} }
/** /**
@@ -92,7 +90,7 @@ public final class Http2FrameLoggerTest {
*/ */
@Test public void allFormattedFlagsWithValidBits() { @Test public void allFormattedFlagsWithValidBits() {
List<String> formattedFlags = new ArrayList<>(0x40); // Highest valid flag is 0x20. List<String> formattedFlags = new ArrayList<>(0x40); // Highest valid flag is 0x20.
for (byte i = 0; i < 0x40; i++) formattedFlags.add(formatFlags(TYPE_HEADERS, i)); for (byte i = 0; i < 0x40; i++) formattedFlags.add(Http2.formatFlags(TYPE_HEADERS, i));
assertEquals(Arrays.asList( assertEquals(Arrays.asList(
"", "",

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
@@ -29,20 +29,20 @@ import okio.Okio;
import org.junit.Test; import org.junit.Test;
import static okhttp3.TestUtil.headerEntries; import static okhttp3.TestUtil.headerEntries;
import static okhttp3.internal.framed.Http2.FLAG_COMPRESSED; import static okhttp3.internal.http2.Http2.FLAG_COMPRESSED;
import static okhttp3.internal.framed.Http2.FLAG_END_HEADERS; import static okhttp3.internal.http2.Http2.FLAG_END_HEADERS;
import static okhttp3.internal.framed.Http2.FLAG_END_STREAM; import static okhttp3.internal.http2.Http2.FLAG_END_STREAM;
import static okhttp3.internal.framed.Http2.FLAG_NONE; import static okhttp3.internal.http2.Http2.FLAG_NONE;
import static okhttp3.internal.framed.Http2.FLAG_PADDED; import static okhttp3.internal.http2.Http2.FLAG_PADDED;
import static okhttp3.internal.framed.Http2.FLAG_PRIORITY; import static okhttp3.internal.http2.Http2.FLAG_PRIORITY;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
public class Http2Test { public final class Http2Test {
final Buffer frame = new Buffer(); final Buffer frame = new Buffer();
final FrameReader fr = new FrameReader(frame, false); final Http2Reader reader = new Http2Reader(frame, false);
final int expectedStreamId = 15; final int expectedStreamId = 15;
@Test public void unknownFrameTypeSkipped() throws IOException { @Test public void unknownFrameTypeSkipped() throws IOException {
@@ -52,7 +52,7 @@ public class Http2Test {
frame.writeInt(expectedStreamId); frame.writeInt(expectedStreamId);
frame.writeInt(111111111); // custom data frame.writeInt(111111111); // custom data
fr.nextFrame(new BaseTestHandler()); // Should not callback. reader.nextFrame(new BaseTestHandler()); // Should not callback.
} }
@Test public void onlyOneLiteralHeadersFrame() throws IOException { @Test public void onlyOneLiteralHeadersFrame() throws IOException {
@@ -67,7 +67,7 @@ public class Http2Test {
assertEquals(frame, sendHeaderFrames(true, sentHeaders)); // Check writer sends the same bytes. assertEquals(frame, sendHeaderFrames(true, sentHeaders)); // Check writer sends the same bytes.
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void headers(boolean inFinished, int streamId, @Override public void headers(boolean inFinished, int streamId,
int associatedStreamId, List<Header> headerBlock) { int associatedStreamId, List<Header> headerBlock) {
assertTrue(inFinished); assertTrue(inFinished);
@@ -90,7 +90,7 @@ public class Http2Test {
frame.writeByte(255); // Heaviest weight, zero-indexed. frame.writeByte(255); // Heaviest weight, zero-indexed.
frame.writeAll(headerBytes); frame.writeAll(headerBytes);
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void priority(int streamId, int streamDependency, int weight, @Override public void priority(int streamId, int streamDependency, int weight,
boolean exclusive) { boolean exclusive) {
assertEquals(0, streamDependency); assertEquals(0, streamDependency);
@@ -131,7 +131,7 @@ public class Http2Test {
assertEquals(frame, sendHeaderFrames(false, sentHeaders)); // Check writer sends the same bytes. assertEquals(frame, sendHeaderFrames(false, sentHeaders)); // Check writer sends the same bytes.
// Reading the above frames should result in a concatenated headerBlock. // Reading the above frames should result in a concatenated headerBlock.
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void headers(boolean inFinished, int streamId, @Override public void headers(boolean inFinished, int streamId,
int associatedStreamId, List<Header> headerBlock) { int associatedStreamId, List<Header> headerBlock) {
assertFalse(inFinished); assertFalse(inFinished);
@@ -163,7 +163,7 @@ public class Http2Test {
assertEquals(frame, sendPushPromiseFrames(expectedPromisedStreamId, pushPromise)); assertEquals(frame, sendPushPromiseFrames(expectedPromisedStreamId, pushPromise));
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override @Override
public void pushPromise(int streamId, int promisedStreamId, List<Header> headerBlock) { public void pushPromise(int streamId, int promisedStreamId, List<Header> headerBlock) {
assertEquals(expectedStreamId, streamId); assertEquals(expectedStreamId, streamId);
@@ -199,7 +199,7 @@ public class Http2Test {
assertEquals(frame, sendPushPromiseFrames(expectedPromisedStreamId, pushPromise)); assertEquals(frame, sendPushPromiseFrames(expectedPromisedStreamId, pushPromise));
// Reading the above frames should result in a concatenated headerBlock. // Reading the above frames should result in a concatenated headerBlock.
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override @Override
public void pushPromise(int streamId, int promisedStreamId, List<Header> headerBlock) { public void pushPromise(int streamId, int promisedStreamId, List<Header> headerBlock) {
assertEquals(expectedStreamId, streamId); assertEquals(expectedStreamId, streamId);
@@ -216,7 +216,7 @@ public class Http2Test {
frame.writeInt(expectedStreamId & 0x7fffffff); frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeInt(ErrorCode.PROTOCOL_ERROR.httpCode); frame.writeInt(ErrorCode.PROTOCOL_ERROR.httpCode);
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void rstStream(int streamId, ErrorCode errorCode) { @Override public void rstStream(int streamId, ErrorCode errorCode) {
assertEquals(expectedStreamId, streamId); assertEquals(expectedStreamId, streamId);
assertEquals(ErrorCode.PROTOCOL_ERROR, errorCode); assertEquals(ErrorCode.PROTOCOL_ERROR, errorCode);
@@ -236,7 +236,7 @@ public class Http2Test {
frame.writeShort(2); // SETTINGS_ENABLE_PUSH frame.writeShort(2); // SETTINGS_ENABLE_PUSH
frame.writeInt(0); frame.writeInt(0);
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void settings(boolean clearPrevious, Settings settings) { @Override public void settings(boolean clearPrevious, Settings settings) {
assertFalse(clearPrevious); // No clearPrevious in HTTP/2. assertFalse(clearPrevious); // No clearPrevious in HTTP/2.
assertEquals(reducedTableSizeBytes, settings.getHeaderTableSize()); assertEquals(reducedTableSizeBytes, settings.getHeaderTableSize());
@@ -254,7 +254,7 @@ public class Http2Test {
frame.writeInt(2); frame.writeInt(2);
try { try {
fr.nextFrame(new BaseTestHandler()); reader.nextFrame(new BaseTestHandler());
fail(); fail();
} catch (IOException e) { } catch (IOException e) {
assertEquals("PROTOCOL_ERROR SETTINGS_ENABLE_PUSH != 0 or 1", e.getMessage()); assertEquals("PROTOCOL_ERROR SETTINGS_ENABLE_PUSH != 0 or 1", e.getMessage());
@@ -270,7 +270,7 @@ public class Http2Test {
frame.writeInt(1); frame.writeInt(1);
final AtomicInteger settingValue = new AtomicInteger(); final AtomicInteger settingValue = new AtomicInteger();
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void settings(boolean clearPrevious, Settings settings) { @Override public void settings(boolean clearPrevious, Settings settings) {
settingValue.set(settings.get(7)); settingValue.set(settings.get(7));
} }
@@ -287,7 +287,7 @@ public class Http2Test {
frame.writeInt(Integer.MIN_VALUE); frame.writeInt(Integer.MIN_VALUE);
try { try {
fr.nextFrame(new BaseTestHandler()); reader.nextFrame(new BaseTestHandler());
fail(); fail();
} catch (IOException e) { } catch (IOException e) {
assertEquals("PROTOCOL_ERROR SETTINGS_INITIAL_WINDOW_SIZE > 2^31 - 1", e.getMessage()); assertEquals("PROTOCOL_ERROR SETTINGS_INITIAL_WINDOW_SIZE > 2^31 - 1", e.getMessage());
@@ -303,7 +303,7 @@ public class Http2Test {
frame.writeInt(Integer.MIN_VALUE); frame.writeInt(Integer.MIN_VALUE);
try { try {
fr.nextFrame(new BaseTestHandler()); reader.nextFrame(new BaseTestHandler());
fail(); fail();
} catch (IOException e) { } catch (IOException e) {
assertEquals("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: -2147483648", e.getMessage()); assertEquals("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: -2147483648", e.getMessage());
@@ -319,7 +319,7 @@ public class Http2Test {
frame.writeInt((int) Math.pow(2, 14) - 1); frame.writeInt((int) Math.pow(2, 14) - 1);
try { try {
fr.nextFrame(new BaseTestHandler()); reader.nextFrame(new BaseTestHandler());
fail(); fail();
} catch (IOException e) { } catch (IOException e) {
assertEquals("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: 16383", e.getMessage()); assertEquals("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: 16383", e.getMessage());
@@ -335,7 +335,7 @@ public class Http2Test {
frame.writeInt((int) Math.pow(2, 24)); frame.writeInt((int) Math.pow(2, 24));
try { try {
fr.nextFrame(new BaseTestHandler()); reader.nextFrame(new BaseTestHandler());
fail(); fail();
} catch (IOException e) { } catch (IOException e) {
assertEquals("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: 16777216", e.getMessage()); assertEquals("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: 16777216", e.getMessage());
@@ -356,7 +356,7 @@ public class Http2Test {
// Check writer sends the same bytes. // Check writer sends the same bytes.
assertEquals(frame, sendPingFrame(true, expectedPayload1, expectedPayload2)); assertEquals(frame, sendPingFrame(true, expectedPayload1, expectedPayload2));
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void ping(boolean ack, int payload1, int payload2) { @Override public void ping(boolean ack, int payload1, int payload2) {
assertTrue(ack); assertTrue(ack);
assertEquals(expectedPayload1, payload1); assertEquals(expectedPayload1, payload1);
@@ -378,7 +378,7 @@ public class Http2Test {
// Check writer sends the same bytes. // Check writer sends the same bytes.
assertEquals(frame, sendDataFrame(new Buffer().write(expectedData))); assertEquals(frame, sendDataFrame(new Buffer().write(expectedData)));
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void data(boolean inFinished, int streamId, BufferedSource source, @Override public void data(boolean inFinished, int streamId, BufferedSource source,
int length) throws IOException { int length) throws IOException {
assertFalse(inFinished); assertFalse(inFinished);
@@ -406,7 +406,7 @@ public class Http2Test {
zipped.readAll(frame); zipped.readAll(frame);
try { try {
fr.nextFrame(new BaseTestHandler()); reader.nextFrame(new BaseTestHandler());
fail(); fail();
} catch (IOException e) { } catch (IOException e) {
assertEquals("PROTOCOL_ERROR: FLAG_COMPRESSED without SETTINGS_COMPRESS_DATA", assertEquals("PROTOCOL_ERROR: FLAG_COMPRESSED without SETTINGS_COMPRESS_DATA",
@@ -431,7 +431,7 @@ public class Http2Test {
frame.write(expectedData); frame.write(expectedData);
frame.write(padding); frame.write(padding);
fr.nextFrame(assertData()); reader.nextFrame(assertData());
assertTrue(frame.exhausted()); // Padding was skipped. assertTrue(frame.exhausted()); // Padding was skipped.
} }
@@ -447,7 +447,7 @@ public class Http2Test {
frame.writeByte(0); frame.writeByte(0);
frame.write(expectedData); frame.write(expectedData);
fr.nextFrame(assertData()); reader.nextFrame(assertData());
} }
@Test public void readPaddedHeadersFrame() throws IOException { @Test public void readPaddedHeadersFrame() throws IOException {
@@ -464,7 +464,7 @@ public class Http2Test {
frame.writeAll(headerBlock); frame.writeAll(headerBlock);
frame.write(padding); frame.write(padding);
fr.nextFrame(assertHeaderBlock()); reader.nextFrame(assertHeaderBlock());
assertTrue(frame.exhausted()); // Padding was skipped. assertTrue(frame.exhausted()); // Padding was skipped.
} }
@@ -477,7 +477,7 @@ public class Http2Test {
frame.writeByte(0); frame.writeByte(0);
frame.writeAll(headerBlock); frame.writeAll(headerBlock);
fr.nextFrame(assertHeaderBlock()); reader.nextFrame(assertHeaderBlock());
} }
/** Headers are compressed, then framed. */ /** Headers are compressed, then framed. */
@@ -505,7 +505,7 @@ public class Http2Test {
frame.writeInt(expectedStreamId & 0x7fffffff); frame.writeInt(expectedStreamId & 0x7fffffff);
frame.writeAll(headerBlock); frame.writeAll(headerBlock);
fr.nextFrame(assertHeaderBlock()); reader.nextFrame(assertHeaderBlock());
assertTrue(frame.exhausted()); assertTrue(frame.exhausted());
} }
@@ -530,7 +530,7 @@ public class Http2Test {
// Check writer sends the same bytes. // Check writer sends the same bytes.
assertEquals(frame, windowUpdate(expectedWindowSizeIncrement)); assertEquals(frame, windowUpdate(expectedWindowSizeIncrement));
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void windowUpdate(int streamId, long windowSizeIncrement) { @Override public void windowUpdate(int streamId, long windowSizeIncrement) {
assertEquals(expectedStreamId, streamId); assertEquals(expectedStreamId, streamId);
assertEquals(expectedWindowSizeIncrement, windowSizeIncrement); assertEquals(expectedWindowSizeIncrement, windowSizeIncrement);
@@ -568,7 +568,7 @@ public class Http2Test {
// Check writer sends the same bytes. // Check writer sends the same bytes.
assertEquals(frame, sendGoAway(expectedStreamId, expectedError, Util.EMPTY_BYTE_ARRAY)); assertEquals(frame, sendGoAway(expectedStreamId, expectedError, Util.EMPTY_BYTE_ARRAY));
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void goAway( @Override public void goAway(
int lastGoodStreamId, ErrorCode errorCode, ByteString debugData) { int lastGoodStreamId, ErrorCode errorCode, ByteString debugData) {
assertEquals(expectedStreamId, lastGoodStreamId); assertEquals(expectedStreamId, lastGoodStreamId);
@@ -594,7 +594,7 @@ public class Http2Test {
// Check writer sends the same bytes. // Check writer sends the same bytes.
assertEquals(frame, sendGoAway(0, expectedError, expectedData.toByteArray())); assertEquals(frame, sendGoAway(0, expectedError, expectedData.toByteArray()));
fr.nextFrame(new BaseTestHandler() { reader.nextFrame(new BaseTestHandler() {
@Override public void goAway( @Override public void goAway(
int lastGoodStreamId, ErrorCode errorCode, ByteString debugData) { int lastGoodStreamId, ErrorCode errorCode, ByteString debugData) {
assertEquals(0, lastGoodStreamId); assertEquals(0, lastGoodStreamId);
@@ -605,7 +605,7 @@ public class Http2Test {
} }
@Test public void frameSizeError() throws IOException { @Test public void frameSizeError() throws IOException {
FrameWriter writer = new FrameWriter(new Buffer(), true); Http2Writer writer = new Http2Writer(new Buffer(), true);
try { try {
writer.frameHeader(0, 16777216, Http2.TYPE_DATA, FLAG_NONE); writer.frameHeader(0, 16777216, Http2.TYPE_DATA, FLAG_NONE);
@@ -619,7 +619,7 @@ public class Http2Test {
@Test public void ackSettingsAppliesMaxFrameSize() throws IOException { @Test public void ackSettingsAppliesMaxFrameSize() throws IOException {
int newMaxFrameSize = 16777215; int newMaxFrameSize = 16777215;
FrameWriter writer = new FrameWriter(new Buffer(), true); Http2Writer writer = new Http2Writer(new Buffer(), true);
writer.applyAndAckSettings(new Settings().set(Settings.MAX_FRAME_SIZE, newMaxFrameSize)); writer.applyAndAckSettings(new Settings().set(Settings.MAX_FRAME_SIZE, newMaxFrameSize));
@@ -628,7 +628,7 @@ public class Http2Test {
} }
@Test public void streamIdHasReservedBit() throws IOException { @Test public void streamIdHasReservedBit() throws IOException {
FrameWriter writer = new FrameWriter(new Buffer(), true); Http2Writer writer = new Http2Writer(new Buffer(), true);
try { try {
int streamId = 3; int streamId = 3;
@@ -648,43 +648,43 @@ public class Http2Test {
private Buffer sendHeaderFrames(boolean outFinished, List<Header> headers) throws IOException { private Buffer sendHeaderFrames(boolean outFinished, List<Header> headers) throws IOException {
Buffer out = new Buffer(); Buffer out = new Buffer();
new FrameWriter(out, true).headers(outFinished, expectedStreamId, headers); new Http2Writer(out, true).headers(outFinished, expectedStreamId, headers);
return out; return out;
} }
private Buffer sendPushPromiseFrames(int streamId, List<Header> headers) throws IOException { private Buffer sendPushPromiseFrames(int streamId, List<Header> headers) throws IOException {
Buffer out = new Buffer(); Buffer out = new Buffer();
new FrameWriter(out, true).pushPromise(expectedStreamId, streamId, headers); new Http2Writer(out, true).pushPromise(expectedStreamId, streamId, headers);
return out; return out;
} }
private Buffer sendPingFrame(boolean ack, int payload1, int payload2) throws IOException { private Buffer sendPingFrame(boolean ack, int payload1, int payload2) throws IOException {
Buffer out = new Buffer(); Buffer out = new Buffer();
new FrameWriter(out, true).ping(ack, payload1, payload2); new Http2Writer(out, true).ping(ack, payload1, payload2);
return out; return out;
} }
private Buffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData) private Buffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData)
throws IOException { throws IOException {
Buffer out = new Buffer(); Buffer out = new Buffer();
new FrameWriter(out, true).goAway(lastGoodStreamId, errorCode, debugData); new Http2Writer(out, true).goAway(lastGoodStreamId, errorCode, debugData);
return out; return out;
} }
private Buffer sendDataFrame(Buffer data) throws IOException { private Buffer sendDataFrame(Buffer data) throws IOException {
Buffer out = new Buffer(); Buffer out = new Buffer();
new FrameWriter(out, true).dataFrame(expectedStreamId, FLAG_NONE, data, new Http2Writer(out, true).dataFrame(expectedStreamId, FLAG_NONE, data,
(int) data.size()); (int) data.size());
return out; return out;
} }
private Buffer windowUpdate(long windowSizeIncrement) throws IOException { private Buffer windowUpdate(long windowSizeIncrement) throws IOException {
Buffer out = new Buffer(); Buffer out = new Buffer();
new FrameWriter(out, true).windowUpdate(expectedStreamId, windowSizeIncrement); new Http2Writer(out, true).windowUpdate(expectedStreamId, windowSizeIncrement);
return out; return out;
} }
private FrameReader.Handler assertHeaderBlock() { private Http2Reader.Handler assertHeaderBlock() {
return new BaseTestHandler() { return new BaseTestHandler() {
@Override public void headers(boolean inFinished, int streamId, @Override public void headers(boolean inFinished, int streamId,
int associatedStreamId, List<Header> headerBlock) { int associatedStreamId, List<Header> headerBlock) {
@@ -696,7 +696,7 @@ public class Http2Test {
}; };
} }
private FrameReader.Handler assertData() { private Http2Reader.Handler assertData() {
return new BaseTestHandler() { return new BaseTestHandler() {
@Override public void data(boolean inFinished, int streamId, BufferedSource source, @Override public void data(boolean inFinished, int streamId, BufferedSource source,
int length) throws IOException { int length) throws IOException {
@@ -717,7 +717,7 @@ public class Http2Test {
return buffer; return buffer;
} }
/** Create a sufficiently large header set to overflow Http20Draft12.INITIAL_MAX_FRAME_SIZE bytes. */ /** Create a sufficiently large header set to overflow INITIAL_MAX_FRAME_SIZE bytes. */
private static List<Header> largeHeaders() { private static List<Header> largeHeaders() {
String[] nameValues = new String[32]; String[] nameValues = new String[32];
char[] chars = new char[512]; char[] chars = new char[512];

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
@@ -44,7 +44,7 @@ public final class MockHttp2Peer implements Closeable {
private int frameCount = 0; private int frameCount = 0;
private boolean client = false; private boolean client = false;
private final Buffer bytesOut = new Buffer(); private final Buffer bytesOut = new Buffer();
private FrameWriter frameWriter = new FrameWriter(bytesOut, client); private Http2Writer writer = new Http2Writer(bytesOut, client);
private final List<OutFrame> outFrames = new ArrayList<>(); private final List<OutFrame> outFrames = new ArrayList<>();
private final BlockingQueue<InFrame> inFrames = new LinkedBlockingQueue<>(); private final BlockingQueue<InFrame> inFrames = new LinkedBlockingQueue<>();
private int port; private int port;
@@ -58,7 +58,7 @@ public final class MockHttp2Peer implements Closeable {
return; return;
} }
this.client = client; this.client = client;
this.frameWriter = new FrameWriter(bytesOut, client); this.writer = new Http2Writer(bytesOut, client);
} }
public void acceptFrame() { public void acceptFrame() {
@@ -67,7 +67,7 @@ public final class MockHttp2Peer implements Closeable {
/** Maximum length of an outbound data frame. */ /** Maximum length of an outbound data frame. */
public int maxOutboundDataLength() { public int maxOutboundDataLength() {
return frameWriter.maxDataLength(); return writer.maxDataLength();
} }
/** Count of frames sent or received. */ /** Count of frames sent or received. */
@@ -75,9 +75,9 @@ public final class MockHttp2Peer implements Closeable {
return frameCount; return frameCount;
} }
public FrameWriter sendFrame() { public Http2Writer sendFrame() {
outFrames.add(new OutFrame(frameCount++, bytesOut.size(), false)); outFrames.add(new OutFrame(frameCount++, bytesOut.size(), false));
return frameWriter; return writer;
} }
/** /**
@@ -85,7 +85,7 @@ public final class MockHttp2Peer implements Closeable {
* close the socket as soon as this frame has been written; otherwise the peer stays open until * close the socket as soon as this frame has been written; otherwise the peer stays open until
* explicitly closed. * explicitly closed.
*/ */
public FrameWriter truncateLastFrame(int length) { public Http2Writer truncateLastFrame(int length) {
OutFrame lastFrame = outFrames.remove(outFrames.size() - 1); OutFrame lastFrame = outFrames.remove(outFrames.size() - 1);
if (length >= bytesOut.size() - lastFrame.start) throw new IllegalArgumentException(); if (length >= bytesOut.size() - lastFrame.start) throw new IllegalArgumentException();
@@ -97,7 +97,7 @@ public final class MockHttp2Peer implements Closeable {
fullBuffer.read(bytesOut, lastFrame.start + length); fullBuffer.read(bytesOut, lastFrame.start + length);
outFrames.add(new OutFrame(lastFrame.sequence, lastFrame.start, true)); outFrames.add(new OutFrame(lastFrame.sequence, lastFrame.start, true));
return frameWriter; return writer;
} }
public InFrame takeFrame() throws InterruptedException { public InFrame takeFrame() throws InterruptedException {
@@ -136,7 +136,7 @@ public final class MockHttp2Peer implements Closeable {
OutputStream out = socket.getOutputStream(); OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream(); InputStream in = socket.getInputStream();
FrameReader reader = new FrameReader(Okio.buffer(Okio.source(in)), client); Http2Reader reader = new Http2Reader(Okio.buffer(Okio.source(in)), client);
Iterator<OutFrame> outFramesIterator = outFrames.iterator(); Iterator<OutFrame> outFramesIterator = outFrames.iterator();
byte[] outBytes = bytesOut.readByteArray(); byte[] outBytes = bytesOut.readByteArray();
@@ -203,9 +203,9 @@ public final class MockHttp2Peer implements Closeable {
} }
} }
public static class InFrame implements FrameReader.Handler { public static class InFrame implements Http2Reader.Handler {
public final int sequence; public final int sequence;
public final FrameReader reader; public final Http2Reader reader;
public int type = -1; public int type = -1;
public boolean clearPrevious; public boolean clearPrevious;
public boolean outFinished; public boolean outFinished;
@@ -221,7 +221,7 @@ public final class MockHttp2Peer implements Closeable {
public int payload1; public int payload1;
public int payload2; public int payload2;
public InFrame(int sequence, FrameReader reader) { public InFrame(int sequence, Http2Reader reader) {
this.sequence = sequence; this.sequence = sequence;
this.reader = reader; this.reader = reader;
} }

View File

@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import org.junit.Test; import org.junit.Test;
import static okhttp3.internal.framed.Settings.DEFAULT_INITIAL_WINDOW_SIZE; import static okhttp3.internal.http2.Settings.DEFAULT_INITIAL_WINDOW_SIZE;
import static okhttp3.internal.framed.Settings.MAX_CONCURRENT_STREAMS; import static okhttp3.internal.http2.Settings.MAX_CONCURRENT_STREAMS;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public final class SettingsTest { public final class SettingsTest {

View File

@@ -33,7 +33,6 @@ import static okhttp3.internal.platform.PlatformTest.getPlatform;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
public final class CertificatePinnerChainValidationTest { public final class CertificatePinnerChainValidationTest {
@Rule public final MockWebServer server = new MockWebServer(); @Rule public final MockWebServer server = new MockWebServer();

View File

@@ -180,7 +180,7 @@ public final class WebSocketCall {
@Override protected void close() throws IOException { @Override protected void close() throws IOException {
replyExecutor.shutdown(); replyExecutor.shutdown();
streamAllocation.noNewStreams(); streamAllocation.noNewStreams();
streamAllocation.streamFinished(true, streamAllocation.stream()); streamAllocation.streamFinished(true, streamAllocation.codec());
} }
} }
} }

View File

@@ -26,9 +26,9 @@ import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import okhttp3.internal.Internal; import okhttp3.internal.Internal;
import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.http.HttpHeaders; import okhttp3.internal.http.HttpHeaders;
import okhttp3.internal.http.HttpMethod; import okhttp3.internal.http.HttpMethod;
import okhttp3.internal.http.HttpStream;
import okhttp3.internal.http.RealResponseBody; import okhttp3.internal.http.RealResponseBody;
import okio.Buffer; import okio.Buffer;
import okio.BufferedSink; import okio.BufferedSink;
@@ -222,7 +222,7 @@ public final class CacheInterceptor implements Interceptor {
@Override public void close() throws IOException { @Override public void close() throws IOException {
if (!cacheRequestClosed if (!cacheRequestClosed
&& !discard(this, HttpStream.DISCARD_STREAM_TIMEOUT_MILLIS, MILLISECONDS)) { && !discard(this, HttpCodec.DISCARD_STREAM_TIMEOUT_MILLIS, MILLISECONDS)) {
cacheRequestClosed = true; cacheRequestClosed = true;
cacheRequest.abort(); cacheRequest.abort();
} }

View File

@@ -21,7 +21,7 @@ import okhttp3.Interceptor;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.internal.http.HttpStream; import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.http.RealInterceptorChain; import okhttp3.internal.http.RealInterceptorChain;
/** Opens a connection to the target server and proceeds to the next interceptor. */ /** Opens a connection to the target server and proceeds to the next interceptor. */
@@ -39,9 +39,9 @@ public final class ConnectInterceptor implements Interceptor {
// We need the network to satisfy this request. Possibly for validating a conditional GET. // We need the network to satisfy this request. Possibly for validating a conditional GET.
boolean doExtensiveHealthChecks = !request.method().equals("GET"); boolean doExtensiveHealthChecks = !request.method().equals("GET");
HttpStream httpStream = streamAllocation.newStream(client, doExtensiveHealthChecks); HttpCodec httpCodec = streamAllocation.newStream(client, doExtensiveHealthChecks);
RealConnection connection = streamAllocation.connection(); RealConnection connection = streamAllocation.connection();
return realChain.proceed(request, streamAllocation, httpStream, connection); return realChain.proceed(request, streamAllocation, httpCodec, connection);
} }
} }

View File

@@ -43,11 +43,11 @@ import okhttp3.Response;
import okhttp3.Route; import okhttp3.Route;
import okhttp3.internal.Util; import okhttp3.internal.Util;
import okhttp3.internal.Version; import okhttp3.internal.Version;
import okhttp3.internal.framed.ErrorCode;
import okhttp3.internal.framed.FramedConnection;
import okhttp3.internal.framed.FramedStream;
import okhttp3.internal.http.Http1xStream;
import okhttp3.internal.http.HttpHeaders; import okhttp3.internal.http.HttpHeaders;
import okhttp3.internal.http1.Http1Codec;
import okhttp3.internal.http2.ErrorCode;
import okhttp3.internal.http2.Http2Connection;
import okhttp3.internal.http2.Http2Stream;
import okhttp3.internal.platform.Platform; import okhttp3.internal.platform.Platform;
import okhttp3.internal.tls.OkHostnameVerifier; import okhttp3.internal.tls.OkHostnameVerifier;
import okio.BufferedSink; import okio.BufferedSink;
@@ -60,7 +60,7 @@ import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static okhttp3.internal.Util.closeQuietly; import static okhttp3.internal.Util.closeQuietly;
public final class RealConnection extends FramedConnection.Listener implements Connection { public final class RealConnection extends Http2Connection.Listener implements Connection {
private final Route route; private final Route route;
/** The low-level TCP socket. */ /** The low-level TCP socket. */
@@ -73,7 +73,7 @@ public final class RealConnection extends FramedConnection.Listener implements C
public Socket socket; public Socket socket;
private Handshake handshake; private Handshake handshake;
private Protocol protocol; private Protocol protocol;
public volatile FramedConnection framedConnection; public volatile Http2Connection http2Connection;
public int successCount; public int successCount;
public BufferedSource source; public BufferedSource source;
public BufferedSink sink; public BufferedSink sink;
@@ -204,15 +204,15 @@ public final class RealConnection extends FramedConnection.Listener implements C
if (protocol == Protocol.HTTP_2) { if (protocol == Protocol.HTTP_2) {
socket.setSoTimeout(0); // Framed connection timeouts are set per-stream. socket.setSoTimeout(0); // Framed connection timeouts are set per-stream.
FramedConnection framedConnection = new FramedConnection.Builder(true) Http2Connection http2Connection = new Http2Connection.Builder(true)
.socket(socket, route.address().url().host(), source, sink) .socket(socket, route.address().url().host(), source, sink)
.listener(this) .listener(this)
.build(); .build();
framedConnection.start(); http2Connection.start();
// Only assign the framed connection once the preface has been sent successfully. // Only assign the framed connection once the preface has been sent successfully.
this.allocationLimit = framedConnection.maxConcurrentStreams(); this.allocationLimit = http2Connection.maxConcurrentStreams();
this.framedConnection = framedConnection; this.http2Connection = http2Connection;
} else { } else {
this.allocationLimit = 1; this.allocationLimit = 1;
} }
@@ -287,7 +287,7 @@ public final class RealConnection extends FramedConnection.Listener implements C
// Make an SSL Tunnel on the first message pair of each SSL + proxy connection. // Make an SSL Tunnel on the first message pair of each SSL + proxy connection.
String requestLine = "CONNECT " + Util.hostHeader(url, true) + " HTTP/1.1"; String requestLine = "CONNECT " + Util.hostHeader(url, true) + " HTTP/1.1";
while (true) { while (true) {
Http1xStream tunnelConnection = new Http1xStream(null, null, source, sink); Http1Codec tunnelConnection = new Http1Codec(null, null, source, sink);
source.timeout().timeout(readTimeout, MILLISECONDS); source.timeout().timeout(readTimeout, MILLISECONDS);
sink.timeout().timeout(writeTimeout, MILLISECONDS); sink.timeout().timeout(writeTimeout, MILLISECONDS);
tunnelConnection.writeRequest(tunnelRequest.headers(), requestLine); tunnelConnection.writeRequest(tunnelRequest.headers(), requestLine);
@@ -363,7 +363,7 @@ public final class RealConnection extends FramedConnection.Listener implements C
return false; return false;
} }
if (framedConnection != null) { if (http2Connection != null) {
return true; // TODO: check framedConnection.shutdown. return true; // TODO: check framedConnection.shutdown.
} }
@@ -390,12 +390,12 @@ public final class RealConnection extends FramedConnection.Listener implements C
} }
/** Refuse incoming streams. */ /** Refuse incoming streams. */
@Override public void onStream(FramedStream stream) throws IOException { @Override public void onStream(Http2Stream stream) throws IOException {
stream.close(ErrorCode.REFUSED_STREAM); stream.close(ErrorCode.REFUSED_STREAM);
} }
/** When settings are received, adjust the allocation limit. */ /** When settings are received, adjust the allocation limit. */
@Override public void onSettings(FramedConnection connection) { @Override public void onSettings(Http2Connection connection) {
allocationLimit = connection.maxConcurrentStreams(); allocationLimit = connection.maxConcurrentStreams();
} }
@@ -408,11 +408,11 @@ public final class RealConnection extends FramedConnection.Listener implements C
* requests simultaneously. * requests simultaneously.
*/ */
public boolean isMultiplexed() { public boolean isMultiplexed() {
return framedConnection != null; return http2Connection != null;
} }
@Override public Protocol protocol() { @Override public Protocol protocol() {
if (framedConnection == null) { if (http2Connection == null) {
return protocol != null ? protocol : Protocol.HTTP_1_1; return protocol != null ? protocol : Protocol.HTTP_1_1;
} else { } else {
return Protocol.HTTP_2; return Protocol.HTTP_2;

View File

@@ -24,11 +24,11 @@ import okhttp3.OkHttpClient;
import okhttp3.Route; import okhttp3.Route;
import okhttp3.internal.Internal; import okhttp3.internal.Internal;
import okhttp3.internal.Util; import okhttp3.internal.Util;
import okhttp3.internal.framed.ErrorCode; import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.framed.StreamResetException; import okhttp3.internal.http1.Http1Codec;
import okhttp3.internal.http.Http1xStream; import okhttp3.internal.http2.ErrorCode;
import okhttp3.internal.http.Http2xStream; import okhttp3.internal.http2.Http2Codec;
import okhttp3.internal.http.HttpStream; import okhttp3.internal.http2.StreamResetException;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -80,7 +80,7 @@ public final class StreamAllocation {
private RealConnection connection; private RealConnection connection;
private boolean released; private boolean released;
private boolean canceled; private boolean canceled;
private HttpStream stream; private HttpCodec codec;
public StreamAllocation(ConnectionPool connectionPool, Address address) { public StreamAllocation(ConnectionPool connectionPool, Address address) {
this.connectionPool = connectionPool; this.connectionPool = connectionPool;
@@ -88,7 +88,7 @@ public final class StreamAllocation {
this.routeSelector = new RouteSelector(address, routeDatabase()); this.routeSelector = new RouteSelector(address, routeDatabase());
} }
public HttpStream newStream(OkHttpClient client, boolean doExtensiveHealthChecks) { public HttpCodec newStream(OkHttpClient client, boolean doExtensiveHealthChecks) {
int connectTimeout = client.connectTimeoutMillis(); int connectTimeout = client.connectTimeoutMillis();
int readTimeout = client.readTimeoutMillis(); int readTimeout = client.readTimeoutMillis();
int writeTimeout = client.writeTimeoutMillis(); int writeTimeout = client.writeTimeoutMillis();
@@ -98,20 +98,20 @@ public final class StreamAllocation {
RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout, RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout,
writeTimeout, connectionRetryEnabled, doExtensiveHealthChecks); writeTimeout, connectionRetryEnabled, doExtensiveHealthChecks);
HttpStream resultStream; HttpCodec resultCodec;
if (resultConnection.framedConnection != null) { if (resultConnection.http2Connection != null) {
resultStream = new Http2xStream(client, this, resultConnection.framedConnection); resultCodec = new Http2Codec(client, this, resultConnection.http2Connection);
} else { } else {
resultConnection.socket().setSoTimeout(readTimeout); resultConnection.socket().setSoTimeout(readTimeout);
resultConnection.source.timeout().timeout(readTimeout, MILLISECONDS); resultConnection.source.timeout().timeout(readTimeout, MILLISECONDS);
resultConnection.sink.timeout().timeout(writeTimeout, MILLISECONDS); resultConnection.sink.timeout().timeout(writeTimeout, MILLISECONDS);
resultStream = new Http1xStream( resultCodec = new Http1Codec(
client, this, resultConnection.source, resultConnection.sink); client, this, resultConnection.source, resultConnection.sink);
} }
synchronized (connectionPool) { synchronized (connectionPool) {
stream = resultStream; codec = resultCodec;
return resultStream; return resultCodec;
} }
} catch (IOException e) { } catch (IOException e) {
throw new RouteException(e); throw new RouteException(e);
@@ -156,7 +156,7 @@ public final class StreamAllocation {
Route selectedRoute; Route selectedRoute;
synchronized (connectionPool) { synchronized (connectionPool) {
if (released) throw new IllegalStateException("released"); if (released) throw new IllegalStateException("released");
if (stream != null) throw new IllegalStateException("stream != null"); if (codec != null) throw new IllegalStateException("codec != null");
if (canceled) throw new IOException("Canceled"); if (canceled) throw new IOException("Canceled");
RealConnection allocatedConnection = this.connection; RealConnection allocatedConnection = this.connection;
@@ -197,10 +197,10 @@ public final class StreamAllocation {
return newConnection; return newConnection;
} }
public void streamFinished(boolean noNewStreams, HttpStream stream) { public void streamFinished(boolean noNewStreams, HttpCodec codec) {
synchronized (connectionPool) { synchronized (connectionPool) {
if (stream == null || stream != this.stream) { if (codec == null || codec != this.codec) {
throw new IllegalStateException("expected " + this.stream + " but was " + stream); throw new IllegalStateException("expected " + this.codec + " but was " + codec);
} }
if (!noNewStreams) { if (!noNewStreams) {
connection.successCount++; connection.successCount++;
@@ -209,9 +209,9 @@ public final class StreamAllocation {
deallocate(noNewStreams, false, true); deallocate(noNewStreams, false, true);
} }
public HttpStream stream() { public HttpCodec codec() {
synchronized (connectionPool) { synchronized (connectionPool) {
return stream; return codec;
} }
} }
@@ -240,7 +240,7 @@ public final class StreamAllocation {
RealConnection connectionToClose = null; RealConnection connectionToClose = null;
synchronized (connectionPool) { synchronized (connectionPool) {
if (streamFinished) { if (streamFinished) {
this.stream = null; this.codec = null;
} }
if (released) { if (released) {
this.released = true; this.released = true;
@@ -249,7 +249,7 @@ public final class StreamAllocation {
if (noNewStreams) { if (noNewStreams) {
connection.noNewStreams = true; connection.noNewStreams = true;
} }
if (this.stream == null && (this.released || connection.noNewStreams)) { if (this.codec == null && (this.released || connection.noNewStreams)) {
release(connection); release(connection);
if (connection.allocations.isEmpty()) { if (connection.allocations.isEmpty()) {
connection.idleAtNanos = System.nanoTime(); connection.idleAtNanos = System.nanoTime();
@@ -267,15 +267,15 @@ public final class StreamAllocation {
} }
public void cancel() { public void cancel() {
HttpStream streamToCancel; HttpCodec codecToCancel;
RealConnection connectionToCancel; RealConnection connectionToCancel;
synchronized (connectionPool) { synchronized (connectionPool) {
canceled = true; canceled = true;
streamToCancel = stream; codecToCancel = codec;
connectionToCancel = connection; connectionToCancel = connection;
} }
if (streamToCancel != null) { if (codecToCancel != null) {
streamToCancel.cancel(); codecToCancel.cancel();
} else if (connectionToCancel != null) { } else if (connectionToCancel != null) {
connectionToCancel.cancel(); connectionToCancel.cancel();
} }

View File

@@ -1,60 +0,0 @@
/*
* Copyright (C) 2013 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3.internal.framed;
import java.io.IOException;
import okio.ByteString;
import static okhttp3.internal.Util.format;
public final class Http2 {
static final ByteString CONNECTION_PREFACE
= ByteString.encodeUtf8("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n");
/** The initial max frame size, applied independently writing to, or reading from the peer. */
static final int INITIAL_MAX_FRAME_SIZE = 0x4000; // 16384
static final byte TYPE_DATA = 0x0;
static final byte TYPE_HEADERS = 0x1;
static final byte TYPE_PRIORITY = 0x2;
static final byte TYPE_RST_STREAM = 0x3;
static final byte TYPE_SETTINGS = 0x4;
static final byte TYPE_PUSH_PROMISE = 0x5;
static final byte TYPE_PING = 0x6;
static final byte TYPE_GOAWAY = 0x7;
static final byte TYPE_WINDOW_UPDATE = 0x8;
static final byte TYPE_CONTINUATION = 0x9;
static final byte FLAG_NONE = 0x0;
static final byte FLAG_ACK = 0x1; // Used for settings and ping.
static final byte FLAG_END_STREAM = 0x1; // Used for headers and data.
static final byte FLAG_END_HEADERS = 0x4; // Used for headers and continuation.
static final byte FLAG_END_PUSH_PROMISE = 0x4;
static final byte FLAG_PADDED = 0x8; // Used for headers and data.
static final byte FLAG_PRIORITY = 0x20; // Used for headers.
static final byte FLAG_COMPRESSED = 0x20; // Used for data.
private Http2() {
}
static IllegalArgumentException illegalArgument(String message, Object... args) {
throw new IllegalArgumentException(format(message, args));
}
static IOException ioException(String message, Object... args) throws IOException {
throw new IOException(format(message, args));
}
}

View File

@@ -34,23 +34,23 @@ public final class CallServerInterceptor implements Interceptor {
} }
@Override public Response intercept(Chain chain) throws IOException { @Override public Response intercept(Chain chain) throws IOException {
HttpStream httpStream = ((RealInterceptorChain) chain).httpStream(); HttpCodec httpCodec = ((RealInterceptorChain) chain).httpStream();
StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation(); StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
Request request = chain.request(); Request request = chain.request();
long sentRequestMillis = System.currentTimeMillis(); long sentRequestMillis = System.currentTimeMillis();
httpStream.writeRequestHeaders(request); httpCodec.writeRequestHeaders(request);
if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) { if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
Sink requestBodyOut = httpStream.createRequestBody(request, request.body().contentLength()); Sink requestBodyOut = httpCodec.createRequestBody(request, request.body().contentLength());
BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut); BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
request.body().writeTo(bufferedRequestBody); request.body().writeTo(bufferedRequestBody);
bufferedRequestBody.close(); bufferedRequestBody.close();
} }
httpStream.finishRequest(); httpCodec.finishRequest();
Response response = httpStream.readResponseHeaders() Response response = httpCodec.readResponseHeaders()
.request(request) .request(request)
.handshake(streamAllocation.connection().handshake()) .handshake(streamAllocation.connection().handshake())
.sentRequestAtMillis(sentRequestMillis) .sentRequestAtMillis(sentRequestMillis)
@@ -59,7 +59,7 @@ public final class CallServerInterceptor implements Interceptor {
if (!forWebSocket || response.code() != 101) { if (!forWebSocket || response.code() != 101) {
response = response.newBuilder() response = response.newBuilder()
.body(httpStream.openResponseBody(response)) .body(httpCodec.openResponseBody(response))
.build(); .build();
} }

View File

@@ -21,7 +21,8 @@ import okhttp3.Response;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import okio.Sink; import okio.Sink;
public interface HttpStream { /** Encodes HTTP requests and decodes HTTP responses. */
public interface HttpCodec {
/** /**
* The timeout to use while discarding a stream of input data. Since this is used for connection * The timeout to use while discarding a stream of input data. Since this is used for connection
* reuse, this timeout should be significantly less than the time it takes to establish a new * reuse, this timeout should be significantly less than the time it takes to establish a new

View File

@@ -31,18 +31,18 @@ import okhttp3.internal.connection.StreamAllocation;
public final class RealInterceptorChain implements Interceptor.Chain { public final class RealInterceptorChain implements Interceptor.Chain {
private final List<Interceptor> interceptors; private final List<Interceptor> interceptors;
private final StreamAllocation streamAllocation; private final StreamAllocation streamAllocation;
private final HttpStream httpStream; private final HttpCodec httpCodec;
private final Connection connection; private final Connection connection;
private final int index; private final int index;
private final Request request; private final Request request;
private int calls; private int calls;
public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation, public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,
HttpStream httpStream, Connection connection, int index, Request request) { HttpCodec httpCodec, Connection connection, int index, Request request) {
this.interceptors = interceptors; this.interceptors = interceptors;
this.connection = connection; this.connection = connection;
this.streamAllocation = streamAllocation; this.streamAllocation = streamAllocation;
this.httpStream = httpStream; this.httpCodec = httpCodec;
this.index = index; this.index = index;
this.request = request; this.request = request;
} }
@@ -55,8 +55,8 @@ public final class RealInterceptorChain implements Interceptor.Chain {
return streamAllocation; return streamAllocation;
} }
public HttpStream httpStream() { public HttpCodec httpStream() {
return httpStream; return httpCodec;
} }
@Override public Request request() { @Override public Request request() {
@@ -64,35 +64,35 @@ public final class RealInterceptorChain implements Interceptor.Chain {
} }
@Override public Response proceed(Request request) throws IOException { @Override public Response proceed(Request request) throws IOException {
return proceed(request, streamAllocation, httpStream, connection); return proceed(request, streamAllocation, httpCodec, connection);
} }
public Response proceed(Request request, StreamAllocation streamAllocation, HttpStream httpStream, public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
Connection connection) throws IOException { Connection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError(); if (index >= interceptors.size()) throw new AssertionError();
calls++; calls++;
// If we already have a stream, confirm that the incoming request will use it. // If we already have a stream, confirm that the incoming request will use it.
if (this.httpStream != null && !sameConnection(request.url())) { if (this.httpCodec != null && !sameConnection(request.url())) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1) throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port"); + " must retain the same host and port");
} }
// If we already have a stream, confirm that this is the only call to chain.proceed(). // If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpStream != null && calls > 1) { if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1) throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once"); + " must call proceed() exactly once");
} }
// Call the next interceptor in the chain. // Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain( RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpStream, connection, index + 1, request); interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index); Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next); Response response = interceptor.intercept(next);
// Confirm that the next interceptor made its required call to chain.proceed(). // Confirm that the next interceptor made its required call to chain.proceed().
if (httpStream != null && index + 1 < interceptors.size() && next.calls != 1) { if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once"); + " must call proceed() exactly once");
} }

View File

@@ -29,7 +29,7 @@ public final class RequestLine {
* {@link HttpURLConnection#getHeaderFields}, so it needs to be set even if the transport is * {@link HttpURLConnection#getHeaderFields}, so it needs to be set even if the transport is
* HTTP/2. * HTTP/2.
*/ */
static String get(Request request, Proxy.Type proxyType) { public static String get(Request request, Proxy.Type proxyType) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
result.append(request.method()); result.append(request.method());
result.append(' '); result.append(' ');

View File

@@ -174,7 +174,7 @@ public final class RetryAndFollowUpInterceptor implements Interceptor {
streamAllocation.release(); streamAllocation.release();
streamAllocation = new StreamAllocation( streamAllocation = new StreamAllocation(
client.connectionPool(), createAddress(followUp.url())); client.connectionPool(), createAddress(followUp.url()));
} else if (streamAllocation.stream() != null) { } else if (streamAllocation.codec() != null) {
throw new IllegalStateException("Closing the body of " + response throw new IllegalStateException("Closing the body of " + response
+ " didn't close its backing stream. Bad interceptor?"); + " didn't close its backing stream. Bad interceptor?");
} }

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.http; package okhttp3.internal.http1;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
@@ -28,6 +28,11 @@ import okhttp3.internal.Internal;
import okhttp3.internal.Util; import okhttp3.internal.Util;
import okhttp3.internal.connection.RealConnection; import okhttp3.internal.connection.RealConnection;
import okhttp3.internal.connection.StreamAllocation; import okhttp3.internal.connection.StreamAllocation;
import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.http.HttpHeaders;
import okhttp3.internal.http.RealResponseBody;
import okhttp3.internal.http.RequestLine;
import okhttp3.internal.http.StatusLine;
import okio.Buffer; import okio.Buffer;
import okio.BufferedSink; import okio.BufferedSink;
import okio.BufferedSource; import okio.BufferedSource;
@@ -61,7 +66,7 @@ import static okhttp3.internal.http.StatusLine.HTTP_CONTINUE;
* Exchanges that do not have a response body can call {@link #newFixedLengthSource(long) * Exchanges that do not have a response body can call {@link #newFixedLengthSource(long)
* newFixedLengthSource(0)} and may skip reading and closing that source. * newFixedLengthSource(0)} and may skip reading and closing that source.
*/ */
public final class Http1xStream implements HttpStream { public final class Http1Codec implements HttpCodec {
private static final int STATE_IDLE = 0; // Idle connections are ready to write request headers. private static final int STATE_IDLE = 0; // Idle connections are ready to write request headers.
private static final int STATE_OPEN_REQUEST_BODY = 1; private static final int STATE_OPEN_REQUEST_BODY = 1;
private static final int STATE_WRITING_REQUEST_BODY = 2; private static final int STATE_WRITING_REQUEST_BODY = 2;
@@ -79,7 +84,7 @@ public final class Http1xStream implements HttpStream {
private final BufferedSink sink; private final BufferedSink sink;
private int state = STATE_IDLE; private int state = STATE_IDLE;
public Http1xStream(OkHttpClient client, StreamAllocation streamAllocation, BufferedSource source, public Http1Codec(OkHttpClient client, StreamAllocation streamAllocation, BufferedSource source,
BufferedSink sink) { BufferedSink sink) {
this.client = client; this.client = client;
this.streamAllocation = streamAllocation; this.streamAllocation = streamAllocation;
@@ -353,7 +358,7 @@ public final class Http1xStream implements HttpStream {
state = STATE_CLOSED; state = STATE_CLOSED;
if (streamAllocation != null) { if (streamAllocation != null) {
streamAllocation.streamFinished(!reuseConnection, Http1xStream.this); streamAllocation.streamFinished(!reuseConnection, Http1Codec.this);
} }
} }
} }

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
// http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-7 // http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-7
public enum ErrorCode { public enum ErrorCode {

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import okhttp3.internal.Util; import okhttp3.internal.Util;
import okio.ByteString; import okio.ByteString;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;

View File

@@ -13,83 +13,42 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException;
import okio.ByteString;
import static okhttp3.internal.Util.format; import static okhttp3.internal.Util.format;
import static okhttp3.internal.framed.Http2.FLAG_ACK;
import static okhttp3.internal.framed.Http2.FLAG_COMPRESSED;
import static okhttp3.internal.framed.Http2.FLAG_END_HEADERS;
import static okhttp3.internal.framed.Http2.FLAG_END_PUSH_PROMISE;
import static okhttp3.internal.framed.Http2.FLAG_END_STREAM;
import static okhttp3.internal.framed.Http2.FLAG_NONE;
import static okhttp3.internal.framed.Http2.FLAG_PADDED;
import static okhttp3.internal.framed.Http2.FLAG_PRIORITY;
import static okhttp3.internal.framed.Http2.TYPE_DATA;
import static okhttp3.internal.framed.Http2.TYPE_GOAWAY;
import static okhttp3.internal.framed.Http2.TYPE_PING;
import static okhttp3.internal.framed.Http2.TYPE_PRIORITY;
import static okhttp3.internal.framed.Http2.TYPE_PUSH_PROMISE;
import static okhttp3.internal.framed.Http2.TYPE_RST_STREAM;
import static okhttp3.internal.framed.Http2.TYPE_SETTINGS;
import static okhttp3.internal.framed.Http2.TYPE_WINDOW_UPDATE;
/** public final class Http2 {
* Logs a human-readable representation of HTTP/2 frame headers. static final ByteString CONNECTION_PREFACE
* = ByteString.encodeUtf8("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n");
* <p>The format is:
*
* <pre>
* direction streamID length type flags
* </pre>
* Where direction is {@code <<} for inbound and {@code >>} for outbound.
*
* <p>For example, the following would indicate a HEAD request sent from the client.
* <pre>
* {@code
* << 0x0000000f 12 HEADERS END_HEADERS|END_STREAM
* }
* </pre>
*/
final class FrameLogger {
private FrameLogger() {
}
static String formatHeader(boolean inbound, int streamId, int length, byte type, byte flags) { /** The initial max frame size, applied independently writing to, or reading from the peer. */
String formattedType = type < TYPES.length ? TYPES[type] : format("0x%02x", type); static final int INITIAL_MAX_FRAME_SIZE = 0x4000; // 16384
String formattedFlags = formatFlags(type, flags);
return format("%s 0x%08x %5d %-13s %s", inbound ? "<<" : ">>", streamId, length,
formattedType, formattedFlags);
}
/** static final byte TYPE_DATA = 0x0;
* Looks up valid string representing flags from the table. Invalid combinations are represented static final byte TYPE_HEADERS = 0x1;
* in binary. static final byte TYPE_PRIORITY = 0x2;
*/ static final byte TYPE_RST_STREAM = 0x3;
// Visible for testing. static final byte TYPE_SETTINGS = 0x4;
static String formatFlags(byte type, byte flags) { static final byte TYPE_PUSH_PROMISE = 0x5;
if (flags == 0) return ""; static final byte TYPE_PING = 0x6;
switch (type) { // Special case types that have 0 or 1 flag. static final byte TYPE_GOAWAY = 0x7;
case TYPE_SETTINGS: static final byte TYPE_WINDOW_UPDATE = 0x8;
case TYPE_PING: static final byte TYPE_CONTINUATION = 0x9;
return flags == FLAG_ACK ? "ACK" : BINARY[flags];
case TYPE_PRIORITY: static final byte FLAG_NONE = 0x0;
case TYPE_RST_STREAM: static final byte FLAG_ACK = 0x1; // Used for settings and ping.
case TYPE_GOAWAY: static final byte FLAG_END_STREAM = 0x1; // Used for headers and data.
case TYPE_WINDOW_UPDATE: static final byte FLAG_END_HEADERS = 0x4; // Used for headers and continuation.
return BINARY[flags]; static final byte FLAG_END_PUSH_PROMISE = 0x4;
} static final byte FLAG_PADDED = 0x8; // Used for headers and data.
String result = flags < FLAGS.length ? FLAGS[flags] : BINARY[flags]; static final byte FLAG_PRIORITY = 0x20; // Used for headers.
// Special case types that have overlap flag values. static final byte FLAG_COMPRESSED = 0x20; // Used for data.
if (type == TYPE_PUSH_PROMISE && (flags & FLAG_END_PUSH_PROMISE) != 0) {
return result.replace("HEADERS", "PUSH_PROMISE"); // TODO: Avoid allocation.
} else if (type == TYPE_DATA && (flags & FLAG_COMPRESSED) != 0) {
return result.replace("PRIORITY", "COMPRESSED"); // TODO: Avoid allocation.
}
return result;
}
/** Lookup table for valid frame types. */ /** Lookup table for valid frame types. */
private static final String[] TYPES = new String[] { private static final String[] FRAME_NAMES = new String[] {
"DATA", "DATA",
"HEADERS", "HEADERS",
"PRIORITY", "PRIORITY",
@@ -106,9 +65,8 @@ final class FrameLogger {
* Lookup table for valid flags for DATA, HEADERS, CONTINUATION. Invalid combinations are * Lookup table for valid flags for DATA, HEADERS, CONTINUATION. Invalid combinations are
* represented in binary. * represented in binary.
*/ */
private static final String[] FLAGS = new String[0x40]; // Highest bit flag is 0x20. static final String[] FLAGS = new String[0x40]; // Highest bit flag is 0x20.
private static final String[] BINARY = new String[256]; static final String[] BINARY = new String[256];
static { static {
for (int i = 0; i < BINARY.length; i++) { for (int i = 0; i < BINARY.length; i++) {
BINARY[i] = format("%8s", Integer.toBinaryString(i)).replace(' ', '0'); BINARY[i] = format("%8s", Integer.toBinaryString(i)).replace(' ', '0');
@@ -143,4 +101,67 @@ final class FrameLogger {
if (FLAGS[i] == null) FLAGS[i] = BINARY[i]; if (FLAGS[i] == null) FLAGS[i] = BINARY[i];
} }
} }
private Http2() {
}
static IllegalArgumentException illegalArgument(String message, Object... args) {
throw new IllegalArgumentException(format(message, args));
}
static IOException ioException(String message, Object... args) throws IOException {
throw new IOException(format(message, args));
}
/**
* Returns human-readable representation of HTTP/2 frame headers.
*
* <p>The format is:
*
* <pre>
* direction streamID length type flags
* </pre>
*
* Where direction is {@code <<} for inbound and {@code >>} for outbound.
*
* <p>For example, the following would indicate a HEAD request sent from the client.
* <pre>
* {@code
* << 0x0000000f 12 HEADERS END_HEADERS|END_STREAM
* }
* </pre>
*/
static String frameLog(boolean inbound, int streamId, int length, byte type, byte flags) {
String formattedType = type < FRAME_NAMES.length ? FRAME_NAMES[type] : format("0x%02x", type);
String formattedFlags = formatFlags(type, flags);
return format("%s 0x%08x %5d %-13s %s", inbound ? "<<" : ">>", streamId, length,
formattedType, formattedFlags);
}
/**
* Looks up valid string representing flags from the table. Invalid combinations are represented
* in binary.
*/
// Visible for testing.
static String formatFlags(byte type, byte flags) {
if (flags == 0) return "";
switch (type) { // Special case types that have 0 or 1 flag.
case TYPE_SETTINGS:
case TYPE_PING:
return flags == FLAG_ACK ? "ACK" : BINARY[flags];
case TYPE_PRIORITY:
case TYPE_RST_STREAM:
case TYPE_GOAWAY:
case TYPE_WINDOW_UPDATE:
return BINARY[flags];
}
String result = flags < FLAGS.length ? FLAGS[flags] : BINARY[flags];
// Special case types that have overlap flag values.
if (type == TYPE_PUSH_PROMISE && (flags & FLAG_END_PUSH_PROMISE) != 0) {
return result.replace("HEADERS", "PUSH_PROMISE"); // TODO: Avoid allocation.
} else if (type == TYPE_DATA && (flags & FLAG_COMPRESSED) != 0) {
return result.replace("PRIORITY", "COMPRESSED"); // TODO: Avoid allocation.
}
return result;
}
} }

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.http; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;
import java.net.ProtocolException; import java.net.ProtocolException;
@@ -30,24 +30,25 @@ import okhttp3.ResponseBody;
import okhttp3.internal.Internal; import okhttp3.internal.Internal;
import okhttp3.internal.Util; import okhttp3.internal.Util;
import okhttp3.internal.connection.StreamAllocation; import okhttp3.internal.connection.StreamAllocation;
import okhttp3.internal.framed.ErrorCode; import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.framed.FramedConnection; import okhttp3.internal.http.HttpMethod;
import okhttp3.internal.framed.FramedStream; import okhttp3.internal.http.RealResponseBody;
import okhttp3.internal.framed.Header; import okhttp3.internal.http.RequestLine;
import okhttp3.internal.http.StatusLine;
import okio.ByteString; import okio.ByteString;
import okio.ForwardingSource; import okio.ForwardingSource;
import okio.Okio; import okio.Okio;
import okio.Sink; import okio.Sink;
import okio.Source; import okio.Source;
import static okhttp3.internal.framed.Header.RESPONSE_STATUS; import static okhttp3.internal.http2.Header.RESPONSE_STATUS;
import static okhttp3.internal.framed.Header.TARGET_AUTHORITY; import static okhttp3.internal.http2.Header.TARGET_AUTHORITY;
import static okhttp3.internal.framed.Header.TARGET_METHOD; import static okhttp3.internal.http2.Header.TARGET_METHOD;
import static okhttp3.internal.framed.Header.TARGET_PATH; import static okhttp3.internal.http2.Header.TARGET_PATH;
import static okhttp3.internal.framed.Header.TARGET_SCHEME; import static okhttp3.internal.http2.Header.TARGET_SCHEME;
/** An HTTP stream for HTTP/2. */ /** Encode requests and responses using HTTP/2 frames. */
public final class Http2xStream implements HttpStream { public final class Http2Codec implements HttpCodec {
private static final ByteString CONNECTION = ByteString.encodeUtf8("connection"); private static final ByteString CONNECTION = ByteString.encodeUtf8("connection");
private static final ByteString HOST = ByteString.encodeUtf8("host"); private static final ByteString HOST = ByteString.encodeUtf8("host");
private static final ByteString KEEP_ALIVE = ByteString.encodeUtf8("keep-alive"); private static final ByteString KEEP_ALIVE = ByteString.encodeUtf8("keep-alive");
@@ -83,14 +84,14 @@ public final class Http2xStream implements HttpStream {
private final OkHttpClient client; private final OkHttpClient client;
private final StreamAllocation streamAllocation; private final StreamAllocation streamAllocation;
private final FramedConnection framedConnection; private final Http2Connection connection;
private FramedStream stream; private Http2Stream stream;
public Http2xStream( public Http2Codec(
OkHttpClient client, StreamAllocation streamAllocation, FramedConnection framedConnection) { OkHttpClient client, StreamAllocation streamAllocation, Http2Connection connection) {
this.client = client; this.client = client;
this.streamAllocation = streamAllocation; this.streamAllocation = streamAllocation;
this.framedConnection = framedConnection; this.connection = connection;
} }
@Override public Sink createRequestBody(Request request, long contentLength) { @Override public Sink createRequestBody(Request request, long contentLength) {
@@ -102,7 +103,7 @@ public final class Http2xStream implements HttpStream {
boolean permitsRequestBody = HttpMethod.permitsRequestBody(request.method()); boolean permitsRequestBody = HttpMethod.permitsRequestBody(request.method());
List<Header> requestHeaders = http2HeadersList(request); List<Header> requestHeaders = http2HeadersList(request);
stream = framedConnection.newStream(requestHeaders, permitsRequestBody); stream = connection.newStream(requestHeaders, permitsRequestBody);
stream.readTimeout().timeout(client.readTimeoutMillis(), TimeUnit.MILLISECONDS); stream.readTimeout().timeout(client.readTimeoutMillis(), TimeUnit.MILLISECONDS);
stream.writeTimeout().timeout(client.writeTimeoutMillis(), TimeUnit.MILLISECONDS); stream.writeTimeout().timeout(client.writeTimeoutMillis(), TimeUnit.MILLISECONDS);
} }
@@ -173,7 +174,7 @@ public final class Http2xStream implements HttpStream {
} }
@Override public void close() throws IOException { @Override public void close() throws IOException {
streamAllocation.streamFinished(false, Http2xStream.this); streamAllocation.streamFinished(false, Http2Codec.this);
super.close(); super.close();
} }
} }

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
@@ -40,7 +40,7 @@ import okio.BufferedSource;
import okio.ByteString; import okio.ByteString;
import okio.Okio; import okio.Okio;
import static okhttp3.internal.framed.Settings.DEFAULT_INITIAL_WINDOW_SIZE; import static okhttp3.internal.http2.Settings.DEFAULT_INITIAL_WINDOW_SIZE;
import static okhttp3.internal.platform.Platform.INFO; import static okhttp3.internal.platform.Platform.INFO;
/** /**
@@ -52,7 +52,7 @@ import static okhttp3.internal.platform.Platform.INFO;
* transparency: an IOException that was triggered by a certain caller can be caught and handled by * transparency: an IOException that was triggered by a certain caller can be caught and handled by
* that caller. * that caller.
*/ */
public final class FramedConnection implements Closeable { public final class Http2Connection implements Closeable {
// Internal state of this connection is guarded by 'this'. No blocking // Internal state of this connection is guarded by 'this'. No blocking
// operations may be performed while holding this lock! // operations may be performed while holding this lock!
@@ -78,7 +78,7 @@ public final class FramedConnection implements Closeable {
* on {@link #executor}. * on {@link #executor}.
*/ */
private final Listener listener; private final Listener listener;
private final Map<Integer, FramedStream> streams = new HashMap<>(); private final Map<Integer, Http2Stream> streams = new HashMap<>();
private final String hostname; private final String hostname;
private int lastGoodStreamId; private int lastGoodStreamId;
private int nextStreamId; private int nextStreamId;
@@ -117,12 +117,12 @@ public final class FramedConnection implements Closeable {
private boolean receivedInitialPeerSettings = false; private boolean receivedInitialPeerSettings = false;
final Socket socket; final Socket socket;
final FrameWriter frameWriter; final Http2Writer writer;
// Visible for testing // Visible for testing
final Reader readerRunnable; final ReaderRunnable readerRunnable;
private FramedConnection(Builder builder) { private Http2Connection(Builder builder) {
pushObserver = builder.pushObserver; pushObserver = builder.pushObserver;
client = builder.client; client = builder.client;
listener = builder.listener; listener = builder.listener;
@@ -152,9 +152,9 @@ public final class FramedConnection implements Closeable {
peerSettings.set(Settings.MAX_FRAME_SIZE, Http2.INITIAL_MAX_FRAME_SIZE); peerSettings.set(Settings.MAX_FRAME_SIZE, Http2.INITIAL_MAX_FRAME_SIZE);
bytesLeftInWriteWindow = peerSettings.getInitialWindowSize(); bytesLeftInWriteWindow = peerSettings.getInitialWindowSize();
socket = builder.socket; socket = builder.socket;
frameWriter = new FrameWriter(builder.sink, client); writer = new Http2Writer(builder.sink, client);
readerRunnable = new Reader(new FrameReader(builder.source, client)); readerRunnable = new ReaderRunnable(new Http2Reader(builder.source, client));
} }
/** The protocol as selected using ALPN. */ /** The protocol as selected using ALPN. */
@@ -163,18 +163,18 @@ public final class FramedConnection implements Closeable {
} }
/** /**
* Returns the number of {@link FramedStream#isOpen() open streams} on this connection. * Returns the number of {@link Http2Stream#isOpen() open streams} on this connection.
*/ */
public synchronized int openStreamCount() { public synchronized int openStreamCount() {
return streams.size(); return streams.size();
} }
synchronized FramedStream getStream(int id) { synchronized Http2Stream getStream(int id) {
return streams.get(id); return streams.get(id);
} }
synchronized FramedStream removeStream(int streamId) { synchronized Http2Stream removeStream(int streamId) {
FramedStream stream = streams.remove(streamId); Http2Stream stream = streams.remove(streamId);
notifyAll(); // The removed stream may be blocked on a connection-wide window update. notifyAll(); // The removed stream may be blocked on a connection-wide window update.
return stream; return stream;
} }
@@ -190,7 +190,7 @@ public final class FramedConnection implements Closeable {
* @param out true to create an output stream that we can use to send data to the remote peer. * @param out true to create an output stream that we can use to send data to the remote peer.
* Corresponds to {@code FLAG_FIN}. * Corresponds to {@code FLAG_FIN}.
*/ */
public FramedStream pushStream(int associatedStreamId, List<Header> requestHeaders, boolean out) public Http2Stream pushStream(int associatedStreamId, List<Header> requestHeaders, boolean out)
throws IOException { throws IOException {
if (client) throw new IllegalStateException("Client cannot push requests."); if (client) throw new IllegalStateException("Client cannot push requests.");
return newStream(associatedStreamId, requestHeaders, out); return newStream(associatedStreamId, requestHeaders, out);
@@ -201,42 +201,42 @@ public final class FramedConnection implements Closeable {
* @param out true to create an output stream that we can use to send data to the remote peer. * @param out true to create an output stream that we can use to send data to the remote peer.
* Corresponds to {@code FLAG_FIN}. * Corresponds to {@code FLAG_FIN}.
*/ */
public FramedStream newStream(List<Header> requestHeaders, boolean out) throws IOException { public Http2Stream newStream(List<Header> requestHeaders, boolean out) throws IOException {
return newStream(0, requestHeaders, out); return newStream(0, requestHeaders, out);
} }
private FramedStream newStream( private Http2Stream newStream(
int associatedStreamId, List<Header> requestHeaders, boolean out) throws IOException { int associatedStreamId, List<Header> requestHeaders, boolean out) throws IOException {
boolean outFinished = !out; boolean outFinished = !out;
boolean inFinished = false; boolean inFinished = false;
boolean flushHeaders; boolean flushHeaders;
FramedStream stream; Http2Stream stream;
int streamId; int streamId;
synchronized (frameWriter) { synchronized (writer) {
synchronized (this) { synchronized (this) {
if (shutdown) { if (shutdown) {
throw new IOException("shutdown"); throw new IOException("shutdown");
} }
streamId = nextStreamId; streamId = nextStreamId;
nextStreamId += 2; nextStreamId += 2;
stream = new FramedStream(streamId, this, outFinished, inFinished, requestHeaders); stream = new Http2Stream(streamId, this, outFinished, inFinished, requestHeaders);
flushHeaders = !out || bytesLeftInWriteWindow == 0L || stream.bytesLeftInWriteWindow == 0L; flushHeaders = !out || bytesLeftInWriteWindow == 0L || stream.bytesLeftInWriteWindow == 0L;
if (stream.isOpen()) { if (stream.isOpen()) {
streams.put(streamId, stream); streams.put(streamId, stream);
} }
} }
if (associatedStreamId == 0) { if (associatedStreamId == 0) {
frameWriter.synStream(outFinished, streamId, associatedStreamId, requestHeaders); writer.synStream(outFinished, streamId, associatedStreamId, requestHeaders);
} else if (client) { } else if (client) {
throw new IllegalArgumentException("client streams shouldn't have associated stream IDs"); throw new IllegalArgumentException("client streams shouldn't have associated stream IDs");
} else { // HTTP/2 has a PUSH_PROMISE frame. } else { // HTTP/2 has a PUSH_PROMISE frame.
frameWriter.pushPromise(associatedStreamId, streamId, requestHeaders); writer.pushPromise(associatedStreamId, streamId, requestHeaders);
} }
} }
if (flushHeaders) { if (flushHeaders) {
frameWriter.flush(); writer.flush();
} }
return stream; return stream;
@@ -244,7 +244,7 @@ public final class FramedConnection implements Closeable {
void writeSynReply(int streamId, boolean outFinished, List<Header> alternating) void writeSynReply(int streamId, boolean outFinished, List<Header> alternating)
throws IOException { throws IOException {
frameWriter.synReply(outFinished, streamId, alternating); writer.synReply(outFinished, streamId, alternating);
} }
/** /**
@@ -262,13 +262,13 @@ public final class FramedConnection implements Closeable {
public void writeData(int streamId, boolean outFinished, Buffer buffer, long byteCount) public void writeData(int streamId, boolean outFinished, Buffer buffer, long byteCount)
throws IOException { throws IOException {
if (byteCount == 0) { // Empty data frames are not flow-controlled. if (byteCount == 0) { // Empty data frames are not flow-controlled.
frameWriter.data(outFinished, streamId, buffer, 0); writer.data(outFinished, streamId, buffer, 0);
return; return;
} }
while (byteCount > 0) { while (byteCount > 0) {
int toWrite; int toWrite;
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
try { try {
while (bytesLeftInWriteWindow <= 0) { while (bytesLeftInWriteWindow <= 0) {
// Before blocking, confirm that the stream we're writing is still open. It's possible // Before blocking, confirm that the stream we're writing is still open. It's possible
@@ -276,19 +276,19 @@ public final class FramedConnection implements Closeable {
if (!streams.containsKey(streamId)) { if (!streams.containsKey(streamId)) {
throw new IOException("stream closed"); throw new IOException("stream closed");
} }
FramedConnection.this.wait(); // Wait until we receive a WINDOW_UPDATE. Http2Connection.this.wait(); // Wait until we receive a WINDOW_UPDATE.
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new InterruptedIOException(); throw new InterruptedIOException();
} }
toWrite = (int) Math.min(byteCount, bytesLeftInWriteWindow); toWrite = (int) Math.min(byteCount, bytesLeftInWriteWindow);
toWrite = Math.min(toWrite, frameWriter.maxDataLength()); toWrite = Math.min(toWrite, writer.maxDataLength());
bytesLeftInWriteWindow -= toWrite; bytesLeftInWriteWindow -= toWrite;
} }
byteCount -= toWrite; byteCount -= toWrite;
frameWriter.data(outFinished && byteCount == 0, streamId, buffer, toWrite); writer.data(outFinished && byteCount == 0, streamId, buffer, toWrite);
} }
} }
@@ -297,7 +297,7 @@ public final class FramedConnection implements Closeable {
*/ */
void addBytesToWriteWindow(long delta) { void addBytesToWriteWindow(long delta) {
bytesLeftInWriteWindow += delta; bytesLeftInWriteWindow += delta;
if (delta > 0) FramedConnection.this.notifyAll(); if (delta > 0) Http2Connection.this.notifyAll();
} }
void writeSynResetLater(final int streamId, final ErrorCode errorCode) { void writeSynResetLater(final int streamId, final ErrorCode errorCode) {
@@ -312,14 +312,14 @@ public final class FramedConnection implements Closeable {
} }
void writeSynReset(int streamId, ErrorCode statusCode) throws IOException { void writeSynReset(int streamId, ErrorCode statusCode) throws IOException {
frameWriter.rstStream(streamId, statusCode); writer.rstStream(streamId, statusCode);
} }
void writeWindowUpdateLater(final int streamId, final long unacknowledgedBytesRead) { void writeWindowUpdateLater(final int streamId, final long unacknowledgedBytesRead) {
executor.execute(new NamedRunnable("OkHttp Window Update %s stream %d", hostname, streamId) { executor.execute(new NamedRunnable("OkHttp Window Update %s stream %d", hostname, streamId) {
@Override public void execute() { @Override public void execute() {
try { try {
frameWriter.windowUpdate(streamId, unacknowledgedBytesRead); writer.windowUpdate(streamId, unacknowledgedBytesRead);
} catch (IOException ignored) { } catch (IOException ignored) {
} }
} }
@@ -360,10 +360,10 @@ public final class FramedConnection implements Closeable {
} }
private void writePing(boolean reply, int payload1, int payload2, Ping ping) throws IOException { private void writePing(boolean reply, int payload1, int payload2, Ping ping) throws IOException {
synchronized (frameWriter) { synchronized (writer) {
// Observe the sent time immediately before performing I/O. // Observe the sent time immediately before performing I/O.
if (ping != null) ping.send(); if (ping != null) ping.send();
frameWriter.ping(reply, payload1, payload2); writer.ping(reply, payload1, payload2);
} }
} }
@@ -372,7 +372,7 @@ public final class FramedConnection implements Closeable {
} }
public void flush() throws IOException { public void flush() throws IOException {
frameWriter.flush(); writer.flush();
} }
/** /**
@@ -381,7 +381,7 @@ public final class FramedConnection implements Closeable {
* to gracefully stop accepting new requests without harming previously established streams. * to gracefully stop accepting new requests without harming previously established streams.
*/ */
public void shutdown(ErrorCode statusCode) throws IOException { public void shutdown(ErrorCode statusCode) throws IOException {
synchronized (frameWriter) { synchronized (writer) {
int lastGoodStreamId; int lastGoodStreamId;
synchronized (this) { synchronized (this) {
if (shutdown) { if (shutdown) {
@@ -391,7 +391,7 @@ public final class FramedConnection implements Closeable {
lastGoodStreamId = this.lastGoodStreamId; lastGoodStreamId = this.lastGoodStreamId;
} }
// TODO: propagate exception message into debugData // TODO: propagate exception message into debugData
frameWriter.goAway(lastGoodStreamId, statusCode, Util.EMPTY_BYTE_ARRAY); writer.goAway(lastGoodStreamId, statusCode, Util.EMPTY_BYTE_ARRAY);
} }
} }
@@ -412,11 +412,11 @@ public final class FramedConnection implements Closeable {
thrown = e; thrown = e;
} }
FramedStream[] streamsToClose = null; Http2Stream[] streamsToClose = null;
Ping[] pingsToCancel = null; Ping[] pingsToCancel = null;
synchronized (this) { synchronized (this) {
if (!streams.isEmpty()) { if (!streams.isEmpty()) {
streamsToClose = streams.values().toArray(new FramedStream[streams.size()]); streamsToClose = streams.values().toArray(new Http2Stream[streams.size()]);
streams.clear(); streams.clear();
} }
if (pings != null) { if (pings != null) {
@@ -426,7 +426,7 @@ public final class FramedConnection implements Closeable {
} }
if (streamsToClose != null) { if (streamsToClose != null) {
for (FramedStream stream : streamsToClose) { for (Http2Stream stream : streamsToClose) {
try { try {
stream.close(streamCode); stream.close(streamCode);
} catch (IOException e) { } catch (IOException e) {
@@ -443,7 +443,7 @@ public final class FramedConnection implements Closeable {
// Close the writer to release its resources (such as deflaters). // Close the writer to release its resources (such as deflaters).
try { try {
frameWriter.close(); writer.close();
} catch (IOException e) { } catch (IOException e) {
if (thrown == null) thrown = e; if (thrown == null) thrown = e;
} }
@@ -472,11 +472,11 @@ public final class FramedConnection implements Closeable {
*/ */
void start(boolean sendConnectionPreface) throws IOException { void start(boolean sendConnectionPreface) throws IOException {
if (sendConnectionPreface) { if (sendConnectionPreface) {
frameWriter.connectionPreface(); writer.connectionPreface();
frameWriter.settings(okHttpSettings); writer.settings(okHttpSettings);
int windowSize = okHttpSettings.getInitialWindowSize(); int windowSize = okHttpSettings.getInitialWindowSize();
if (windowSize != Settings.DEFAULT_INITIAL_WINDOW_SIZE) { if (windowSize != Settings.DEFAULT_INITIAL_WINDOW_SIZE) {
frameWriter.windowUpdate(0, windowSize - Settings.DEFAULT_INITIAL_WINDOW_SIZE); writer.windowUpdate(0, windowSize - Settings.DEFAULT_INITIAL_WINDOW_SIZE);
} }
} }
new Thread(readerRunnable).start(); // Not a daemon thread. new Thread(readerRunnable).start(); // Not a daemon thread.
@@ -484,13 +484,13 @@ public final class FramedConnection implements Closeable {
/** Merges {@code settings} into this peer's settings and sends them to the remote peer. */ /** Merges {@code settings} into this peer's settings and sends them to the remote peer. */
public void setSettings(Settings settings) throws IOException { public void setSettings(Settings settings) throws IOException {
synchronized (frameWriter) { synchronized (writer) {
synchronized (this) { synchronized (this) {
if (shutdown) { if (shutdown) {
throw new IOException("shutdown"); throw new IOException("shutdown");
} }
okHttpSettings.merge(settings); okHttpSettings.merge(settings);
frameWriter.settings(settings); writer.settings(settings);
} }
} }
} }
@@ -536,8 +536,8 @@ public final class FramedConnection implements Closeable {
return this; return this;
} }
public FramedConnection build() throws IOException { public Http2Connection build() throws IOException {
return new FramedConnection(this); return new Http2Connection(this);
} }
} }
@@ -545,12 +545,12 @@ public final class FramedConnection implements Closeable {
* Methods in this class must not lock FrameWriter. If a method needs to write a frame, create an * Methods in this class must not lock FrameWriter. If a method needs to write a frame, create an
* async task to do so. * async task to do so.
*/ */
class Reader extends NamedRunnable implements FrameReader.Handler { class ReaderRunnable extends NamedRunnable implements Http2Reader.Handler {
final FrameReader frameReader; final Http2Reader reader;
private Reader(FrameReader frameReader) { private ReaderRunnable(Http2Reader reader) {
super("OkHttp %s", hostname); super("OkHttp %s", hostname);
this.frameReader = frameReader; this.reader = reader;
} }
@Override protected void execute() { @Override protected void execute() {
@@ -558,9 +558,9 @@ public final class FramedConnection implements Closeable {
ErrorCode streamErrorCode = ErrorCode.INTERNAL_ERROR; ErrorCode streamErrorCode = ErrorCode.INTERNAL_ERROR;
try { try {
if (!client) { if (!client) {
frameReader.readConnectionPreface(); reader.readConnectionPreface();
} }
while (frameReader.nextFrame(this)) { while (reader.nextFrame(this)) {
} }
connectionErrorCode = ErrorCode.NO_ERROR; connectionErrorCode = ErrorCode.NO_ERROR;
streamErrorCode = ErrorCode.CANCEL; streamErrorCode = ErrorCode.CANCEL;
@@ -572,7 +572,7 @@ public final class FramedConnection implements Closeable {
close(connectionErrorCode, streamErrorCode); close(connectionErrorCode, streamErrorCode);
} catch (IOException ignored) { } catch (IOException ignored) {
} }
Util.closeQuietly(frameReader); Util.closeQuietly(reader);
} }
} }
@@ -582,7 +582,7 @@ public final class FramedConnection implements Closeable {
pushDataLater(streamId, source, length, inFinished); pushDataLater(streamId, source, length, inFinished);
return; return;
} }
FramedStream dataStream = getStream(streamId); Http2Stream dataStream = getStream(streamId);
if (dataStream == null) { if (dataStream == null) {
writeSynResetLater(streamId, ErrorCode.PROTOCOL_ERROR); writeSynResetLater(streamId, ErrorCode.PROTOCOL_ERROR);
source.skip(length); source.skip(length);
@@ -600,8 +600,8 @@ public final class FramedConnection implements Closeable {
pushHeadersLater(streamId, headerBlock, inFinished); pushHeadersLater(streamId, headerBlock, inFinished);
return; return;
} }
FramedStream stream; Http2Stream stream;
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
// If we're shutdown, don't bother with this stream. // If we're shutdown, don't bother with this stream.
if (shutdown) return; if (shutdown) return;
@@ -615,7 +615,7 @@ public final class FramedConnection implements Closeable {
if (streamId % 2 == nextStreamId % 2) return; if (streamId % 2 == nextStreamId % 2) return;
// Create a stream. // Create a stream.
final FramedStream newStream = new FramedStream(streamId, FramedConnection.this, final Http2Stream newStream = new Http2Stream(streamId, Http2Connection.this,
false, inFinished, headerBlock); false, inFinished, headerBlock);
lastGoodStreamId = streamId; lastGoodStreamId = streamId;
streams.put(streamId, newStream); streams.put(streamId, newStream);
@@ -646,7 +646,7 @@ public final class FramedConnection implements Closeable {
pushResetLater(streamId, errorCode); pushResetLater(streamId, errorCode);
return; return;
} }
FramedStream rstStream = removeStream(streamId); Http2Stream rstStream = removeStream(streamId);
if (rstStream != null) { if (rstStream != null) {
rstStream.receiveRstStream(errorCode); rstStream.receiveRstStream(errorCode);
} }
@@ -654,8 +654,8 @@ public final class FramedConnection implements Closeable {
@Override public void settings(boolean clearPrevious, Settings newSettings) { @Override public void settings(boolean clearPrevious, Settings newSettings) {
long delta = 0; long delta = 0;
FramedStream[] streamsToNotify = null; Http2Stream[] streamsToNotify = null;
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
int priorWriteWindowSize = peerSettings.getInitialWindowSize(); int priorWriteWindowSize = peerSettings.getInitialWindowSize();
if (clearPrevious) peerSettings.clear(); if (clearPrevious) peerSettings.clear();
peerSettings.merge(newSettings); peerSettings.merge(newSettings);
@@ -668,17 +668,17 @@ public final class FramedConnection implements Closeable {
receivedInitialPeerSettings = true; receivedInitialPeerSettings = true;
} }
if (!streams.isEmpty()) { if (!streams.isEmpty()) {
streamsToNotify = streams.values().toArray(new FramedStream[streams.size()]); streamsToNotify = streams.values().toArray(new Http2Stream[streams.size()]);
} }
} }
executor.execute(new NamedRunnable("OkHttp %s settings", hostname) { executor.execute(new NamedRunnable("OkHttp %s settings", hostname) {
@Override public void execute() { @Override public void execute() {
listener.onSettings(FramedConnection.this); listener.onSettings(Http2Connection.this);
} }
}); });
} }
if (streamsToNotify != null && delta != 0) { if (streamsToNotify != null && delta != 0) {
for (FramedStream stream : streamsToNotify) { for (Http2Stream stream : streamsToNotify) {
synchronized (stream) { synchronized (stream) {
stream.addBytesToWriteWindow(delta); stream.addBytesToWriteWindow(delta);
} }
@@ -690,7 +690,7 @@ public final class FramedConnection implements Closeable {
executor.execute(new NamedRunnable("OkHttp %s ACK Settings", hostname) { executor.execute(new NamedRunnable("OkHttp %s ACK Settings", hostname) {
@Override public void execute() { @Override public void execute() {
try { try {
frameWriter.applyAndAckSettings(peerSettings); writer.applyAndAckSettings(peerSettings);
} catch (IOException ignored) { } catch (IOException ignored) {
} }
} }
@@ -718,29 +718,29 @@ public final class FramedConnection implements Closeable {
} }
// Copy the streams first. We don't want to hold a lock when we call receiveRstStream(). // Copy the streams first. We don't want to hold a lock when we call receiveRstStream().
FramedStream[] streamsCopy; Http2Stream[] streamsCopy;
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
streamsCopy = streams.values().toArray(new FramedStream[streams.size()]); streamsCopy = streams.values().toArray(new Http2Stream[streams.size()]);
shutdown = true; shutdown = true;
} }
// Fail all streams created after the last good stream ID. // Fail all streams created after the last good stream ID.
for (FramedStream framedStream : streamsCopy) { for (Http2Stream http2Stream : streamsCopy) {
if (framedStream.getId() > lastGoodStreamId && framedStream.isLocallyInitiated()) { if (http2Stream.getId() > lastGoodStreamId && http2Stream.isLocallyInitiated()) {
framedStream.receiveRstStream(ErrorCode.REFUSED_STREAM); http2Stream.receiveRstStream(ErrorCode.REFUSED_STREAM);
removeStream(framedStream.getId()); removeStream(http2Stream.getId());
} }
} }
} }
@Override public void windowUpdate(int streamId, long windowSizeIncrement) { @Override public void windowUpdate(int streamId, long windowSizeIncrement) {
if (streamId == 0) { if (streamId == 0) {
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
bytesLeftInWriteWindow += windowSizeIncrement; bytesLeftInWriteWindow += windowSizeIncrement;
FramedConnection.this.notifyAll(); Http2Connection.this.notifyAll();
} }
} else { } else {
FramedStream stream = getStream(streamId); Http2Stream stream = getStream(streamId);
if (stream != null) { if (stream != null) {
synchronized (stream) { synchronized (stream) {
stream.addBytesToWriteWindow(windowSizeIncrement); stream.addBytesToWriteWindow(windowSizeIncrement);
@@ -786,8 +786,8 @@ public final class FramedConnection implements Closeable {
boolean cancel = pushObserver.onRequest(streamId, requestHeaders); boolean cancel = pushObserver.onRequest(streamId, requestHeaders);
try { try {
if (cancel) { if (cancel) {
frameWriter.rstStream(streamId, ErrorCode.CANCEL); writer.rstStream(streamId, ErrorCode.CANCEL);
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
currentPushRequests.remove(streamId); currentPushRequests.remove(streamId);
} }
} }
@@ -803,9 +803,9 @@ public final class FramedConnection implements Closeable {
@Override public void execute() { @Override public void execute() {
boolean cancel = pushObserver.onHeaders(streamId, requestHeaders, inFinished); boolean cancel = pushObserver.onHeaders(streamId, requestHeaders, inFinished);
try { try {
if (cancel) frameWriter.rstStream(streamId, ErrorCode.CANCEL); if (cancel) writer.rstStream(streamId, ErrorCode.CANCEL);
if (cancel || inFinished) { if (cancel || inFinished) {
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
currentPushRequests.remove(streamId); currentPushRequests.remove(streamId);
} }
} }
@@ -829,9 +829,9 @@ public final class FramedConnection implements Closeable {
@Override public void execute() { @Override public void execute() {
try { try {
boolean cancel = pushObserver.onData(streamId, buffer, byteCount, inFinished); boolean cancel = pushObserver.onData(streamId, buffer, byteCount, inFinished);
if (cancel) frameWriter.rstStream(streamId, ErrorCode.CANCEL); if (cancel) writer.rstStream(streamId, ErrorCode.CANCEL);
if (cancel || inFinished) { if (cancel || inFinished) {
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
currentPushRequests.remove(streamId); currentPushRequests.remove(streamId);
} }
} }
@@ -845,7 +845,7 @@ public final class FramedConnection implements Closeable {
pushExecutor.execute(new NamedRunnable("OkHttp %s Push Reset[%s]", hostname, streamId) { pushExecutor.execute(new NamedRunnable("OkHttp %s Push Reset[%s]", hostname, streamId) {
@Override public void execute() { @Override public void execute() {
pushObserver.onReset(streamId, errorCode); pushObserver.onReset(streamId, errorCode);
synchronized (FramedConnection.this) { synchronized (Http2Connection.this) {
currentPushRequests.remove(streamId); currentPushRequests.remove(streamId);
} }
} }
@@ -855,17 +855,17 @@ public final class FramedConnection implements Closeable {
/** Listener of streams and settings initiated by the peer. */ /** Listener of streams and settings initiated by the peer. */
public abstract static class Listener { public abstract static class Listener {
public static final Listener REFUSE_INCOMING_STREAMS = new Listener() { public static final Listener REFUSE_INCOMING_STREAMS = new Listener() {
@Override public void onStream(FramedStream stream) throws IOException { @Override public void onStream(Http2Stream stream) throws IOException {
stream.close(ErrorCode.REFUSED_STREAM); stream.close(ErrorCode.REFUSED_STREAM);
} }
}; };
/** /**
* Handle a new stream from this connection's peer. Implementations should respond by either * Handle a new stream from this connection's peer. Implementations should respond by either
* {@linkplain FramedStream#reply replying to the stream} or {@linkplain FramedStream#close * {@linkplain Http2Stream#reply replying to the stream} or {@linkplain Http2Stream#close
* closing it}. This response does not need to be synchronous. * closing it}. This response does not need to be synchronous.
*/ */
public abstract void onStream(FramedStream stream) throws IOException; public abstract void onStream(Http2Stream stream) throws IOException;
/** /**
* Notification that the connection's peer's settings may have changed. Implementations should * Notification that the connection's peer's settings may have changed. Implementations should
@@ -875,7 +875,7 @@ public final class FramedConnection implements Closeable {
* remote peer that sends multiple settings frames will trigger multiple calls to this method, * remote peer that sends multiple settings frames will trigger multiple calls to this method,
* and those calls are not necessarily serialized. * and those calls are not necessarily serialized.
*/ */
public void onSettings(FramedConnection connection) { public void onSettings(Http2Connection connection) {
} }
} }
} }

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
@@ -27,37 +27,37 @@ import okio.Timeout;
import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINE;
import static okhttp3.internal.Util.format; import static okhttp3.internal.Util.format;
import static okhttp3.internal.framed.FrameLogger.formatHeader; import static okhttp3.internal.http2.Http2.CONNECTION_PREFACE;
import static okhttp3.internal.framed.Http2.CONNECTION_PREFACE; import static okhttp3.internal.http2.Http2.FLAG_ACK;
import static okhttp3.internal.framed.Http2.FLAG_ACK; import static okhttp3.internal.http2.Http2.FLAG_COMPRESSED;
import static okhttp3.internal.framed.Http2.FLAG_COMPRESSED; import static okhttp3.internal.http2.Http2.FLAG_END_HEADERS;
import static okhttp3.internal.framed.Http2.FLAG_END_HEADERS; import static okhttp3.internal.http2.Http2.FLAG_END_STREAM;
import static okhttp3.internal.framed.Http2.FLAG_END_STREAM; import static okhttp3.internal.http2.Http2.FLAG_PADDED;
import static okhttp3.internal.framed.Http2.FLAG_PADDED; import static okhttp3.internal.http2.Http2.FLAG_PRIORITY;
import static okhttp3.internal.framed.Http2.FLAG_PRIORITY; import static okhttp3.internal.http2.Http2.INITIAL_MAX_FRAME_SIZE;
import static okhttp3.internal.framed.Http2.INITIAL_MAX_FRAME_SIZE; import static okhttp3.internal.http2.Http2.TYPE_CONTINUATION;
import static okhttp3.internal.framed.Http2.TYPE_CONTINUATION; import static okhttp3.internal.http2.Http2.TYPE_DATA;
import static okhttp3.internal.framed.Http2.TYPE_DATA; import static okhttp3.internal.http2.Http2.TYPE_GOAWAY;
import static okhttp3.internal.framed.Http2.TYPE_GOAWAY; import static okhttp3.internal.http2.Http2.TYPE_HEADERS;
import static okhttp3.internal.framed.Http2.TYPE_HEADERS; import static okhttp3.internal.http2.Http2.TYPE_PING;
import static okhttp3.internal.framed.Http2.TYPE_PING; import static okhttp3.internal.http2.Http2.TYPE_PRIORITY;
import static okhttp3.internal.framed.Http2.TYPE_PRIORITY; import static okhttp3.internal.http2.Http2.TYPE_PUSH_PROMISE;
import static okhttp3.internal.framed.Http2.TYPE_PUSH_PROMISE; import static okhttp3.internal.http2.Http2.TYPE_RST_STREAM;
import static okhttp3.internal.framed.Http2.TYPE_RST_STREAM; import static okhttp3.internal.http2.Http2.TYPE_SETTINGS;
import static okhttp3.internal.framed.Http2.TYPE_SETTINGS; import static okhttp3.internal.http2.Http2.TYPE_WINDOW_UPDATE;
import static okhttp3.internal.framed.Http2.TYPE_WINDOW_UPDATE; import static okhttp3.internal.http2.Http2.frameLog;
import static okhttp3.internal.framed.Http2.ioException; import static okhttp3.internal.http2.Http2.ioException;
import static okio.ByteString.EMPTY; import static okio.ByteString.EMPTY;
/** /**
* Reads transport frames for HTTP/2. * Reads HTTP/2 transport frames.
* *
* <p>This implementation assumes we do not send an increased {@link Settings#getMaxFrameSize frame * <p>This implementation assumes we do not send an increased {@link Settings#getMaxFrameSize frame
* size setting} to the peer. Hence, we expect all frames to have a max length of {@link * size setting} to the peer. Hence, we expect all frames to have a max length of {@link
* Http2#INITIAL_MAX_FRAME_SIZE}. * Http2#INITIAL_MAX_FRAME_SIZE}.
*/ */
final class FrameReader implements Closeable { final class Http2Reader implements Closeable {
private static final Logger logger = Logger.getLogger(FrameLogger.class.getName()); private static final Logger logger = Logger.getLogger(Http2.class.getName());
private final BufferedSource source; private final BufferedSource source;
private final ContinuationSource continuation; private final ContinuationSource continuation;
@@ -67,7 +67,7 @@ final class FrameReader implements Closeable {
final Hpack.Reader hpackReader; final Hpack.Reader hpackReader;
/** Creates a frame reader with max header table size of 4096. */ /** Creates a frame reader with max header table size of 4096. */
public FrameReader(BufferedSource source, boolean client) { public Http2Reader(BufferedSource source, boolean client) {
this.source = source; this.source = source;
this.client = client; this.client = client;
this.continuation = new ContinuationSource(this.source); this.continuation = new ContinuationSource(this.source);
@@ -109,7 +109,7 @@ final class FrameReader implements Closeable {
byte type = (byte) (source.readByte() & 0xff); byte type = (byte) (source.readByte() & 0xff);
byte flags = (byte) (source.readByte() & 0xff); byte flags = (byte) (source.readByte() & 0xff);
int streamId = (source.readInt() & 0x7fffffff); // Ignore reserved bit. int streamId = (source.readInt() & 0x7fffffff); // Ignore reserved bit.
if (logger.isLoggable(FINE)) logger.fine(formatHeader(true, streamId, length, type, flags)); if (logger.isLoggable(FINE)) logger.fine(frameLog(true, streamId, length, type, flags));
switch (type) { switch (type) {
case TYPE_DATA: case TYPE_DATA:
@@ -377,7 +377,7 @@ final class FrameReader implements Closeable {
length = left = readMedium(source); length = left = readMedium(source);
byte type = (byte) (source.readByte() & 0xff); byte type = (byte) (source.readByte() & 0xff);
flags = (byte) (source.readByte() & 0xff); flags = (byte) (source.readByte() & 0xff);
if (logger.isLoggable(FINE)) logger.fine(formatHeader(true, streamId, length, type, flags)); if (logger.isLoggable(FINE)) logger.fine(frameLog(true, streamId, length, type, flags));
streamId = (source.readInt() & 0x7fffffff); streamId = (source.readInt() & 0x7fffffff);
if (type != TYPE_CONTINUATION) throw ioException("%s != TYPE_CONTINUATION", type); if (type != TYPE_CONTINUATION) throw ioException("%s != TYPE_CONTINUATION", type);
if (streamId != previousStreamId) throw ioException("TYPE_CONTINUATION streamId changed"); if (streamId != previousStreamId) throw ioException("TYPE_CONTINUATION streamId changed");

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
@@ -29,7 +29,7 @@ import okio.Source;
import okio.Timeout; import okio.Timeout;
/** A logical bidirectional stream. */ /** A logical bidirectional stream. */
public final class FramedStream { public final class Http2Stream {
// Internal state is guarded by this. No long-running or potentially // Internal state is guarded by this. No long-running or potentially
// blocking operations are performed while the lock is held. // blocking operations are performed while the lock is held.
@@ -49,7 +49,7 @@ public final class FramedStream {
long bytesLeftInWriteWindow; long bytesLeftInWriteWindow;
private final int id; private final int id;
private final FramedConnection connection; private final Http2Connection connection;
/** Headers sent by the stream initiator. Immutable and non null. */ /** Headers sent by the stream initiator. Immutable and non null. */
private final List<Header> requestHeaders; private final List<Header> requestHeaders;
@@ -69,7 +69,7 @@ public final class FramedStream {
*/ */
private ErrorCode errorCode = null; private ErrorCode errorCode = null;
FramedStream(int id, FramedConnection connection, boolean outFinished, boolean inFinished, Http2Stream(int id, Http2Connection connection, boolean outFinished, boolean inFinished,
List<Header> requestHeaders) { List<Header> requestHeaders) {
if (connection == null) throw new NullPointerException("connection == null"); if (connection == null) throw new NullPointerException("connection == null");
if (requestHeaders == null) throw new NullPointerException("requestHeaders == null"); if (requestHeaders == null) throw new NullPointerException("requestHeaders == null");
@@ -118,7 +118,7 @@ public final class FramedStream {
return connection.client == streamIsClient; return connection.client == streamIsClient;
} }
public FramedConnection getConnection() { public Http2Connection getConnection() {
return connection; return connection;
} }
@@ -158,7 +158,7 @@ public final class FramedStream {
* Corresponds to {@code FLAG_FIN}. * Corresponds to {@code FLAG_FIN}.
*/ */
public void reply(List<Header> responseHeaders, boolean out) throws IOException { public void reply(List<Header> responseHeaders, boolean out) throws IOException {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
boolean outFinished = false; boolean outFinished = false;
synchronized (this) { synchronized (this) {
if (responseHeaders == null) { if (responseHeaders == null) {
@@ -248,7 +248,7 @@ public final class FramedStream {
} }
void receiveHeaders(List<Header> headers) { void receiveHeaders(List<Header> headers) {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
boolean open = true; boolean open = true;
synchronized (this) { synchronized (this) {
if (responseHeaders == null) { if (responseHeaders == null) {
@@ -268,12 +268,12 @@ public final class FramedStream {
} }
void receiveData(BufferedSource in, int length) throws IOException { void receiveData(BufferedSource in, int length) throws IOException {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
this.source.receive(in, length); this.source.receive(in, length);
} }
void receiveFin() { void receiveFin() {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
boolean open; boolean open;
synchronized (this) { synchronized (this) {
this.source.finished = true; this.source.finished = true;
@@ -325,7 +325,7 @@ public final class FramedStream {
if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
long read; long read;
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
waitUntilReadable(); waitUntilReadable();
checkNotClosed(); checkNotClosed();
if (readBuffer.size() == 0) return -1; // This source is exhausted. if (readBuffer.size() == 0) return -1; // This source is exhausted.
@@ -368,12 +368,12 @@ public final class FramedStream {
} }
void receive(BufferedSource in, long byteCount) throws IOException { void receive(BufferedSource in, long byteCount) throws IOException {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
while (byteCount > 0) { while (byteCount > 0) {
boolean finished; boolean finished;
boolean flowControlError; boolean flowControlError;
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
finished = this.finished; finished = this.finished;
flowControlError = byteCount + readBuffer.size() > maxByteCount; flowControlError = byteCount + readBuffer.size() > maxByteCount;
} }
@@ -397,11 +397,11 @@ public final class FramedStream {
byteCount -= read; byteCount -= read;
// Move the received data to the read buffer to the reader can read it. // Move the received data to the read buffer to the reader can read it.
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
boolean wasEmpty = readBuffer.size() == 0; boolean wasEmpty = readBuffer.size() == 0;
readBuffer.writeAll(receiveBuffer); readBuffer.writeAll(receiveBuffer);
if (wasEmpty) { if (wasEmpty) {
FramedStream.this.notifyAll(); Http2Stream.this.notifyAll();
} }
} }
} }
@@ -412,10 +412,10 @@ public final class FramedStream {
} }
@Override public void close() throws IOException { @Override public void close() throws IOException {
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
closed = true; closed = true;
readBuffer.clear(); readBuffer.clear();
FramedStream.this.notifyAll(); Http2Stream.this.notifyAll();
} }
cancelStreamIfNecessary(); cancelStreamIfNecessary();
} }
@@ -431,7 +431,7 @@ public final class FramedStream {
} }
private void cancelStreamIfNecessary() throws IOException { private void cancelStreamIfNecessary() throws IOException {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
boolean open; boolean open;
boolean cancel; boolean cancel;
synchronized (this) { synchronized (this) {
@@ -443,7 +443,7 @@ public final class FramedStream {
// is safe because the input stream is closed (we won't use any // is safe because the input stream is closed (we won't use any
// further bytes) and the output stream is either finished or closed // further bytes) and the output stream is either finished or closed
// (so RSTing both streams doesn't cause harm). // (so RSTing both streams doesn't cause harm).
FramedStream.this.close(ErrorCode.CANCEL); Http2Stream.this.close(ErrorCode.CANCEL);
} else if (!open) { } else if (!open) {
connection.removeStream(id); connection.removeStream(id);
} }
@@ -469,7 +469,7 @@ public final class FramedStream {
private boolean finished; private boolean finished;
@Override public void write(Buffer source, long byteCount) throws IOException { @Override public void write(Buffer source, long byteCount) throws IOException {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
sendBuffer.write(source, byteCount); sendBuffer.write(source, byteCount);
while (sendBuffer.size() >= EMIT_BUFFER_SIZE) { while (sendBuffer.size() >= EMIT_BUFFER_SIZE) {
emitDataFrame(false); emitDataFrame(false);
@@ -482,7 +482,7 @@ public final class FramedStream {
*/ */
private void emitDataFrame(boolean outFinished) throws IOException { private void emitDataFrame(boolean outFinished) throws IOException {
long toWrite; long toWrite;
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
writeTimeout.enter(); writeTimeout.enter();
try { try {
while (bytesLeftInWriteWindow <= 0 && !finished && !closed && errorCode == null) { while (bytesLeftInWriteWindow <= 0 && !finished && !closed && errorCode == null) {
@@ -506,8 +506,8 @@ public final class FramedStream {
} }
@Override public void flush() throws IOException { @Override public void flush() throws IOException {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
checkOutNotClosed(); checkOutNotClosed();
} }
while (sendBuffer.size() > 0) { while (sendBuffer.size() > 0) {
@@ -521,8 +521,8 @@ public final class FramedStream {
} }
@Override public void close() throws IOException { @Override public void close() throws IOException {
assert (!Thread.holdsLock(FramedStream.this)); assert (!Thread.holdsLock(Http2Stream.this));
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
if (closed) return; if (closed) return;
} }
if (!sink.finished) { if (!sink.finished) {
@@ -536,7 +536,7 @@ public final class FramedStream {
connection.writeData(id, true, null, 0); connection.writeData(id, true, null, 0);
} }
} }
synchronized (FramedStream.this) { synchronized (Http2Stream.this) {
closed = true; closed = true;
} }
connection.flush(); connection.flush();
@@ -549,7 +549,7 @@ public final class FramedStream {
*/ */
void addBytesToWriteWindow(long delta) { void addBytesToWriteWindow(long delta) {
bytesLeftInWriteWindow += delta; bytesLeftInWriteWindow += delta;
if (delta > 0) FramedStream.this.notifyAll(); if (delta > 0) Http2Stream.this.notifyAll();
} }
private void checkOutNotClosed() throws IOException { private void checkOutNotClosed() throws IOException {

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
@@ -24,27 +24,27 @@ import okio.BufferedSink;
import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINE;
import static okhttp3.internal.Util.format; import static okhttp3.internal.Util.format;
import static okhttp3.internal.framed.FrameLogger.formatHeader; import static okhttp3.internal.http2.Http2.CONNECTION_PREFACE;
import static okhttp3.internal.framed.Http2.CONNECTION_PREFACE; import static okhttp3.internal.http2.Http2.FLAG_ACK;
import static okhttp3.internal.framed.Http2.FLAG_ACK; import static okhttp3.internal.http2.Http2.FLAG_END_HEADERS;
import static okhttp3.internal.framed.Http2.FLAG_END_HEADERS; import static okhttp3.internal.http2.Http2.FLAG_END_STREAM;
import static okhttp3.internal.framed.Http2.FLAG_END_STREAM; import static okhttp3.internal.http2.Http2.FLAG_NONE;
import static okhttp3.internal.framed.Http2.FLAG_NONE; import static okhttp3.internal.http2.Http2.INITIAL_MAX_FRAME_SIZE;
import static okhttp3.internal.framed.Http2.INITIAL_MAX_FRAME_SIZE; import static okhttp3.internal.http2.Http2.TYPE_CONTINUATION;
import static okhttp3.internal.framed.Http2.TYPE_CONTINUATION; import static okhttp3.internal.http2.Http2.TYPE_DATA;
import static okhttp3.internal.framed.Http2.TYPE_DATA; import static okhttp3.internal.http2.Http2.TYPE_GOAWAY;
import static okhttp3.internal.framed.Http2.TYPE_GOAWAY; import static okhttp3.internal.http2.Http2.TYPE_HEADERS;
import static okhttp3.internal.framed.Http2.TYPE_HEADERS; import static okhttp3.internal.http2.Http2.TYPE_PING;
import static okhttp3.internal.framed.Http2.TYPE_PING; import static okhttp3.internal.http2.Http2.TYPE_PUSH_PROMISE;
import static okhttp3.internal.framed.Http2.TYPE_PUSH_PROMISE; import static okhttp3.internal.http2.Http2.TYPE_RST_STREAM;
import static okhttp3.internal.framed.Http2.TYPE_RST_STREAM; import static okhttp3.internal.http2.Http2.TYPE_SETTINGS;
import static okhttp3.internal.framed.Http2.TYPE_SETTINGS; import static okhttp3.internal.http2.Http2.TYPE_WINDOW_UPDATE;
import static okhttp3.internal.framed.Http2.TYPE_WINDOW_UPDATE; import static okhttp3.internal.http2.Http2.frameLog;
import static okhttp3.internal.framed.Http2.illegalArgument; import static okhttp3.internal.http2.Http2.illegalArgument;
/** Writes transport frames for HTTP/2. */ /** Writes HTTP/2 transport frames. */
public final class FrameWriter implements Closeable { final class Http2Writer implements Closeable {
private static final Logger logger = Logger.getLogger(FrameLogger.class.getName()); private static final Logger logger = Logger.getLogger(Http2.class.getName());
private final BufferedSink sink; private final BufferedSink sink;
private final boolean client; private final boolean client;
@@ -54,7 +54,7 @@ public final class FrameWriter implements Closeable {
final Hpack.Writer hpackWriter; final Hpack.Writer hpackWriter;
public FrameWriter(BufferedSink sink, boolean client) { public Http2Writer(BufferedSink sink, boolean client) {
this.sink = sink; this.sink = sink;
this.client = client; this.client = client;
this.hpackBuffer = new Buffer(); this.hpackBuffer = new Buffer();
@@ -263,7 +263,7 @@ public final class FrameWriter implements Closeable {
} }
public void frameHeader(int streamId, int length, byte type, byte flags) throws IOException { public void frameHeader(int streamId, int length, byte type, byte flags) throws IOException {
if (logger.isLoggable(FINE)) logger.fine(formatHeader(false, streamId, length, type, flags)); if (logger.isLoggable(FINE)) logger.fine(frameLog(false, streamId, length, type, flags));
if (length > maxFrameSize) { if (length > maxFrameSize) {
throw illegalArgument("FRAME_SIZE_ERROR length > %d: %d", maxFrameSize, length); throw illegalArgument("FRAME_SIZE_ERROR length > %d: %d", maxFrameSize, length);
} }

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -21,7 +21,7 @@ import java.util.concurrent.TimeUnit;
/** /**
* A locally-originated ping. * A locally-originated ping.
*/ */
public final class Ping { final class Ping {
private final CountDownLatch latch = new CountDownLatch(1); private final CountDownLatch latch = new CountDownLatch(1);
private long sent = -1; private long sent = -1;
private long received = -1; private long received = -1;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;

View File

@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.util.Arrays; import java.util.Arrays;
/** /**
* Settings describe characteristics of the sending peer, which are used by the receiving peer. * Settings describe characteristics of the sending peer, which are used by the receiving peer.
* Settings are {@link FramedConnection connection} scoped. * Settings are {@link Http2Connection connection} scoped.
*/ */
public final class Settings { public final class Settings {
/** /**

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package okhttp3.internal.framed; package okhttp3.internal.http2;
import java.io.IOException; import java.io.IOException;