1
0
mirror of https://github.com/square/okhttp.git synced 2026-01-21 03:41:07 +03:00

Merge pull request #612 from square/okhttp_15_jwilson_strip_20_apis

Strip 2.0 APIs from the 1.5 branch.
This commit is contained in:
Jake Wharton
2014-03-07 11:23:32 -08:00
100 changed files with 238 additions and 2173 deletions

View File

@@ -22,12 +22,6 @@ enum Client {
}
},
OkHttpAsync {
@Override HttpClient create() {
return new OkHttpAsync();
}
},
Apache {
@Override HttpClient create() {
return new ApacheHttpClient();

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) 2014 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 com.squareup.okhttp.benchmarks;
import com.squareup.okhttp.Dispatcher;
import com.squareup.okhttp.Failure;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.SslContextBuilder;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
class OkHttpAsync implements HttpClient {
private static final boolean VERBOSE = false;
private final AtomicInteger requestsInFlight = new AtomicInteger();
private OkHttpClient client;
private Response.Receiver receiver;
private int concurrencyLevel;
private int targetBacklog;
@Override public void prepare(final Benchmark benchmark) {
concurrencyLevel = benchmark.concurrencyLevel;
targetBacklog = benchmark.targetBacklog;
client = new OkHttpClient();
client.setProtocols(benchmark.protocols);
client.setDispatcher(new Dispatcher(new ThreadPoolExecutor(benchmark.concurrencyLevel,
benchmark.concurrencyLevel, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>())));
if (benchmark.tls) {
SSLContext sslContext = SslContextBuilder.localhost();
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession session) {
return true;
}
};
client.setSslSocketFactory(socketFactory);
client.setHostnameVerifier(hostnameVerifier);
}
receiver = new Response.Receiver() {
@Override public void onFailure(Failure failure) {
System.out.println("Failed: " + failure.exception());
}
@Override public boolean onResponse(Response response) throws IOException {
Response.Body body = response.body();
long total = SynchronousHttpClient.readAllAndClose(body.byteStream());
long finish = System.nanoTime();
if (VERBOSE) {
long start = (Long) response.request().tag();
System.out.printf("Transferred % 8d bytes in %4d ms%n",
total, TimeUnit.NANOSECONDS.toMillis(finish - start));
}
requestsInFlight.decrementAndGet();
return true;
}
};
}
@Override public void enqueue(URL url) throws Exception {
requestsInFlight.incrementAndGet();
client.enqueue(new Request.Builder().tag(System.nanoTime()).url(url).build(), receiver);
}
@Override public synchronized boolean acceptingJobs() {
return requestsInFlight.get() < (concurrencyLevel + targetBacklog);
}
}

View File

@@ -19,6 +19,8 @@ package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.SslContextBuilder;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.Okio;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -29,8 +31,6 @@ import java.util.Arrays;
import java.util.List;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import okio.BufferedSink;
import okio.Okio;
import org.eclipse.jetty.npn.NextProtoNego;
import static com.squareup.okhttp.internal.Util.headerEntries;

View File

@@ -21,6 +21,10 @@ import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.NamedRunnable;
import com.squareup.okhttp.internal.Platform;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.spdy.ErrorCode;
import com.squareup.okhttp.internal.spdy.Header;
import com.squareup.okhttp.internal.spdy.IncomingStreamHandler;
@@ -63,10 +67,6 @@ import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okio.BufferedSink;
import okio.ByteString;
import okio.OkBuffer;
import okio.Okio;
import static com.squareup.okhttp.mockwebserver.SocketPolicy.DISCONNECT_AT_START;
import static com.squareup.okhttp.mockwebserver.SocketPolicy.FAIL_HANDSHAKE;
@@ -110,7 +110,7 @@ public final class MockWebServer {
private int port = -1;
private boolean npnEnabled = true;
private List<Protocol> npnProtocols = Protocol.HTTP2_SPDY3_AND_HTTP;
private List<Protocol> npnProtocols = Util.HTTP2_SPDY3_AND_HTTP;
public int getPort() {
if (port == -1) throw new IllegalStateException("Cannot retrieve port before calling play()");
@@ -334,7 +334,7 @@ public final class MockWebServer {
if (npnEnabled) {
ByteString selectedProtocol = Platform.get().getNpnSelectedProtocol(sslSocket);
protocol = Protocol.find(selectedProtocol);
protocol = Util.getProtocol(selectedProtocol);
}
openClientSockets.remove(raw);
} else {

View File

@@ -1,7 +0,0 @@
OkCurl
======
_A curl for the next-generation web._
OkCurl is an OkHttp-backed curl clone which allows you to test OkHttp's HTTP engine (including
SPDY and HTTP/2) against web servers.

View File

@@ -1,94 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.squareup.okhttp</groupId>
<artifactId>parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<artifactId>okcurl</artifactId>
<name>OkCurl</name>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.mortbay.jetty.npn</groupId>
<artifactId>npn-boot</artifactId>
</dependency>
<dependency>
<groupId>io.airlift</groupId>
<artifactId>airline</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.squareup.okhttp.curl.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.skife.maven</groupId>
<artifactId>really-executable-jar-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>really-executable-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<flags>-Xbootclasspath/p:$0</flags>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,254 +0,0 @@
/*
* Copyright (C) 2014 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 com.squareup.okhttp.curl;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.squareup.okhttp.ConnectionPool;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import io.airlift.command.Arguments;
import io.airlift.command.Command;
import io.airlift.command.HelpOption;
import io.airlift.command.Option;
import io.airlift.command.SingleCommand;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import static java.util.concurrent.TimeUnit.SECONDS;
@Command(name = Main.NAME, description = "A curl for the next-generation web.")
public class Main extends HelpOption implements Runnable {
static final String NAME = "okcurl";
static final int DEFAULT_TIMEOUT = -1;
static Main fromArgs(String... args) {
return SingleCommand.singleCommand(Main.class).parse(args);
}
public static void main(String... args) {
fromArgs(args).run();
}
private static String versionString() {
try {
Properties prop = new Properties();
InputStream in = Main.class.getResourceAsStream("/okcurl-version.properties");
prop.load(in);
in.close();
return prop.getProperty("version");
} catch (IOException e) {
throw new AssertionError("Could not load okcurl-version.properties.");
}
}
private static String protocols() {
return Joiner.on(", ").join(Lists.transform(Arrays.asList(Protocol.values()),
new Function<Protocol, String>() {
@Override public String apply(Protocol protocol) {
return protocol.name.utf8();
}
}));
}
@Option(name = { "-X", "--request" }, description = "Specify request command to use")
public String method;
@Option(name = { "-d", "--data" }, description = "HTTP POST data")
public String data;
@Option(name = { "-H", "--header" }, description = "Custom header to pass to server")
public List<String> headers;
@Option(name = { "-A", "--user-agent" }, description = "User-Agent to send to server")
public String userAgent = NAME + "/" + versionString();
@Option(name = "--connect-timeout", description = "Maximum time allowed for connection (seconds)")
public int connectTimeout = DEFAULT_TIMEOUT;
@Option(name = "--read-timeout", description = "Maximum time allowed for reading data (seconds)")
public int readTimeout = DEFAULT_TIMEOUT;
@Option(name = { "-L", "--location" }, description = "Follow redirects")
public boolean followRedirects;
@Option(name = { "-k", "--insecure" },
description = "Allow connections to SSL sites without certs")
public boolean allowInsecure;
@Option(name = { "-i", "--include" }, description = "Include protocol headers in the output")
public boolean showHeaders;
@Option(name = { "-e", "--referer" }, description = "Referer URL")
public String referer;
@Option(name = { "-V", "--version" }, description = "Show version number and quit")
public boolean version;
@Arguments(title = "url", description = "Remote resource URL")
public String url;
private OkHttpClient client;
@Override public void run() {
if (showHelpIfRequested()) {
return;
}
if (version) {
System.out.println(NAME + " " + versionString());
System.out.println("Protocols: " + protocols());
return;
}
client = createClient();
Request request = createRequest();
try {
Response response = client.execute(request);
if (showHeaders) {
System.out.println(response.statusLine());
Headers headers = response.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
System.out.println(headers.name(i) + ": " + headers.value(i));
}
System.out.println();
}
Response.Body body = response.body();
byte[] buffer = new byte[1024];
while (body.ready()) {
int c = body.byteStream().read(buffer);
if (c == -1) {
return;
}
System.out.write(buffer, 0, c);
}
body.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
close();
}
}
private OkHttpClient createClient() {
OkHttpClient client = new OkHttpClient();
client.setFollowProtocolRedirects(followRedirects);
if (connectTimeout != DEFAULT_TIMEOUT) {
client.setConnectTimeout(connectTimeout, SECONDS);
}
if (readTimeout != DEFAULT_TIMEOUT) {
client.setReadTimeout(readTimeout, SECONDS);
}
if (allowInsecure) {
client.setSslSocketFactory(createInsecureSslSocketFactory());
}
// If we don't set this reference, there's no way to clean shutdown persistent connections.
client.setConnectionPool(ConnectionPool.getDefault());
return client;
}
private String getRequestMethod() {
if (method != null) {
return method;
}
if (data != null) {
return "POST";
}
return "GET";
}
private Request.Body getRequestBody() {
if (data == null) {
return null;
}
String bodyData = data;
String mimeType = "application/x-form-urlencoded";
if (headers != null) {
for (String header : headers) {
String[] parts = header.split(":", -1);
if ("Content-Type".equalsIgnoreCase(parts[0])) {
mimeType = parts[1].trim();
headers.remove(header);
break;
}
}
}
return Request.Body.create(MediaType.parse(mimeType), bodyData);
}
Request createRequest() {
Request.Builder request = new Request.Builder();
request.url(url);
request.method(getRequestMethod(), getRequestBody());
if (headers != null) {
for (String header : headers) {
String[] parts = header.split(":", -1);
request.header(parts[0], parts[1]);
}
}
if (referer != null) {
request.header("Referer", referer);
}
request.header("User-Agent", userAgent);
return request.build();
}
private void close() {
client.getConnectionPool().evictAll(); // Close any persistent connections.
}
private static SSLSocketFactory createInsecureSslSocketFactory() {
try {
SSLContext context = SSLContext.getInstance("TLS");
TrustManager permissive = new X509TrustManager() {
@Override public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
context.init(null, new TrustManager[] { permissive }, null);
return context.getSocketFactory();
} catch (Exception e) {
throw new AssertionError(e);
}
}
}

View File

@@ -1 +0,0 @@
version=${project.version}

View File

@@ -1,96 +0,0 @@
/*
* Copyright (C) 2014 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 com.squareup.okhttp.curl;
import com.squareup.okhttp.Request;
import java.io.IOException;
import okio.OkBuffer;
import org.junit.Test;
import static com.squareup.okhttp.curl.Main.fromArgs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class MainTest {
@Test public void simple() {
Request request = fromArgs("http://example.com").createRequest();
assertEquals("GET", request.method());
assertEquals("http://example.com", request.urlString());
assertNull(request.body());
}
@Test public void put() {
Request request = fromArgs("-X", "PUT", "http://example.com").createRequest();
assertEquals("PUT", request.method());
assertEquals("http://example.com", request.urlString());
assertNull(request.body());
}
@Test public void dataPost() {
Request request = fromArgs("-d", "foo", "http://example.com").createRequest();
Request.Body body = request.body();
assertEquals("POST", request.method());
assertEquals("http://example.com", request.urlString());
assertEquals("application/x-form-urlencoded; charset=utf-8", body.contentType().toString());
assertEquals("foo", bodyAsString(body));
}
@Test public void dataPut() {
Request request = fromArgs("-d", "foo", "-X", "PUT", "http://example.com").createRequest();
Request.Body body = request.body();
assertEquals("PUT", request.method());
assertEquals("http://example.com", request.urlString());
assertEquals("application/x-form-urlencoded; charset=utf-8", body.contentType().toString());
assertEquals("foo", bodyAsString(body));
}
@Test public void contentTypeHeader() {
Request request = fromArgs("-d", "foo", "-H", "Content-Type: application/json",
"http://example.com").createRequest();
Request.Body body = request.body();
assertEquals("POST", request.method());
assertEquals("http://example.com", request.urlString());
assertEquals("application/json; charset=utf-8", body.contentType().toString());
assertEquals("foo", bodyAsString(body));
}
@Test public void referer() {
Request request = fromArgs("-e", "foo", "http://example.com").createRequest();
assertEquals("GET", request.method());
assertEquals("http://example.com", request.urlString());
assertEquals("foo", request.header("Referer"));
assertNull(request.body());
}
@Test public void userAgent() {
Request request = fromArgs("-A", "foo", "http://example.com").createRequest();
assertEquals("GET", request.method());
assertEquals("http://example.com", request.urlString());
assertEquals("foo", request.header("User-Agent"));
assertNull(request.body());
}
private static String bodyAsString(Request.Body body) {
try {
OkBuffer buffer = new OkBuffer();
body.writeTo(buffer);
return new String(buffer.readByteString(buffer.size()).toByteArray(),
body.contentType().charset());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,371 +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 com.squareup.okhttp;
import com.squareup.okhttp.internal.RecordingHostnameVerifier;
import com.squareup.okhttp.internal.SslContextBuilder;
import com.squareup.okhttp.mockwebserver.Dispatcher;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import com.squareup.okhttp.mockwebserver.SocketPolicy;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.SSLContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public final class AsyncApiTest {
private MockWebServer server = new MockWebServer();
private OkHttpClient client = new OkHttpClient();
private RecordingReceiver receiver = new RecordingReceiver();
private static final SSLContext sslContext = SslContextBuilder.localhost();
private HttpResponseCache cache;
@Before public void setUp() throws Exception {
String tmp = System.getProperty("java.io.tmpdir");
File cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID());
cache = new HttpResponseCache(cacheDir, Integer.MAX_VALUE);
}
@After public void tearDown() throws Exception {
server.shutdown();
cache.delete();
}
@Test public void get() throws Exception {
server.enqueue(new MockResponse()
.setBody("abc")
.addHeader("Content-Type: text/plain"));
server.play();
Request request = new Request.Builder()
.url(server.getUrl("/"))
.header("User-Agent", "AsyncApiTest")
.build();
client.enqueue(request, receiver);
receiver.await(request.url())
.assertCode(200)
.assertContainsHeaders("Content-Type: text/plain")
.assertBody("abc");
assertTrue(server.takeRequest().getHeaders().contains("User-Agent: AsyncApiTest"));
}
@Test public void connectionPooling() throws Exception {
server.enqueue(new MockResponse().setBody("abc"));
server.enqueue(new MockResponse().setBody("def"));
server.enqueue(new MockResponse().setBody("ghi"));
server.play();
client.enqueue(new Request.Builder().url(server.getUrl("/a")).build(), receiver);
receiver.await(server.getUrl("/a")).assertBody("abc");
client.enqueue(new Request.Builder().url(server.getUrl("/b")).build(), receiver);
receiver.await(server.getUrl("/b")).assertBody("def");
client.enqueue(new Request.Builder().url(server.getUrl("/c")).build(), receiver);
receiver.await(server.getUrl("/c")).assertBody("ghi");
assertEquals(0, server.takeRequest().getSequenceNumber());
assertEquals(1, server.takeRequest().getSequenceNumber());
assertEquals(2, server.takeRequest().getSequenceNumber());
}
@Test public void tls() throws Exception {
server.useHttps(sslContext.getSocketFactory(), false);
server.enqueue(new MockResponse()
.setBody("abc")
.addHeader("Content-Type: text/plain"));
server.play();
client.setSslSocketFactory(sslContext.getSocketFactory());
client.setHostnameVerifier(new RecordingHostnameVerifier());
Request request = new Request.Builder()
.url(server.getUrl("/"))
.build();
client.enqueue(request, receiver);
receiver.await(request.url()).assertHandshake();
}
@Test public void recoverFromTlsHandshakeFailure() throws Exception {
server.useHttps(sslContext.getSocketFactory(), false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setBody("abc"));
server.play();
client.setSslSocketFactory(sslContext.getSocketFactory());
client.setHostnameVerifier(new RecordingHostnameVerifier());
Request request = new Request.Builder()
.url(server.getUrl("/"))
.build();
client.enqueue(request, receiver);
receiver.await(request.url()).assertBody("abc");
}
@Test public void post() throws Exception {
server.enqueue(new MockResponse().setBody("abc"));
server.play();
Request request = new Request.Builder()
.url(server.getUrl("/"))
.post(Request.Body.create(MediaType.parse("text/plain"), "def"))
.build();
client.enqueue(request, receiver);
receiver.await(request.url())
.assertCode(200)
.assertBody("abc");
RecordedRequest recordedRequest = server.takeRequest();
assertEquals("def", recordedRequest.getUtf8Body());
assertEquals("3", recordedRequest.getHeader("Content-Length"));
assertEquals("text/plain; charset=utf-8", recordedRequest.getHeader("Content-Type"));
}
@Test public void cache() throws Exception {
server.enqueue(new MockResponse().setBody("A").addHeader("ETag: v1"));
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_NOT_MODIFIED));
server.play();
client.setOkResponseCache(cache);
Request request1 = new Request.Builder()
.url(server.getUrl("/"))
.build();
client.enqueue(request1, receiver);
receiver.await(request1.url()).assertCode(200).assertBody("A");
assertNull(server.takeRequest().getHeader("If-None-Match"));
Request request2 = new Request.Builder()
.url(server.getUrl("/"))
.build();
client.enqueue(request2, receiver);
receiver.await(request2.url()).assertCode(200).assertBody("A");
assertEquals("v1", server.takeRequest().getHeader("If-None-Match"));
}
@Test public void redirect() throws Exception {
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /b")
.addHeader("Test", "Redirect from /a to /b")
.setBody("/a has moved!"));
server.enqueue(new MockResponse()
.setResponseCode(302)
.addHeader("Location: /c")
.addHeader("Test", "Redirect from /b to /c")
.setBody("/b has moved!"));
server.enqueue(new MockResponse().setBody("C"));
server.play();
Request request = new Request.Builder().url(server.getUrl("/a")).build();
client.enqueue(request, receiver);
receiver.await(server.getUrl("/c"))
.assertCode(200)
.assertBody("C")
.redirectedBy()
.assertCode(302)
.assertContainsHeaders("Test: Redirect from /b to /c")
.redirectedBy()
.assertCode(301)
.assertContainsHeaders("Test: Redirect from /a to /b");
assertEquals(0, server.takeRequest().getSequenceNumber()); // New connection.
assertEquals(1, server.takeRequest().getSequenceNumber()); // Connection reused.
assertEquals(2, server.takeRequest().getSequenceNumber()); // Connection reused again!
}
@Test public void redirectWithRedirectsDisabled() throws Exception {
client.setFollowProtocolRedirects(false);
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /b")
.addHeader("Test", "Redirect from /a to /b")
.setBody("/a has moved!"));
server.play();
Request request = new Request.Builder().url(server.getUrl("/a")).build();
client.enqueue(request, receiver);
receiver.await(server.getUrl("/a"))
.assertCode(301)
.assertBody("/a has moved!")
.assertContainsHeaders("Location: /b");
}
@Test public void follow20Redirects() throws Exception {
for (int i = 0; i < 20; i++) {
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /" + (i + 1))
.setBody("Redirecting to /" + (i + 1)));
}
server.enqueue(new MockResponse().setBody("Success!"));
server.play();
Request request = new Request.Builder().url(server.getUrl("/0")).build();
client.enqueue(request, receiver);
receiver.await(server.getUrl("/20"))
.assertCode(200)
.assertBody("Success!");
}
@Test public void doesNotFollow21Redirects() throws Exception {
for (int i = 0; i < 21; i++) {
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /" + (i + 1))
.setBody("Redirecting to /" + (i + 1)));
}
server.play();
Request request = new Request.Builder().url(server.getUrl("/0")).build();
client.enqueue(request, receiver);
receiver.await(server.getUrl("/20")).assertFailure("Too many redirects: 21");
}
@Test public void canceledBeforeResponseReadIsNeverDelivered() throws Exception {
client.getDispatcher().setMaxRequests(1); // Force requests to be executed serially.
server.setDispatcher(new Dispatcher() {
char nextResponse = 'A';
@Override public MockResponse dispatch(RecordedRequest request) {
client.cancel("request A");
return new MockResponse().setBody(Character.toString(nextResponse++));
}
});
server.play();
// Canceling a request after the server has received a request but before
// it has delivered the response. That request will never be received to the
// client.
Request requestA = new Request.Builder().url(server.getUrl("/a")).tag("request A").build();
client.enqueue(requestA, receiver);
assertEquals("/a", server.takeRequest().getPath());
// We then make a second request (not canceled) to make sure the receiver
// has nothing left to wait for.
Request requestB = new Request.Builder().url(server.getUrl("/b")).tag("request B").build();
client.enqueue(requestB, receiver);
assertEquals("/b", server.takeRequest().getPath());
receiver.await(requestB.url()).assertBody("B");
// At this point we know the receiver is ready: if it hasn't received 'A'
// yet it never will.
receiver.assertNoResponse(requestA.url());
}
@Test public void canceledAfterResponseIsDeliveredDoesNothing() throws Exception {
server.enqueue(new MockResponse().setBody("A"));
server.play();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<String> bodyRef = new AtomicReference<String>();
Request request = new Request.Builder().url(server.getUrl("/a")).tag("request A").build();
client.enqueue(request, new Response.Receiver() {
@Override public void onFailure(Failure failure) {
throw new AssertionError();
}
@Override public boolean onResponse(Response response) throws IOException {
client.cancel("request A");
bodyRef.set(response.body().string());
latch.countDown();
return true;
}
});
latch.await();
assertEquals("A", bodyRef.get());
}
@Test public void connectionReuseWhenResponseBodyConsumed() throws Exception {
server.enqueue(new MockResponse().setBody("abc"));
server.enqueue(new MockResponse().setBody("def"));
server.play();
Request request = new Request.Builder().url(server.getUrl("/a")).build();
client.enqueue(request, new Response.Receiver() {
@Override public void onFailure(Failure failure) {
throw new AssertionError();
}
@Override public boolean onResponse(Response response) throws IOException {
InputStream bytes = response.body().byteStream();
assertEquals('a', bytes.read());
assertEquals('b', bytes.read());
assertEquals('c', bytes.read());
// This request will share a connection with 'A' cause it's all done.
client.enqueue(new Request.Builder().url(server.getUrl("/b")).build(), receiver);
return true;
}
});
receiver.await(server.getUrl("/b")).assertCode(200).assertBody("def");
assertEquals(0, server.takeRequest().getSequenceNumber()); // New connection.
assertEquals(1, server.takeRequest().getSequenceNumber()); // Connection reuse!
}
@Test public void postBodyRetransmittedOnRedirect() throws Exception {
server.enqueue(new MockResponse()
.setResponseCode(302)
.addHeader("Location: /b")
.setBody("Moved to /b !"));
server.enqueue(new MockResponse()
.setBody("This is b."));
server.play();
Request request = new Request.Builder()
.url(server.getUrl("/"))
.post(Request.Body.create(MediaType.parse("text/plain"), "body!"))
.build();
client.enqueue(request, receiver);
receiver.await(server.getUrl("/b"))
.assertCode(200)
.assertBody("This is b.");
RecordedRequest request1 = server.takeRequest();
assertEquals("body!", request1.getUtf8Body());
assertEquals("5", request1.getHeader("Content-Length"));
assertEquals("text/plain; charset=utf-8", request1.getHeader("Content-Type"));
assertEquals(0, request1.getSequenceNumber());
RecordedRequest request2 = server.takeRequest();
assertEquals("body!", request2.getUtf8Body());
assertEquals("5", request2.getHeader("Content-Length"));
assertEquals("text/plain; charset=utf-8", request2.getHeader("Content-Type"));
assertEquals(1, request2.getSequenceNumber());
}
}

View File

@@ -61,14 +61,14 @@ public final class ConnectionPoolTest {
httpServer.play();
httpAddress = new Address(httpServer.getHostName(), httpServer.getPort(), null, null,
HttpAuthenticator.SYSTEM_DEFAULT, null, Protocol.SPDY3_AND_HTTP11);
HttpAuthenticator.SYSTEM_DEFAULT, null, Util.SPDY3_AND_HTTP11);
httpSocketAddress = new InetSocketAddress(InetAddress.getByName(httpServer.getHostName()),
httpServer.getPort());
spdyServer.play();
spdyAddress = new Address(spdyServer.getHostName(), spdyServer.getPort(),
sslContext.getSocketFactory(), new RecordingHostnameVerifier(),
HttpAuthenticator.SYSTEM_DEFAULT, null,Protocol.SPDY3_AND_HTTP11);
HttpAuthenticator.SYSTEM_DEFAULT, null, Util.SPDY3_AND_HTTP11);
spdySocketAddress = new InetSocketAddress(InetAddress.getByName(spdyServer.getHostName()),
spdyServer.getPort());

View File

@@ -1,189 +0,0 @@
package com.squareup.okhttp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public final class DispatcherTest {
RecordingExecutor executor = new RecordingExecutor();
RecordingReceiver receiver = new RecordingReceiver();
Dispatcher dispatcher = new Dispatcher(executor);
OkHttpClient client = new OkHttpClient().setDispatcher(dispatcher);
@Before public void setUp() throws Exception {
dispatcher.setMaxRequests(20);
dispatcher.setMaxRequestsPerHost(10);
}
@Test public void maxRequestsZero() throws Exception {
try {
dispatcher.setMaxRequests(0);
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test public void maxPerHostZero() throws Exception {
try {
dispatcher.setMaxRequestsPerHost(0);
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test public void enqueuedJobsRunImmediately() throws Exception {
client.enqueue(newRequest("http://a/1"), receiver);
executor.assertJobs("http://a/1");
}
@Test public void maxRequestsEnforced() throws Exception {
dispatcher.setMaxRequests(3);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://a/2"), receiver);
client.enqueue(newRequest("http://b/1"), receiver);
client.enqueue(newRequest("http://b/2"), receiver);
executor.assertJobs("http://a/1", "http://a/2", "http://b/1");
}
@Test public void maxPerHostEnforced() throws Exception {
dispatcher.setMaxRequestsPerHost(2);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://a/2"), receiver);
client.enqueue(newRequest("http://a/3"), receiver);
executor.assertJobs("http://a/1", "http://a/2");
}
@Test public void increasingMaxRequestsPromotesJobsImmediately() throws Exception {
dispatcher.setMaxRequests(2);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://b/1"), receiver);
client.enqueue(newRequest("http://c/1"), receiver);
client.enqueue(newRequest("http://a/2"), receiver);
client.enqueue(newRequest("http://b/2"), receiver);
dispatcher.setMaxRequests(4);
executor.assertJobs("http://a/1", "http://b/1", "http://c/1", "http://a/2");
}
@Test public void increasingMaxPerHostPromotesJobsImmediately() throws Exception {
dispatcher.setMaxRequestsPerHost(2);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://a/2"), receiver);
client.enqueue(newRequest("http://a/3"), receiver);
client.enqueue(newRequest("http://a/4"), receiver);
client.enqueue(newRequest("http://a/5"), receiver);
dispatcher.setMaxRequestsPerHost(4);
executor.assertJobs("http://a/1", "http://a/2", "http://a/3", "http://a/4");
}
@Test public void oldJobFinishesNewJobCanRunDifferentHost() throws Exception {
dispatcher.setMaxRequests(1);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://b/1"), receiver);
executor.finishJob("http://a/1");
executor.assertJobs("http://b/1");
}
@Test public void oldJobFinishesNewJobWithSameHostStarts() throws Exception {
dispatcher.setMaxRequests(2);
dispatcher.setMaxRequestsPerHost(1);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://b/1"), receiver);
client.enqueue(newRequest("http://b/2"), receiver);
client.enqueue(newRequest("http://a/2"), receiver);
executor.finishJob("http://a/1");
executor.assertJobs("http://b/1", "http://a/2");
}
@Test public void oldJobFinishesNewJobCantRunDueToHostLimit() throws Exception {
dispatcher.setMaxRequestsPerHost(1);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://b/1"), receiver);
client.enqueue(newRequest("http://a/2"), receiver);
executor.finishJob("http://b/1");
executor.assertJobs("http://a/1");
}
@Test public void cancelingReadyJobPreventsItFromStarting() throws Exception {
dispatcher.setMaxRequestsPerHost(1);
client.enqueue(newRequest("http://a/1"), receiver);
client.enqueue(newRequest("http://a/2", "tag1"), receiver);
dispatcher.cancel("tag1");
executor.finishJob("http://a/1");
executor.assertJobs();
}
@Test public void cancelingRunningJobTakesNoEffectUntilJobFinishes() throws Exception {
dispatcher.setMaxRequests(1);
client.enqueue(newRequest("http://a/1", "tag1"), receiver);
client.enqueue(newRequest("http://a/2"), receiver);
dispatcher.cancel("tag1");
executor.assertJobs("http://a/1");
executor.finishJob("http://a/1");
executor.assertJobs("http://a/2");
}
class RecordingExecutor extends AbstractExecutorService {
private List<Job> jobs = new ArrayList<Job>();
@Override public void execute(Runnable command) {
jobs.add((Job) command);
}
public void assertJobs(String... expectedUrls) {
List<String> actualUrls = new ArrayList<String>();
for (Job job : jobs) {
actualUrls.add(job.request().urlString());
}
assertEquals(Arrays.asList(expectedUrls), actualUrls);
}
public void finishJob(String url) {
for (Iterator<Job> i = jobs.iterator(); i.hasNext(); ) {
Job job = i.next();
if (job.request().urlString().equals(url)) {
i.remove();
dispatcher.finished(job);
return;
}
}
throw new AssertionError("No such job: " + url);
}
@Override public void shutdown() {
throw new UnsupportedOperationException();
}
@Override public List<Runnable> shutdownNow() {
throw new UnsupportedOperationException();
}
@Override public boolean isShutdown() {
throw new UnsupportedOperationException();
}
@Override public boolean isTerminated() {
throw new UnsupportedOperationException();
}
@Override public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
throw new UnsupportedOperationException();
}
}
private Request newRequest(String url) {
return new Request.Builder().url(url).build();
}
private Request newRequest(String url, String tag) {
return new Request.Builder().url(url).tag(tag).build();
}
}

View File

@@ -15,6 +15,10 @@
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.http.Failure;
import com.squareup.okhttp.internal.http.Headers;
import com.squareup.okhttp.internal.http.Request;
import com.squareup.okhttp.internal.http.Response;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

View File

@@ -15,6 +15,8 @@
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.http.Failure;
import com.squareup.okhttp.internal.http.Response;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;

View File

@@ -16,10 +16,11 @@
package com.squareup.okhttp;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.http.Request;
import com.squareup.okhttp.internal.okio.OkBuffer;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import okio.OkBuffer;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

View File

@@ -1,268 +0,0 @@
/*
* Copyright (C) 2014 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 com.squareup.okhttp;
import com.squareup.okhttp.internal.RecordingHostnameVerifier;
import com.squareup.okhttp.internal.SslContextBuilder;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import com.squareup.okhttp.mockwebserver.SocketPolicy;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.UUID;
import javax.net.ssl.SSLContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public final class SyncApiTest {
private MockWebServer server = new MockWebServer();
private OkHttpClient client = new OkHttpClient();
private static final SSLContext sslContext = SslContextBuilder.localhost();
private HttpResponseCache cache;
@Before public void setUp() throws Exception {
String tmp = System.getProperty("java.io.tmpdir");
File cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID());
cache = new HttpResponseCache(cacheDir, Integer.MAX_VALUE);
}
@After public void tearDown() throws Exception {
server.shutdown();
cache.delete();
}
@Test public void get() throws Exception {
server.enqueue(new MockResponse()
.setBody("abc")
.addHeader("Content-Type: text/plain"));
server.play();
Request request = new Request.Builder()
.url(server.getUrl("/"))
.header("User-Agent", "SyncApiTest")
.build();
onSuccess(request)
.assertCode(200)
.assertContainsHeaders("Content-Type: text/plain")
.assertBody("abc");
assertTrue(server.takeRequest().getHeaders().contains("User-Agent: SyncApiTest"));
}
@Test public void connectionPooling() throws Exception {
server.enqueue(new MockResponse().setBody("abc"));
server.enqueue(new MockResponse().setBody("def"));
server.enqueue(new MockResponse().setBody("ghi"));
server.play();
onSuccess(new Request.Builder().url(server.getUrl("/a")).build())
.assertBody("abc");
onSuccess(new Request.Builder().url(server.getUrl("/b")).build())
.assertBody("def");
onSuccess(new Request.Builder().url(server.getUrl("/c")).build())
.assertBody("ghi");
assertEquals(0, server.takeRequest().getSequenceNumber());
assertEquals(1, server.takeRequest().getSequenceNumber());
assertEquals(2, server.takeRequest().getSequenceNumber());
}
@Test public void tls() throws Exception {
server.useHttps(sslContext.getSocketFactory(), false);
server.enqueue(new MockResponse()
.setBody("abc")
.addHeader("Content-Type: text/plain"));
server.play();
client.setSslSocketFactory(sslContext.getSocketFactory());
client.setHostnameVerifier(new RecordingHostnameVerifier());
onSuccess(new Request.Builder().url(server.getUrl("/")).build())
.assertHandshake();
}
@Test public void recoverFromTlsHandshakeFailure() throws Exception {
server.useHttps(sslContext.getSocketFactory(), false);
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE));
server.enqueue(new MockResponse().setBody("abc"));
server.play();
client.setSslSocketFactory(sslContext.getSocketFactory());
client.setHostnameVerifier(new RecordingHostnameVerifier());
onSuccess(new Request.Builder().url(server.getUrl("/")).build())
.assertBody("abc");
}
@Test public void post() throws Exception {
server.enqueue(new MockResponse().setBody("abc"));
server.play();
Request request = new Request.Builder()
.url(server.getUrl("/"))
.post(Request.Body.create(MediaType.parse("text/plain"), "def"))
.build();
onSuccess(request)
.assertCode(200)
.assertBody("abc");
RecordedRequest recordedRequest = server.takeRequest();
assertEquals("def", recordedRequest.getUtf8Body());
assertEquals("3", recordedRequest.getHeader("Content-Length"));
assertEquals("text/plain; charset=utf-8", recordedRequest.getHeader("Content-Type"));
}
@Test public void cache() throws Exception {
server.enqueue(new MockResponse().setBody("A").addHeader("ETag: v1"));
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_NOT_MODIFIED));
server.play();
client.setOkResponseCache(cache);
onSuccess(new Request.Builder().url(server.getUrl("/")).build())
.assertCode(200).assertBody("A");
assertNull(server.takeRequest().getHeader("If-None-Match"));
onSuccess(new Request.Builder().url(server.getUrl("/")).build())
.assertCode(200).assertBody("A");
assertEquals("v1", server.takeRequest().getHeader("If-None-Match"));
}
@Test public void redirect() throws Exception {
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /b")
.addHeader("Test", "Redirect from /a to /b")
.setBody("/a has moved!"));
server.enqueue(new MockResponse()
.setResponseCode(302)
.addHeader("Location: /c")
.addHeader("Test", "Redirect from /b to /c")
.setBody("/b has moved!"));
server.enqueue(new MockResponse().setBody("C"));
server.play();
onSuccess(new Request.Builder().url(server.getUrl("/a")).build())
.assertCode(200)
.assertBody("C")
.redirectedBy()
.assertCode(302)
.assertContainsHeaders("Test: Redirect from /b to /c")
.redirectedBy()
.assertCode(301)
.assertContainsHeaders("Test: Redirect from /a to /b");
assertEquals(0, server.takeRequest().getSequenceNumber()); // New connection.
assertEquals(1, server.takeRequest().getSequenceNumber()); // Connection reused.
assertEquals(2, server.takeRequest().getSequenceNumber()); // Connection reused again!
}
@Test public void redirectWithRedirectsDisabled() throws Exception {
client.setFollowProtocolRedirects(false);
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /b")
.addHeader("Test", "Redirect from /a to /b")
.setBody("/a has moved!"));
server.play();
onSuccess(new Request.Builder().url(server.getUrl("/a")).build())
.assertCode(301)
.assertBody("/a has moved!")
.assertContainsHeaders("Location: /b");
}
@Test public void follow20Redirects() throws Exception {
for (int i = 0; i < 20; i++) {
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /" + (i + 1))
.setBody("Redirecting to /" + (i + 1)));
}
server.enqueue(new MockResponse().setBody("Success!"));
server.play();
onSuccess(new Request.Builder().url(server.getUrl("/0")).build())
.assertCode(200)
.assertBody("Success!");
}
@Test public void doesNotFollow21Redirects() throws Exception {
for (int i = 0; i < 21; i++) {
server.enqueue(new MockResponse()
.setResponseCode(301)
.addHeader("Location: /" + (i + 1))
.setBody("Redirecting to /" + (i + 1)));
}
server.play();
try {
client.execute(new Request.Builder().url(server.getUrl("/0")).build());
fail();
} catch (IOException e) {
assertEquals("Too many redirects: 21", e.getMessage());
}
}
@Test public void postBodyRetransmittedOnRedirect() throws Exception {
server.enqueue(new MockResponse()
.setResponseCode(302)
.addHeader("Location: /b")
.setBody("Moved to /b !"));
server.enqueue(new MockResponse()
.setBody("This is b."));
server.play();
Request request = new Request.Builder()
.url(server.getUrl("/"))
.post(Request.Body.create(MediaType.parse("text/plain"), "body!"))
.build();
onSuccess(request)
.assertCode(200)
.assertBody("This is b.");
RecordedRequest request1 = server.takeRequest();
assertEquals("body!", request1.getUtf8Body());
assertEquals("5", request1.getHeader("Content-Length"));
assertEquals("text/plain; charset=utf-8", request1.getHeader("Content-Type"));
assertEquals(0, request1.getSequenceNumber());
RecordedRequest request2 = server.takeRequest();
assertEquals("body!", request2.getUtf8Body());
assertEquals("5", request2.getHeader("Content-Length"));
assertEquals("text/plain; charset=utf-8", request2.getHeader("Content-Type"));
assertEquals(1, request2.getSequenceNumber());
}
private RecordedResponse onSuccess(Request request) throws IOException {
Response response = client.execute(request);
return new RecordedResponse(request, response, response.body().string(), null);
}
}

View File

@@ -20,11 +20,6 @@ import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.CookieHandler;
import java.net.CookieManager;
@@ -37,6 +32,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static java.net.CookiePolicy.ACCEPT_ORIGINAL_SERVER;
import static org.junit.Assert.assertEquals;

View File

@@ -17,7 +17,7 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.Util;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
@@ -32,7 +32,7 @@ public final class ExternalHttp2Example {
public static void main(String[] args) throws Exception {
URL url = new URL("https://http2.iijplus.jp/push/test1");
HttpsURLConnection connection = (HttpsURLConnection) new OkHttpClient()
.setProtocols(Protocol.HTTP2_AND_HTTP_11).open(url);
.setProtocols(Util.HTTP2_AND_HTTP_11).open(url);
connection.setHostnameVerifier(new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession sslSession) {

View File

@@ -17,7 +17,7 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.Util;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
@@ -32,7 +32,7 @@ public final class ExternalSpdyExample {
public static void main(String[] args) throws Exception {
URL url = new URL("https://www.google.ca/");
HttpsURLConnection connection = (HttpsURLConnection) new OkHttpClient()
.setProtocols(Protocol.SPDY3_AND_HTTP11).open(url);
.setProtocols(Util.SPDY3_AND_HTTP11).open(url);
connection.setHostnameVerifier(new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession sslSession) {

View File

@@ -15,10 +15,7 @@
*/
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.spdy.Header;
import java.io.IOException;
import java.util.List;

View File

@@ -19,8 +19,6 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.HttpResponseCache;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.OkResponseCache;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseSource;
import com.squareup.okhttp.internal.SslContextBuilder;
import com.squareup.okhttp.internal.Util;

View File

@@ -20,11 +20,6 @@ import com.squareup.okhttp.internal.SslContextBuilder;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.CacheRequest;
import java.net.CacheResponse;
@@ -40,11 +35,13 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

View File

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

View File

@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.util.zip.CRC32;
import org.junit.Test;
import static okio.Util.UTF_8;
import static com.squareup.okhttp.internal.okio.Util.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.EOFException;
import java.io.IOException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
public final class OkBufferReadUtf8LineTest extends ReadUtf8LineTest {
@Override protected BufferedSource newSource(String s) {

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.util.Arrays;
import java.util.List;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -21,7 +21,7 @@ import java.io.InputStream;
import java.util.Arrays;
import org.junit.Test;
import static okio.Util.UTF_8;
import static com.squareup.okhttp.internal.okio.Util.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.EOFException;
import java.io.IOException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.io.OutputStream;
@@ -24,7 +24,7 @@ import java.util.List;
import java.util.Map;
import org.junit.Test;
import static okio.Util.UTF_8;
import static com.squareup.okhttp.internal.okio.Util.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;

View File

@@ -13,16 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import org.junit.Test;
import static okio.Util.UTF_8;
import static com.squareup.okhttp.internal.okio.Util.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

View File

@@ -15,10 +15,10 @@
*/
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import java.io.IOException;
import java.util.List;
import okio.BufferedSource;
import okio.ByteString;
import static org.junit.Assert.fail;

View File

@@ -15,11 +15,11 @@
*/
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import okio.ByteString;
import okio.OkBuffer;
import org.junit.Before;
import org.junit.Test;

View File

@@ -16,12 +16,12 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import okio.BufferedSource;
import okio.ByteString;
import okio.OkBuffer;
import org.junit.Test;
import static com.squareup.okhttp.internal.Util.headerEntries;

View File

@@ -17,6 +17,10 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
@@ -30,10 +34,6 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import okio.BufferedSource;
import okio.ByteString;
import okio.OkBuffer;
import okio.Okio;
/** Replays prerecorded outgoing frames and records incoming frames. */
public final class MockSpdyPeer implements Closeable {

View File

@@ -16,9 +16,9 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import java.io.IOException;
import okio.ByteString;
import okio.OkBuffer;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

View File

@@ -16,6 +16,12 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.ArrayList;
@@ -23,12 +29,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ByteString;
import okio.OkBuffer;
import okio.Okio;
import okio.Source;
import org.junit.After;
import org.junit.Test;

View File

@@ -23,6 +23,12 @@
<artifactId>okhttp-protocols</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-annotations</artifactId>
<version>1.10</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>

View File

@@ -1,6 +1,7 @@
package com.squareup.okhttp;
import com.squareup.okhttp.internal.http.HeaderParser;
import com.squareup.okhttp.internal.http.Headers;
/**
* A Cache-Control header with cache directives from a server or client. These

View File

@@ -17,11 +17,18 @@
package com.squareup.okhttp;
import com.squareup.okhttp.internal.Platform;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.http.HttpAuthenticator;
import com.squareup.okhttp.internal.http.HttpConnection;
import com.squareup.okhttp.internal.http.HttpEngine;
import com.squareup.okhttp.internal.http.HttpTransport;
import com.squareup.okhttp.internal.http.Request;
import com.squareup.okhttp.internal.http.Response;
import com.squareup.okhttp.internal.http.SpdyTransport;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.spdy.SpdyConnection;
import java.io.Closeable;
import java.io.IOException;
@@ -31,10 +38,6 @@ import java.net.Proxy;
import java.net.Socket;
import java.net.SocketTimeoutException;
import javax.net.ssl.SSLSocket;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ByteString;
import okio.Okio;
import static java.net.HttpURLConnection.HTTP_OK;
import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
@@ -136,11 +139,11 @@ public final class Connection implements Closeable {
if (useNpn) {
if (route.address.protocols.contains(Protocol.HTTP_2) // Contains both spdy variants.
&& route.address.protocols.contains(Protocol.SPDY_3)) {
platform.setNpnProtocols(sslSocket, Protocol.HTTP2_SPDY3_AND_HTTP);
platform.setNpnProtocols(sslSocket, Util.HTTP2_SPDY3_AND_HTTP);
} else if (route.address.protocols.contains(Protocol.HTTP_2)) {
platform.setNpnProtocols(sslSocket, Protocol.HTTP2_AND_HTTP_11);
platform.setNpnProtocols(sslSocket, Util.HTTP2_AND_HTTP_11);
} else {
platform.setNpnProtocols(sslSocket, Protocol.SPDY3_AND_HTTP11);
platform.setNpnProtocols(sslSocket, Util.SPDY3_AND_HTTP11);
}
}
@@ -160,7 +163,7 @@ public final class Connection implements Closeable {
ByteString maybeProtocol;
Protocol selectedProtocol = Protocol.HTTP_11;
if (useNpn && (maybeProtocol = platform.getNpnSelectedProtocol(sslSocket)) != null) {
selectedProtocol = Protocol.find(maybeProtocol); // Throws IOE on unknown.
selectedProtocol = Util.getProtocol(maybeProtocol); // Throws IOE on unknown.
}
if (selectedProtocol.spdyVariant) {

View File

@@ -1,161 +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 com.squareup.okhttp;
import com.squareup.okhttp.internal.Util;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Policy on when async requests are executed.
*
* <p>Each dispatcher uses an {@link ExecutorService} to run jobs internally. If you
* supply your own executor, it should be able to run {@link #getMaxRequests the
* configured maximum} number of jobs concurrently.
*/
public final class Dispatcher {
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
/** Executes jobs. Created lazily. */
private ExecutorService executorService;
/** Ready jobs in the order they'll be run. */
private final Deque<Job> readyJobs = new ArrayDeque<Job>();
/** Running jobs. Includes canceled jobs that haven't finished yet. */
private final Deque<Job> runningJobs = new ArrayDeque<Job>();
public Dispatcher(ExecutorService executorService) {
this.executorService = executorService;
}
public Dispatcher() {
}
public synchronized ExecutorService getExecutorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
/**
* Set the maximum number of requests to execute concurrently. Above this
* requests queue in memory, waiting for the running jobs to complete.
*
* <p>If more than {@code maxRequests} requests are in flight when this is
* invoked, those requests will remain in flight.
*/
public synchronized void setMaxRequests(int maxRequests) {
if (maxRequests < 1) {
throw new IllegalArgumentException("max < 1: " + maxRequests);
}
this.maxRequests = maxRequests;
promoteJobs();
}
public synchronized int getMaxRequests() {
return maxRequests;
}
/**
* Set the maximum number of requests for each host to execute concurrently.
* This limits requests by the URL's host name. Note that concurrent requests
* to a single IP address may still exceed this limit: multiple hostnames may
* share an IP address or be routed through the same HTTP proxy.
*
* <p>If more than {@code maxRequestsPerHost} requests are in flight when this
* is invoked, those requests will remain in flight.
*/
public synchronized void setMaxRequestsPerHost(int maxRequestsPerHost) {
if (maxRequestsPerHost < 1) {
throw new IllegalArgumentException("max < 1: " + maxRequestsPerHost);
}
this.maxRequestsPerHost = maxRequestsPerHost;
promoteJobs();
}
public synchronized int getMaxRequestsPerHost() {
return maxRequestsPerHost;
}
synchronized void enqueue(OkHttpClient client, Request request, Response.Receiver receiver) {
// Copy the client. Otherwise changes (socket factory, redirect policy,
// etc.) may incorrectly be reflected in the request when it is executed.
client = client.copyWithDefaults();
Job job = new Job(this, client, request, receiver);
if (runningJobs.size() < maxRequests && runningJobsForHost(job) < maxRequestsPerHost) {
runningJobs.add(job);
getExecutorService().execute(job);
} else {
readyJobs.add(job);
}
}
/**
* Cancel all jobs with the tag {@code tag}. If a canceled job is running it
* may continue running until it reaches a safe point to finish.
*/
public synchronized void cancel(Object tag) {
for (Iterator<Job> i = readyJobs.iterator(); i.hasNext(); ) {
if (Util.equal(tag, i.next().tag())) i.remove();
}
for (Job job : runningJobs) {
if (Util.equal(tag, job.tag())) job.canceled = true;
}
}
/** Used by {@code Job#run} to signal completion. */
synchronized void finished(Job job) {
if (!runningJobs.remove(job)) throw new AssertionError("Job wasn't running!");
promoteJobs();
}
private void promoteJobs() {
if (runningJobs.size() >= maxRequests) return; // Already running max capacity.
if (readyJobs.isEmpty()) return; // No ready jobs to promote.
for (Iterator<Job> i = readyJobs.iterator(); i.hasNext(); ) {
Job job = i.next();
if (runningJobsForHost(job) < maxRequestsPerHost) {
i.remove();
runningJobs.add(job);
getExecutorService().execute(job);
}
if (runningJobs.size() >= maxRequests) return; // Reached max capacity.
}
}
/** Returns the number of running jobs that share a host with {@code job}. */
private int runningJobsForHost(Job job) {
int result = 0;
for (Job j : runningJobs) {
if (j.host().equals(job.host())) result++;
}
return result;
}
}

View File

@@ -18,7 +18,13 @@ package com.squareup.okhttp;
import com.squareup.okhttp.internal.DiskLruCache;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.http.Headers;
import com.squareup.okhttp.internal.http.HttpMethod;
import com.squareup.okhttp.internal.http.Request;
import com.squareup.okhttp.internal.http.Response;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.Okio;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -42,9 +48,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import okio.BufferedSource;
import okio.ByteString;
import okio.Okio;
import static com.squareup.okhttp.internal.Util.UTF_8;

View File

@@ -1,273 +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 com.squareup.okhttp;
import com.squareup.okhttp.internal.NamedRunnable;
import com.squareup.okhttp.internal.http.HttpAuthenticator;
import com.squareup.okhttp.internal.http.HttpEngine;
import com.squareup.okhttp.internal.http.HttpURLConnectionImpl;
import com.squareup.okhttp.internal.http.OkHeaders;
import java.io.IOException;
import java.io.InputStream;
import java.net.ProtocolException;
import java.net.Proxy;
import java.net.URL;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
import static com.squareup.okhttp.internal.Util.getEffectivePort;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_MOVED_PERM;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_MOVED_TEMP;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_MULT_CHOICE;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_PROXY_AUTH;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_SEE_OTHER;
import static com.squareup.okhttp.internal.http.HttpURLConnectionImpl.HTTP_UNAUTHORIZED;
import static com.squareup.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT;
final class Job extends NamedRunnable {
private final Dispatcher dispatcher;
private final OkHttpClient client;
private final Response.Receiver responseReceiver;
private int redirectionCount;
volatile boolean canceled;
/** The request; possibly a consequence of redirects or auth headers. */
private Request request;
HttpEngine engine;
public Job(Dispatcher dispatcher, OkHttpClient client, Request request,
Response.Receiver responseReceiver) {
super("OkHttp %s", request.urlString());
this.dispatcher = dispatcher;
this.client = client;
this.request = request;
this.responseReceiver = responseReceiver;
}
String host() {
return request.url().getHost();
}
Request request() {
return request;
}
Object tag() {
return request.tag();
}
@Override protected void execute() {
try {
Response response = getResponse();
if (response != null && !canceled) {
responseReceiver.onResponse(response);
}
} catch (IOException e) {
responseReceiver.onFailure(new Failure.Builder()
.request(request)
.exception(e)
.build());
} finally {
engine.close(); // Close the connection if it isn't already.
dispatcher.finished(this);
}
}
/**
* Performs the request and returns the response. May return null if this job
* was canceled.
*/
Response getResponse() throws IOException {
Response redirectedBy = null;
// Copy body metadata to the appropriate request headers.
Request.Body body = request.body();
if (body != null) {
MediaType contentType = body.contentType();
if (contentType == null) throw new IllegalStateException("contentType == null");
Request.Builder requestBuilder = request.newBuilder();
requestBuilder.header("Content-Type", contentType.toString());
long contentLength = body.contentLength();
if (contentLength != -1) {
requestBuilder.header("Content-Length", Long.toString(contentLength));
requestBuilder.removeHeader("Transfer-Encoding");
} else {
requestBuilder.header("Transfer-Encoding", "chunked");
requestBuilder.removeHeader("Content-Length");
}
request = requestBuilder.build();
}
// Create the initial HTTP engine. Retries and redirects need new engine for each attempt.
engine = new HttpEngine(client, request, false, null, null, null);
while (true) {
if (canceled) return null;
try {
engine.sendRequest();
if (body != null) {
BufferedSink sink = Okio.buffer(engine.getRequestBody());
body.writeTo(sink);
sink.flush();
}
engine.readResponse();
} catch (IOException e) {
HttpEngine retryEngine = engine.recover(e);
if (retryEngine != null) {
engine = retryEngine;
continue;
}
// Give up; recovery is not possible.
throw e;
}
Response response = engine.getResponse();
Request redirect = processResponse(engine, response);
if (redirect == null) {
engine.releaseConnection();
return response.newBuilder()
// Cache body includes original content-length and content-type data.
.body(engine.responseSource().usesCache()
? engine.getResponse().body()
: new RealResponseBody(response, engine.getResponseBody()))
.redirectedBy(redirectedBy)
.build();
}
if (!sameConnection(request, redirect)) {
engine.releaseConnection();
}
Connection connection = engine.close();
redirectedBy = response.newBuilder().redirectedBy(redirectedBy).build(); // Chained.
request = redirect;
engine = new HttpEngine(client, request, false, connection, null, null);
}
}
/**
* Figures out the HTTP request to make in response to receiving {@code
* response}. This will either add authentication headers or follow
* redirects. If a follow-up is either unnecessary or not applicable, this
* returns null.
*/
private Request processResponse(HttpEngine engine, Response response) throws IOException {
Request request = response.request();
Proxy selectedProxy = engine.getRoute() != null
? engine.getRoute().getProxy()
: client.getProxy();
int responseCode = response.code();
switch (responseCode) {
case HTTP_PROXY_AUTH:
if (selectedProxy.type() != Proxy.Type.HTTP) {
throw new ProtocolException("Received HTTP_PROXY_AUTH (407) code while not using proxy");
}
// fall-through
case HTTP_UNAUTHORIZED:
return HttpAuthenticator.processAuthHeader(
client.getAuthenticator(), response, selectedProxy);
case HTTP_MULT_CHOICE:
case HTTP_MOVED_PERM:
case HTTP_MOVED_TEMP:
case HTTP_SEE_OTHER:
case HTTP_TEMP_REDIRECT:
if (!client.getFollowProtocolRedirects()) {
return null; // This client has is configured to not follow redirects.
}
if (++redirectionCount > HttpURLConnectionImpl.MAX_REDIRECTS) {
throw new ProtocolException("Too many redirects: " + redirectionCount);
}
String method = request.method();
if (responseCode == HTTP_TEMP_REDIRECT && !method.equals("GET") && !method.equals("HEAD")) {
// "If the 307 status code is received in response to a request other than GET or HEAD,
// the user agent MUST NOT automatically redirect the request"
return null;
}
String location = response.header("Location");
if (location == null) {
return null;
}
URL url = new URL(request.url(), location);
if (!url.getProtocol().equals("https") && !url.getProtocol().equals("http")) {
return null; // Don't follow redirects to unsupported protocols.
}
return this.request.newBuilder().url(url).build();
default:
return null;
}
}
static boolean sameConnection(Request a, Request b) {
return a.url().getHost().equals(b.url().getHost())
&& getEffectivePort(a.url()) == getEffectivePort(b.url())
&& a.url().getProtocol().equals(b.url().getProtocol());
}
static class RealResponseBody extends Response.Body {
private final Response response;
private final Source source;
/** Multiple calls to {@link #byteStream} must return the same instance. */
private InputStream in;
RealResponseBody(Response response, Source source) {
this.response = response;
this.source = source;
}
@Override public boolean ready() throws IOException {
return true;
}
@Override public MediaType contentType() {
String contentType = response.header("Content-Type");
return contentType != null ? MediaType.parse(contentType) : null;
}
@Override public long contentLength() {
return OkHeaders.contentLength(response);
}
@Override public Source source() {
return source;
}
@Override public InputStream byteStream() {
InputStream result = in;
return result != null
? result
: (in = Okio.buffer(source).inputStream());
}
}
}

View File

@@ -15,12 +15,12 @@
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.okio.ByteString;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.Proxy;
import java.net.URL;
import java.util.List;
import okio.ByteString;
/**
* Responds to authentication challenges from the remote web or proxy server by

View File

@@ -20,6 +20,7 @@ import com.squareup.okhttp.internal.http.HttpAuthenticator;
import com.squareup.okhttp.internal.http.HttpURLConnectionImpl;
import com.squareup.okhttp.internal.http.HttpsURLConnectionImpl;
import com.squareup.okhttp.internal.http.ResponseCacheAdapter;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.tls.OkHostnameVerifier;
import java.io.IOException;
import java.net.CookieHandler;
@@ -38,13 +39,11 @@ import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import okio.ByteString;
/** Configures and creates HTTP connections. */
public final class OkHttpClient implements URLStreamHandlerFactory, Cloneable {
private final RouteDatabase routeDatabase;
private Dispatcher dispatcher;
private Proxy proxy;
private List<Protocol> protocols;
private ProxySelector proxySelector;
@@ -60,7 +59,6 @@ public final class OkHttpClient implements URLStreamHandlerFactory, Cloneable {
public OkHttpClient() {
routeDatabase = new RouteDatabase();
dispatcher = new Dispatcher();
}
/**
@@ -265,21 +263,7 @@ public final class OkHttpClient implements URLStreamHandlerFactory, Cloneable {
}
/**
* Sets the dispatcher used to set policy and execute asynchronous requests.
* Must not be null.
*/
public OkHttpClient setDispatcher(Dispatcher dispatcher) {
if (dispatcher == null) throw new IllegalArgumentException("dispatcher == null");
this.dispatcher = dispatcher;
return this;
}
public Dispatcher getDispatcher() {
return dispatcher;
}
/**
* @deprecated OkHttp 2 enforces an enumeration of {@link Protocol protocols}
* @deprecated OkHttp 1.5 enforces an enumeration of {@link Protocol protocols}
* that can be selected. Please switch to {@link #setProtocols(java.util.List)}.
*/
@Deprecated
@@ -287,7 +271,7 @@ public final class OkHttpClient implements URLStreamHandlerFactory, Cloneable {
List<Protocol> protocols = new ArrayList<Protocol>(transports.size());
for (int i = 0, size = transports.size(); i < size; i++) {
try {
Protocol protocol = Protocol.find(ByteString.encodeUtf8(transports.get(i)));
Protocol protocol = Util.getProtocol(ByteString.encodeUtf8(transports.get(i)));
protocols.add(protocol);
} catch (IOException e) {
throw new IllegalArgumentException(e);
@@ -337,8 +321,9 @@ public final class OkHttpClient implements URLStreamHandlerFactory, Cloneable {
}
/**
* @deprecated OkHttp 2 enforces an enumeration of {@link Protocol protocols}
* that can be selected. Please switch to {@link #getProtocols()}.
* @deprecated OkHttp 1.5 enforces an enumeration of {@link Protocol
* protocols} that can be selected. Please switch to {@link
* #getProtocols()}.
*/
@Deprecated
public List<String> getTransports() {
@@ -353,68 +338,6 @@ public final class OkHttpClient implements URLStreamHandlerFactory, Cloneable {
return protocols;
}
/**
* Invokes {@code request} immediately, and blocks until the response can be
* processed or is in error.
*
* <p>The caller may read the response body with the response's
* {@link Response#body} method. To facilitate connection recycling, callers
* should always {@link Response.Body#close() close the response body}.
*
* <p>Note that transport-layer success (receiving a HTTP response code,
* headers and body) does not necessarily indicate application-layer
* success: {@code response} may still indicate an unhappy HTTP response
* code like 404 or 500.
*
* <h3>Non-blocking responses</h3>
*
* <p>Receivers do not need to block while waiting for the response body to
* download. Instead, they can get called back as data arrives. Use {@link
* Response.Body#ready} to check if bytes should be read immediately. While
* there is data ready, read it.
*
* <p>The current implementation of {@link Response.Body#ready} always
* returns true when the underlying transport is HTTP/1. This results in
* blocking on that transport. For effective non-blocking your server must
* support {@link Protocol#SPDY_3} or {@link Protocol#HTTP_2}.
*
* @throws IOException when the request could not be executed due to a
* connectivity problem or timeout. Because networks can fail during an
* exchange, it is possible that the remote server accepted the request
* before the failure.
*/
public Response execute(Request request) throws IOException {
// Copy the client. Otherwise changes (socket factory, redirect policy,
// etc.) may incorrectly be reflected in the request when it is executed.
OkHttpClient client = copyWithDefaults();
Job job = new Job(dispatcher, client, request, null);
Response result = job.getResponse(); // Since we don't cancel, this won't be null.
job.engine.releaseConnection(); // Transfer ownership of the body to the caller.
return result;
}
/**
* Schedules {@code request} to be executed at some point in the future. The
* {@link #getDispatcher dispatcher} defines when the request will run:
* usually immediately unless there are several other requests currently being
* executed.
*
* <p>This client will later call back {@code responseReceiver} with either an
* HTTP response or a failure exception. If you {@link #cancel} a request
* before it completes the receiver will not be called back.
*/
public void enqueue(Request request, Response.Receiver responseReceiver) {
dispatcher.enqueue(this, request, responseReceiver);
}
/**
* Cancels all scheduled tasks tagged with {@code tag}. Requests that are already
* complete cannot be canceled.
*/
public void cancel(Object tag) {
dispatcher.cancel(tag);
}
public HttpURLConnection open(URL url) {
return open(url, proxy);
}
@@ -457,7 +380,7 @@ public final class OkHttpClient implements URLStreamHandlerFactory, Cloneable {
result.connectionPool = ConnectionPool.getDefault();
}
if (result.protocols == null) {
result.protocols = Protocol.HTTP2_SPDY3_AND_HTTP;
result.protocols = Util.HTTP2_SPDY3_AND_HTTP;
}
return result;
}

View File

@@ -15,12 +15,17 @@
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.http.Request;
import com.squareup.okhttp.internal.http.Response;
import java.io.IOException;
import java.net.CacheRequest;
/**
* An extended response cache API. Unlike {@link java.net.ResponseCache}, this
* interface supports conditional caching and statistics.
*
* <h3>Warning: Experimental OkHttp 2.0 API</h3>
* This class is in beta. APIs are subject to change!
*/
public interface OkResponseCache {
Response get(Request request) throws IOException;

View File

@@ -15,11 +15,7 @@
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.Util;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import okio.ByteString;
import com.squareup.okhttp.internal.okio.ByteString;
/**
* Contains protocols that OkHttp supports
@@ -38,13 +34,6 @@ public enum Protocol {
SPDY_3("spdy/3.1", true),
HTTP_11("http/1.1", false);
public static final List<Protocol> HTTP2_SPDY3_AND_HTTP =
Util.immutableList(Arrays.asList(HTTP_2, SPDY_3, HTTP_11));
public static final List<Protocol> SPDY3_AND_HTTP11 =
Util.immutableList(Arrays.asList(SPDY_3, HTTP_11));
public static final List<Protocol> HTTP2_AND_HTTP_11 =
Util.immutableList(Arrays.asList(HTTP_2, HTTP_11));
/** Identifier string used in NPN or ALPN selection. */
public final ByteString name;
@@ -59,17 +48,4 @@ public enum Protocol {
this.name = ByteString.encodeUtf8(name);
this.spdyVariant = spdyVariant;
}
/**
* Returns the protocol matching {@code input} or {@link #HTTP_11} is on
* {@code null}. Throws an {@link IOException} when {@code input} doesn't
* match the {@link #name} of a supported protocol.
*/
public static Protocol find(ByteString input) throws IOException {
if (input == null) return HTTP_11;
for (Protocol protocol : values()) {
if (protocol.name.equals(input)) return protocol;
}
throw new IOException("Unexpected protocol: " + input.utf8());
}
}

View File

@@ -15,6 +15,7 @@
*/
package com.squareup.okhttp;
import com.squareup.okhttp.internal.http.Request;
import java.io.IOException;
import java.net.URL;

View File

@@ -16,6 +16,10 @@
package com.squareup.okhttp.internal;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
@@ -34,10 +38,6 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.OkBuffer;
import okio.Okio;
/**
* A cache that uses a bounded amount of space on a filesystem. Each cache

View File

@@ -17,6 +17,7 @@
package com.squareup.okhttp.internal;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.okio.ByteString;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
@@ -37,7 +38,6 @@ import java.util.logging.Logger;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import javax.net.ssl.SSLSocket;
import okio.ByteString;
/**
* Access to Platform-specific features necessary for SPDY and advanced TLS.

View File

@@ -16,6 +16,10 @@
package com.squareup.okhttp.internal;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Source;
import com.squareup.okhttp.internal.spdy.Header;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
@@ -37,9 +41,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadFactory;
import okio.ByteString;
import okio.OkBuffer;
import okio.Source;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
@@ -54,6 +55,12 @@ public final class Util {
/** A cheap and type-safe constant for the UTF-8 Charset. */
public static final Charset UTF_8 = Charset.forName("UTF-8");
public static final List<Protocol> HTTP2_SPDY3_AND_HTTP =
immutableList(Arrays.asList(Protocol.HTTP_2, Protocol.SPDY_3, Protocol.HTTP_11));
public static final List<Protocol> SPDY3_AND_HTTP11 =
immutableList(Arrays.asList(Protocol.SPDY_3, Protocol.HTTP_11));
public static final List<Protocol> HTTP2_AND_HTTP_11 =
immutableList(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_11));
private Util() {
}
@@ -286,4 +293,17 @@ public final class Util {
}
return result;
}
/**
* Returns the protocol matching {@code input} or {@link #HTTP_11} is on
* {@code null}. Throws an {@link java.io.IOException} when {@code input} doesn't
* match the {@link #name} of a supported protocol.
*/
public static Protocol getProtocol(ByteString input) throws IOException {
if (input == null) return Protocol.HTTP_11;
for (Protocol protocol : Protocol.values()) {
if (protocol.name.equals(input)) return protocol;
}
throw new IOException("Unexpected protocol: " + input.utf8());
}
}

View File

@@ -2,8 +2,6 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseSource;
import java.io.IOException;
import java.io.InputStream;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.okhttp;
package com.squareup.okhttp.internal.http;
/**
* A failure attempting to retrieve an HTTP response.

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
package com.squareup.okhttp;
package com.squareup.okhttp.internal.http;
import java.util.ArrayList;
import java.util.Arrays;

View File

@@ -16,11 +16,8 @@
*/
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.OkAuthenticator;
import com.squareup.okhttp.OkAuthenticator.Challenge;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.IOException;
import java.net.Authenticator;
import java.net.InetAddress;

View File

@@ -18,22 +18,20 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Connection;
import com.squareup.okhttp.ConnectionPool;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.Deadline;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.okio.Sink;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.io.OutputStream;
import java.net.CacheRequest;
import java.net.ProtocolException;
import java.net.Socket;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Deadline;
import okio.OkBuffer;
import okio.Okio;
import okio.Sink;
import okio.Source;
import static com.squareup.okhttp.internal.Util.checkOffsetAndCount;
import static com.squareup.okhttp.internal.http.StatusLine.HTTP_CONTINUE;

View File

@@ -19,15 +19,17 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Address;
import com.squareup.okhttp.Connection;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.OkResponseCache;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseSource;
import com.squareup.okhttp.Route;
import com.squareup.okhttp.TunnelRequest;
import com.squareup.okhttp.internal.Dns;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.GzipSource;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.okio.Sink;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.io.InputStream;
import java.net.CacheRequest;
@@ -41,11 +43,6 @@ import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocketFactory;
import okio.BufferedSink;
import okio.GzipSource;
import okio.Okio;
import okio.Sink;
import okio.Source;
import static com.squareup.okhttp.internal.Util.closeQuietly;
import static com.squareup.okhttp.internal.Util.getDefaultPort;

View File

@@ -16,12 +16,10 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.okio.Sink;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.net.CacheRequest;
import okio.Sink;
import okio.Source;
public final class HttpTransport implements Transport {
private final HttpEngine httpEngine;

View File

@@ -19,14 +19,14 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Connection;
import com.squareup.okhttp.Handshake;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.Route;
import com.squareup.okhttp.internal.Platform;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.Sink;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -45,9 +45,6 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okio.BufferedSink;
import okio.ByteString;
import okio.Sink;
import static com.squareup.okhttp.internal.Util.getEffectivePort;
import static com.squareup.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT;
@@ -559,7 +556,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection {
}
for (String protocol : protocolsString.split(",", -1)) {
try {
protocolsList.add(Protocol.find(ByteString.encodeUtf8(protocol)));
protocolsList.add(Util.getProtocol(ByteString.encodeUtf8(protocol)));
} catch (IOException e) {
throw new IllegalStateException(e);
}

View File

@@ -1,8 +1,5 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.Platform;
import java.util.ArrayList;
import java.util.Collections;

View File

@@ -13,10 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.okhttp;
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.internal.Platform;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -27,7 +30,6 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import okio.BufferedSink;
/**
* An HTTP request. Instances of this class are immutable if their {@link #body}

View File

@@ -1,6 +1,5 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Request;
import java.net.Proxy;
import java.net.URL;

View File

@@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.okhttp;
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.Handshake;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.ResponseSource;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.http.HttpDate;
import com.squareup.okhttp.internal.http.OkHeaders;
import com.squareup.okhttp.internal.http.StatusLine;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.okio.Source;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
@@ -32,8 +35,6 @@ import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import okio.Okio;
import okio.Source;
import static com.squareup.okhttp.internal.Util.UTF_8;
import static com.squareup.okhttp.internal.Util.equal;

View File

@@ -16,11 +16,8 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Handshake;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkResponseCache;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseSource;
import java.io.IOException;
import java.io.InputStream;

View File

@@ -16,12 +16,12 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.Deadline;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Sink;
import java.io.IOException;
import java.net.ProtocolException;
import okio.BufferedSink;
import okio.Deadline;
import okio.OkBuffer;
import okio.Sink;
import static com.squareup.okhttp.internal.Util.checkOffsetAndCount;

View File

@@ -16,11 +16,14 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.Deadline;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.okio.Sink;
import com.squareup.okhttp.internal.okio.Source;
import com.squareup.okhttp.internal.spdy.ErrorCode;
import com.squareup.okhttp.internal.spdy.Header;
import com.squareup.okhttp.internal.spdy.SpdyConnection;
@@ -34,12 +37,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import okio.ByteString;
import okio.Deadline;
import okio.OkBuffer;
import okio.Okio;
import okio.Sink;
import okio.Source;
import static com.squareup.okhttp.internal.spdy.Header.RESPONSE_STATUS;
import static com.squareup.okhttp.internal.spdy.Header.TARGET_AUTHORITY;

View File

@@ -16,12 +16,10 @@
package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.okio.Sink;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.net.CacheRequest;
import okio.Sink;
import okio.Source;
interface Transport {
/**

View File

@@ -19,7 +19,7 @@
* @author Alexander Y. Kleymenov
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.UnsupportedEncodingException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.io.OutputStream;

View File

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

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.EOFException;
import java.io.IOException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

View File

@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.util.zip.Deflater;
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
import static okio.Util.checkOffsetAndCount;
import static com.squareup.okhttp.internal.okio.Util.checkOffsetAndCount;
/**
* A sink that uses <a href="http://tools.ietf.org/html/rfc1951">DEFLATE</a> to

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.util.zip.CRC32;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.EOFException;
import java.io.IOException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.EOFException;
import java.io.InputStream;
@@ -24,8 +24,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static okio.Util.UTF_8;
import static okio.Util.checkOffsetAndCount;
import static com.squareup.okhttp.internal.okio.Util.UTF_8;
import static com.squareup.okhttp.internal.okio.Util.checkOffsetAndCount;
/**
* A collection of bytes in memory.
@@ -253,7 +253,7 @@ public final class OkBuffer implements BufferedSource, BufferedSink, Cloneable {
Segment head = this.head;
if (head.pos + byteCount > head.limit) {
// If the string spans multiple segments, delegate to readBytes().
return new String(readBytes(byteCount), Util.UTF_8);
return new String(readBytes(byteCount), UTF_8);
}
String result = new String(head.data, head.pos, (int) byteCount, UTF_8);
@@ -369,7 +369,7 @@ public final class OkBuffer implements BufferedSource, BufferedSink, Cloneable {
/** Encodes {@code string} as UTF-8 and appends the bytes to this. */
@Override public OkBuffer writeUtf8(String string) {
byte[] data = string.getBytes(Util.UTF_8);
byte[] data = string.getBytes(UTF_8);
return write(data, 0, data.length);
}

View File

@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static okio.Util.checkOffsetAndCount;
import static com.squareup.okhttp.internal.okio.Util.checkOffsetAndCount;
public final class Okio {
private Okio() {

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.IOException;
import java.io.OutputStream;

View File

@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import static okio.Util.checkOffsetAndCount;
import static com.squareup.okhttp.internal.okio.Util.checkOffsetAndCount;
final class RealBufferedSource implements BufferedSource {
public final OkBuffer buffer;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
/**
* A segment of an OkBuffer.

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
/**
* A collection of unused segments, necessary to avoid GC churn and zero-fill.

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.Closeable;
import java.io.IOException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.io.Closeable;
import java.io.IOException;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
package com.squareup.okhttp.internal.okio;
import java.nio.charset.Charset;

View File

@@ -16,11 +16,11 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import okio.BufferedSource;
import okio.ByteString;
/** Reads transport frames for SPDY/3 or HTTP/2. */
public interface FrameReader extends Closeable {

View File

@@ -16,10 +16,10 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.OkBuffer;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import okio.OkBuffer;
/** Writes transport frames for SPDY/3 or HTTP/2. */
public interface FrameWriter extends Closeable {

View File

@@ -1,6 +1,6 @@
package com.squareup.okhttp.internal.spdy;
import okio.ByteString;
import com.squareup.okhttp.internal.okio.ByteString;
/** HTTP header: the name is an ASCII string, but the value can be UTF-8. */
public final class Header {

View File

@@ -1,6 +1,11 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.BitArray;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -8,11 +13,6 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import okio.BufferedSource;
import okio.ByteString;
import okio.OkBuffer;
import okio.Okio;
import okio.Source;
/**
* Read and write HPACK v05.

View File

@@ -16,14 +16,14 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.Deadline;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.util.List;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ByteString;
import okio.Deadline;
import okio.OkBuffer;
import okio.Source;
/**
* Read and write http/2 v09 frames.

View File

@@ -15,10 +15,10 @@
*/
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.ByteString;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import okio.ByteString;
/**
* This class was originally composed from the following classes in

View File

@@ -1,17 +1,17 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.Deadline;
import com.squareup.okhttp.internal.okio.InflaterSource;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import com.squareup.okhttp.internal.okio.Source;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import okio.BufferedSource;
import okio.ByteString;
import okio.Deadline;
import okio.InflaterSource;
import okio.OkBuffer;
import okio.Okio;
import okio.Source;
/**
* Reads a SPDY/3 Name/Value header block. This class is made complicated by the

View File

@@ -15,9 +15,9 @@
*/
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.BufferedSource;
import java.io.IOException;
import java.util.List;
import okio.BufferedSource;
/**
* {@link com.squareup.okhttp.Protocol#HTTP_2 HTTP/2} only.

View File

@@ -17,17 +17,17 @@ package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.DeflaterSink;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ProtocolException;
import java.util.List;
import java.util.zip.Deflater;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ByteString;
import okio.DeflaterSink;
import okio.OkBuffer;
import okio.Okio;
/**
* Read and write spdy/3.1 frames.

View File

@@ -18,6 +18,11 @@ package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.NamedRunnable;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.ByteString;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Okio;
import java.io.Closeable;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -32,11 +37,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ByteString;
import okio.OkBuffer;
import okio.Okio;
/**
* A socket connection to a remote peer. A connection hosts streams which can

View File

@@ -16,17 +16,17 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.internal.okio.BufferedSource;
import com.squareup.okhttp.internal.okio.Deadline;
import com.squareup.okhttp.internal.okio.OkBuffer;
import com.squareup.okhttp.internal.okio.Sink;
import com.squareup.okhttp.internal.okio.Source;
import java.io.EOFException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import okio.BufferedSource;
import okio.Deadline;
import okio.OkBuffer;
import okio.Sink;
import okio.Source;
/** A logical bidirectional stream. */
public final class SpdyStream {

View File

@@ -16,8 +16,8 @@
package com.squareup.okhttp.internal.spdy;
import com.squareup.okhttp.Protocol;
import okio.BufferedSink;
import okio.BufferedSource;
import com.squareup.okhttp.internal.okio.BufferedSink;
import com.squareup.okhttp.internal.okio.BufferedSource;
/** A version and dialect of the framed socket protocol. */
interface Variant {

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.squareup.okhttp</groupId>
<artifactId>parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<name>Okio</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-annotations</artifactId>
<version>1.10</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -22,8 +22,6 @@
<module>okhttp</module>
<module>okhttp-apache</module>
<module>okhttp-tests</module>
<module>okcurl</module>
<module>okio</module>
<module>mockwebserver</module>
<module>samples</module>
<module>benchmarks</module>