mirror of
https://github.com/square/okhttp.git
synced 2026-01-12 10:23:16 +03:00
Add logging interceptor for simple request and response logging.
This commit is contained in:
49
okhttp-logging-interceptor/README.md
Normal file
49
okhttp-logging-interceptor/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
Logging Interceptor
|
||||
===================
|
||||
|
||||
An [OkHttp interceptor][1] which logs HTTP request and response data.
|
||||
|
||||
```java
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(Level.BASIC);
|
||||
client.interceptors().add(logging);
|
||||
```
|
||||
|
||||
You can change the log level at any time by calling `setLevel`.
|
||||
|
||||
To log to a custom location, pass a `Logger` instance to the constructor.
|
||||
```java
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new Logger() {
|
||||
@Override public void log(String message) {
|
||||
Timber.tag("OkHttp").d(message);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**Warning**: The logs generated by this interceptor when using the `HEADERS` or `BODY` levels has
|
||||
the potential to leak sensitive information such as "Authorization" or "Cookie" headers and the
|
||||
contents of request and response bodies. This data should only be logged in a controlled way or in
|
||||
a non-production environment.
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
Get via Maven:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
<version>(insert latest version)</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
or via Gradle
|
||||
```groovy
|
||||
compile 'com.squareup.okhttp:logging-interceptor:(insert latest version)'
|
||||
```
|
||||
|
||||
|
||||
|
||||
[1]: https://github.com/square/okhttp/wiki/Interceptors
|
||||
40
okhttp-logging-interceptor/pom.xml
Normal file
40
okhttp-logging-interceptor/pom.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?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.6.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
<name>OkHttp Logging Interceptor</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>mockwebserver</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp-testing-support</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.logging;
|
||||
|
||||
import com.squareup.okhttp.Connection;
|
||||
import com.squareup.okhttp.Headers;
|
||||
import com.squareup.okhttp.HttpUrl;
|
||||
import com.squareup.okhttp.Interceptor;
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Protocol;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.Response;
|
||||
import com.squareup.okhttp.ResponseBody;
|
||||
import com.squareup.okhttp.internal.Platform;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import okio.Buffer;
|
||||
|
||||
/**
|
||||
* An OkHttp interceptor which logs request and response information. Can be applied as an
|
||||
* {@linkplain OkHttpClient#interceptors() application interceptor} or as a
|
||||
* {@linkplain OkHttpClient#networkInterceptors() network interceptor}.
|
||||
* <p>
|
||||
* The format of the logs created by this class should not be considered stable and may change
|
||||
* slightly between releases. If you need a stable logging format, use your own interceptor.
|
||||
*/
|
||||
public final class HttpLoggingInterceptor implements Interceptor {
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
public enum Level {
|
||||
/** No logs. */
|
||||
NONE,
|
||||
/**
|
||||
* Logs request and response lines.
|
||||
* <p>
|
||||
* Example:
|
||||
* <pre>{@code
|
||||
* --> POST /greeting HTTP/1.1 (3-byte body)
|
||||
*
|
||||
* <-- HTTP/1.1 200 OK (22ms, 6-byte body)
|
||||
* }</pre>
|
||||
*/
|
||||
BASIC,
|
||||
/**
|
||||
* Logs request and response lines and their respective headers.
|
||||
* <p>
|
||||
* Example:
|
||||
* <pre>{@code
|
||||
* --> POST /greeting HTTP/1.1
|
||||
* Host: example.com
|
||||
* Content-Type: plain/text
|
||||
* Content-Length: 3
|
||||
* --> END POST
|
||||
*
|
||||
* <-- HTTP/1.1 200 OK (22ms)
|
||||
* Content-Type: plain/text
|
||||
* Content-Length: 6
|
||||
* <-- END HTTP
|
||||
* }</pre>
|
||||
*/
|
||||
HEADERS,
|
||||
/**
|
||||
* Logs request and response lines and their respective headers and bodies (if present).
|
||||
* <p>
|
||||
* Example:
|
||||
* <pre>{@code
|
||||
* --> POST /greeting HTTP/1.1
|
||||
* Host: example.com
|
||||
* Content-Type: plain/text
|
||||
* Content-Length: 3
|
||||
*
|
||||
* Hi?
|
||||
* --> END GET
|
||||
*
|
||||
* <-- HTTP/1.1 200 OK (22ms)
|
||||
* Content-Type: plain/text
|
||||
* Content-Length: 6
|
||||
*
|
||||
* Hello!
|
||||
* <-- END HTTP
|
||||
* }</pre>
|
||||
*/
|
||||
BODY
|
||||
}
|
||||
|
||||
public interface Logger {
|
||||
void log(String message);
|
||||
|
||||
/** A {@link Logger} defaults output appropriate for the current platform. */
|
||||
Logger DEFAULT = new Logger() {
|
||||
@Override public void log(String message) {
|
||||
Platform.get().log(message);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public HttpLoggingInterceptor() {
|
||||
this(Logger.DEFAULT);
|
||||
}
|
||||
|
||||
public HttpLoggingInterceptor(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
private volatile Level level = Level.NONE;
|
||||
|
||||
/** Change the level at which this interceptor logs. */
|
||||
public void setLevel(Level level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override public Response intercept(Chain chain) throws IOException {
|
||||
Level level = this.level;
|
||||
|
||||
Request request = chain.request();
|
||||
if (level == Level.NONE) {
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
boolean logBody = level == Level.BODY;
|
||||
boolean logHeaders = logBody || level == Level.HEADERS;
|
||||
|
||||
RequestBody requestBody = request.body();
|
||||
boolean hasRequestBody = requestBody != null;
|
||||
|
||||
Connection connection = chain.connection();
|
||||
Protocol protocol = connection != null ? connection.getProtocol() : Protocol.HTTP_1_1;
|
||||
String requestStartMessage =
|
||||
"--> " + request.method() + ' ' + requestPath(request.httpUrl()) + ' ' + protocol(protocol);
|
||||
if (!logHeaders && hasRequestBody) {
|
||||
requestStartMessage += " (" + requestBody.contentLength() + "-byte body)";
|
||||
}
|
||||
logger.log(requestStartMessage);
|
||||
|
||||
if (logHeaders) {
|
||||
Headers headers = request.headers();
|
||||
for (int i = 0, count = headers.size(); i < count; i++) {
|
||||
logger.log(headers.name(i) + ": " + headers.value(i));
|
||||
}
|
||||
|
||||
if (logBody && hasRequestBody) {
|
||||
Buffer buffer = new Buffer();
|
||||
requestBody.writeTo(buffer);
|
||||
|
||||
Charset charset = UTF8;
|
||||
MediaType contentType = requestBody.contentType();
|
||||
if (contentType != null) {
|
||||
contentType.charset(UTF8);
|
||||
}
|
||||
|
||||
logger.log("");
|
||||
logger.log(buffer.readString(charset));
|
||||
}
|
||||
|
||||
String endMessage = "--> END " + request.method();
|
||||
if (logBody && hasRequestBody) {
|
||||
endMessage += " (" + requestBody.contentLength() + "-byte body)";
|
||||
}
|
||||
logger.log(endMessage);
|
||||
}
|
||||
|
||||
long startNs = System.nanoTime();
|
||||
Response response = chain.proceed(request);
|
||||
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
|
||||
|
||||
ResponseBody responseBody = response.body();
|
||||
logger.log("<-- " + protocol(response.protocol()) + ' ' + response.code() + ' '
|
||||
+ response.message() + " (" + tookMs + "ms"
|
||||
+ (!logHeaders ? ", " + responseBody.contentLength() + "-byte body" : "") + ')');
|
||||
|
||||
if (logHeaders) {
|
||||
Headers headers = response.headers();
|
||||
for (int i = 0, count = headers.size(); i < count; i++) {
|
||||
logger.log(headers.name(i) + ": " + headers.value(i));
|
||||
}
|
||||
|
||||
if (logBody) {
|
||||
Buffer buffer = new Buffer();
|
||||
responseBody.source().readAll(buffer);
|
||||
|
||||
Charset charset = UTF8;
|
||||
MediaType contentType = responseBody.contentType();
|
||||
if (contentType != null) {
|
||||
charset = contentType.charset(UTF8);
|
||||
}
|
||||
|
||||
if (responseBody.contentLength() > 0) {
|
||||
logger.log("");
|
||||
logger.log(buffer.clone().readString(charset));
|
||||
}
|
||||
|
||||
// Since we consumed the original, replace the one-shot body in the response with a new one.
|
||||
response = response.newBuilder()
|
||||
.body(ResponseBody.create(contentType, responseBody.contentLength(), buffer))
|
||||
.build();
|
||||
}
|
||||
|
||||
String endMessage = "<-- END HTTP";
|
||||
if (logBody) {
|
||||
endMessage += " (" + responseBody.contentLength() + "-byte body)";
|
||||
}
|
||||
logger.log(endMessage);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private static String protocol(Protocol protocol) {
|
||||
return protocol == Protocol.HTTP_1_0 ? "HTTP/1.0" : "HTTP/1.1";
|
||||
}
|
||||
|
||||
private static String requestPath(HttpUrl url) {
|
||||
String path = url.encodedPath();
|
||||
String query = url.encodedQuery();
|
||||
return query != null ? (path + '?' + query) : path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.logging;
|
||||
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.logging.HttpLoggingInterceptor.Level;
|
||||
import com.squareup.okhttp.mockwebserver.MockResponse;
|
||||
import com.squareup.okhttp.mockwebserver.MockWebServer;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public final class HttpLoggingInterceptorTest {
|
||||
private static final MediaType PLAIN = MediaType.parse("text/plain; charset=utf-8");
|
||||
|
||||
@Rule public final MockWebServer server = new MockWebServer();
|
||||
|
||||
private final OkHttpClient client = new OkHttpClient();
|
||||
private final List<String> logs = new ArrayList<>();
|
||||
private HttpLoggingInterceptor interceptor;
|
||||
|
||||
@Before public void setUp() {
|
||||
HttpLoggingInterceptor.Logger logger = new HttpLoggingInterceptor.Logger() {
|
||||
@Override public void log(String message) {
|
||||
logs.add(message);
|
||||
}
|
||||
};
|
||||
interceptor = new HttpLoggingInterceptor(logger);
|
||||
client.networkInterceptors().add(interceptor);
|
||||
client.setConnectionPool(null);
|
||||
}
|
||||
|
||||
@Test public void none() throws IOException {
|
||||
server.enqueue(new MockResponse());
|
||||
client.newCall(request().build()).execute();
|
||||
assertTrue(logs.isEmpty());
|
||||
}
|
||||
|
||||
@Test public void basicGet() throws IOException {
|
||||
interceptor.setLevel(Level.BASIC);
|
||||
|
||||
server.enqueue(new MockResponse());
|
||||
client.newCall(request().build()).execute();
|
||||
|
||||
assertEquals(2, logs.size());
|
||||
assertEquals("--> GET / HTTP/1.1", logs.get(0));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms, 0-byte body\\)", logs.get(1)));
|
||||
}
|
||||
|
||||
@Test public void basicPost() throws IOException {
|
||||
interceptor.setLevel(Level.BASIC);
|
||||
|
||||
server.enqueue(new MockResponse());
|
||||
client.newCall(request().post(RequestBody.create(PLAIN, "Hi?")).build()).execute();
|
||||
|
||||
assertEquals(2, logs.size());
|
||||
assertEquals("--> POST / HTTP/1.1 (3-byte body)", logs.get(0));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms, 0-byte body\\)", logs.get(1)));
|
||||
}
|
||||
|
||||
@Test public void basicResponseBody() throws IOException {
|
||||
interceptor.setLevel(Level.BASIC);
|
||||
|
||||
server.enqueue(new MockResponse()
|
||||
.setBody("Hello!")
|
||||
.setHeader("Content-Type", PLAIN.toString()));
|
||||
client.newCall(request().build()).execute();
|
||||
|
||||
assertEquals(2, logs.size());
|
||||
assertEquals("--> GET / HTTP/1.1", logs.get(0));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms, 6-byte body\\)", logs.get(1)));
|
||||
}
|
||||
|
||||
@Test public void headersGet() throws IOException {
|
||||
interceptor.setLevel(Level.HEADERS);
|
||||
|
||||
server.enqueue(new MockResponse());
|
||||
client.newCall(request().build()).execute();
|
||||
|
||||
assertEquals(12, logs.size());
|
||||
assertEquals("--> GET / HTTP/1.1", logs.get(0));
|
||||
assertEquals("Host: " + server.getHostName() + ":" + server.getPort(), logs.get(1));
|
||||
assertEquals("Connection: Keep-Alive", logs.get(2));
|
||||
assertEquals("Accept-Encoding: gzip", logs.get(3));
|
||||
assertTrue(Pattern.matches("User-Agent: okhttp/.+", logs.get(4)));
|
||||
assertEquals("--> END GET", logs.get(5));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms\\)", logs.get(6)));
|
||||
assertEquals("Content-Length: 0", logs.get(7));
|
||||
assertEquals("OkHttp-Selected-Protocol: http/1.1", logs.get(8));
|
||||
assertTrue(Pattern.matches("OkHttp-Sent-Millis: \\d+", logs.get(9)));
|
||||
assertTrue(Pattern.matches("OkHttp-Received-Millis: \\d+", logs.get(10)));
|
||||
assertEquals("<-- END HTTP", logs.get(11));
|
||||
}
|
||||
|
||||
@Test public void headersPost() throws IOException {
|
||||
interceptor.setLevel(Level.HEADERS);
|
||||
|
||||
server.enqueue(new MockResponse());
|
||||
client.newCall(request().post(RequestBody.create(PLAIN, "Hi?")).build()).execute();
|
||||
|
||||
assertEquals(14, logs.size());
|
||||
assertEquals("--> POST / HTTP/1.1", logs.get(0));
|
||||
assertEquals("Content-Type: text/plain; charset=utf-8", logs.get(1));
|
||||
assertEquals("Content-Length: 3", logs.get(2));
|
||||
assertEquals("Host: " + server.getHostName() + ":" + server.getPort(), logs.get(3));
|
||||
assertEquals("Connection: Keep-Alive", logs.get(4));
|
||||
assertEquals("Accept-Encoding: gzip", logs.get(5));
|
||||
assertTrue(Pattern.matches("User-Agent: okhttp/.+", logs.get(6)));
|
||||
assertEquals("--> END POST", logs.get(7));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms\\)", logs.get(8)));
|
||||
assertEquals("Content-Length: 0", logs.get(9));
|
||||
assertEquals("OkHttp-Selected-Protocol: http/1.1", logs.get(10));
|
||||
assertTrue(Pattern.matches("OkHttp-Sent-Millis: \\d+", logs.get(11)));
|
||||
assertTrue(Pattern.matches("OkHttp-Received-Millis: \\d+", logs.get(12)));
|
||||
assertEquals("<-- END HTTP", logs.get(13));
|
||||
}
|
||||
|
||||
@Test public void headersResponseBody() throws IOException {
|
||||
interceptor.setLevel(Level.HEADERS);
|
||||
|
||||
server.enqueue(new MockResponse()
|
||||
.setBody("Hello!")
|
||||
.setHeader("Content-Type", PLAIN.toString()));
|
||||
client.newCall(request().build()).execute();
|
||||
|
||||
assertEquals(13, logs.size());
|
||||
assertEquals("--> GET / HTTP/1.1", logs.get(0));
|
||||
assertEquals("Host: " + server.getHostName() + ":" + server.getPort(), logs.get(1));
|
||||
assertEquals("Connection: Keep-Alive", logs.get(2));
|
||||
assertEquals("Accept-Encoding: gzip", logs.get(3));
|
||||
assertTrue(Pattern.matches("User-Agent: okhttp/.+", logs.get(4)));
|
||||
assertEquals("--> END GET", logs.get(5));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms\\)", logs.get(6)));
|
||||
assertEquals("Content-Length: 6", logs.get(7));
|
||||
assertEquals("Content-Type: text/plain; charset=utf-8", logs.get(8));
|
||||
assertEquals("OkHttp-Selected-Protocol: http/1.1", logs.get(9));
|
||||
assertTrue(Pattern.matches("OkHttp-Sent-Millis: \\d+", logs.get(10)));
|
||||
assertTrue(Pattern.matches("OkHttp-Received-Millis: \\d+", logs.get(11)));
|
||||
assertEquals("<-- END HTTP", logs.get(12));
|
||||
}
|
||||
|
||||
@Test public void bodyGet() throws IOException {
|
||||
interceptor.setLevel(Level.BODY);
|
||||
|
||||
server.enqueue(new MockResponse());
|
||||
client.newCall(request().build()).execute();
|
||||
|
||||
assertEquals(12, logs.size());
|
||||
assertEquals("--> GET / HTTP/1.1", logs.get(0));
|
||||
assertEquals("Host: " + server.getHostName() + ":" + server.getPort(), logs.get(1));
|
||||
assertEquals("Connection: Keep-Alive", logs.get(2));
|
||||
assertEquals("Accept-Encoding: gzip", logs.get(3));
|
||||
assertTrue(Pattern.matches("User-Agent: okhttp/.+", logs.get(4)));
|
||||
assertEquals("--> END GET", logs.get(5));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms\\)", logs.get(6)));
|
||||
assertEquals("Content-Length: 0", logs.get(7));
|
||||
assertEquals("OkHttp-Selected-Protocol: http/1.1", logs.get(8));
|
||||
assertTrue(Pattern.matches("OkHttp-Sent-Millis: \\d+", logs.get(9)));
|
||||
assertTrue(Pattern.matches("OkHttp-Received-Millis: \\d+", logs.get(10)));
|
||||
assertEquals("<-- END HTTP (0-byte body)", logs.get(11));
|
||||
}
|
||||
|
||||
@Test public void bodyPost() throws IOException {
|
||||
interceptor.setLevel(Level.BODY);
|
||||
|
||||
server.enqueue(new MockResponse());
|
||||
client.newCall(request().post(RequestBody.create(PLAIN, "Hi?")).build()).execute();
|
||||
|
||||
assertEquals(16, logs.size());
|
||||
assertEquals("--> POST / HTTP/1.1", logs.get(0));
|
||||
assertEquals("Content-Type: text/plain; charset=utf-8", logs.get(1));
|
||||
assertEquals("Content-Length: 3", logs.get(2));
|
||||
assertEquals("Host: " + server.getHostName() + ":" + server.getPort(), logs.get(3));
|
||||
assertEquals("Connection: Keep-Alive", logs.get(4));
|
||||
assertEquals("Accept-Encoding: gzip", logs.get(5));
|
||||
assertTrue(Pattern.matches("User-Agent: okhttp/.+", logs.get(6)));
|
||||
assertEquals("", logs.get(7));
|
||||
assertEquals("Hi?", logs.get(8));
|
||||
assertEquals("--> END POST (3-byte body)", logs.get(9));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms\\)", logs.get(10)));
|
||||
assertEquals("Content-Length: 0", logs.get(11));
|
||||
assertEquals("OkHttp-Selected-Protocol: http/1.1", logs.get(12));
|
||||
assertTrue(Pattern.matches("OkHttp-Sent-Millis: \\d+", logs.get(13)));
|
||||
assertTrue(Pattern.matches("OkHttp-Received-Millis: \\d+", logs.get(14)));
|
||||
assertEquals("<-- END HTTP (0-byte body)", logs.get(15));
|
||||
}
|
||||
|
||||
@Test public void bodyResponseBody() throws IOException {
|
||||
interceptor.setLevel(Level.BODY);
|
||||
|
||||
server.enqueue(new MockResponse()
|
||||
.setBody("Hello!")
|
||||
.setHeader("Content-Type", PLAIN.toString()));
|
||||
client.newCall(request().build()).execute();
|
||||
|
||||
assertEquals(15, logs.size());
|
||||
assertEquals("--> GET / HTTP/1.1", logs.get(0));
|
||||
assertEquals("Host: " + server.getHostName() + ":" + server.getPort(), logs.get(1));
|
||||
assertEquals("Connection: Keep-Alive", logs.get(2));
|
||||
assertEquals("Accept-Encoding: gzip", logs.get(3));
|
||||
assertTrue(Pattern.matches("User-Agent: okhttp/.+", logs.get(4)));
|
||||
assertEquals("--> END GET", logs.get(5));
|
||||
assertTrue(Pattern.matches("<-- HTTP/1\\.1 200 OK \\(\\d+ms\\)", logs.get(6)));
|
||||
assertEquals("Content-Length: 6", logs.get(7));
|
||||
assertEquals("Content-Type: text/plain; charset=utf-8", logs.get(8));
|
||||
assertEquals("OkHttp-Selected-Protocol: http/1.1", logs.get(9));
|
||||
assertTrue(Pattern.matches("OkHttp-Sent-Millis: \\d+", logs.get(10)));
|
||||
assertTrue(Pattern.matches("OkHttp-Received-Millis: \\d+", logs.get(11)));
|
||||
assertEquals("", logs.get(12));
|
||||
assertEquals("Hello!", logs.get(13));
|
||||
assertEquals("<-- END HTTP (6-byte body)", logs.get(14));
|
||||
}
|
||||
|
||||
private Request.Builder request() {
|
||||
return new Request.Builder().url(server.url("/"));
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,11 @@
|
||||
<groupId>com.squareup.okio</groupId>
|
||||
<artifactId>okio</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.squareup.okhttp.internal;
|
||||
|
||||
import android.util.Log;
|
||||
import com.squareup.okhttp.Protocol;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
@@ -100,6 +101,10 @@ public class Platform {
|
||||
socket.connect(address, connectTimeout);
|
||||
}
|
||||
|
||||
public void log(String message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
/** Attempt to match the host runtime to a capable Platform implementation. */
|
||||
private static Platform findPlatform() {
|
||||
// Attempt to find Android 2.3+ APIs.
|
||||
@@ -162,6 +167,8 @@ public class Platform {
|
||||
|
||||
/** Android 2.3 or better. */
|
||||
private static class Android extends Platform {
|
||||
private static final int MAX_LOG_LENGTH = 4000;
|
||||
|
||||
private final OptionalMethod<Socket> setUseSessionTickets;
|
||||
private final OptionalMethod<Socket> setHostname;
|
||||
|
||||
@@ -243,6 +250,19 @@ public class Platform {
|
||||
throw new RuntimeException(e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void log(String message) {
|
||||
// Split by line, then ensure each line can fit into Log's maximum length.
|
||||
for (int i = 0, length = message.length(); i < length; i++) {
|
||||
int newline = message.indexOf('\n', i);
|
||||
newline = newline != -1 ? newline : length;
|
||||
do {
|
||||
int end = Math.min(newline, i + MAX_LOG_LENGTH);
|
||||
Log.d("OkHttp", message.substring(i, end));
|
||||
i = end;
|
||||
} while (i < newline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
8
pom.xml
8
pom.xml
@@ -31,6 +31,8 @@
|
||||
<module>okhttp-ws</module>
|
||||
<module>okhttp-ws-tests</module>
|
||||
|
||||
<module>okhttp-logging-interceptor</module>
|
||||
|
||||
<module>okcurl</module>
|
||||
<module>mockwebserver</module>
|
||||
<module>samples</module>
|
||||
@@ -52,6 +54,7 @@
|
||||
<apache.http.version>4.2.2</apache.http.version>
|
||||
<airlift.version>0.6</airlift.version>
|
||||
<guava.version>16.0</guava.version>
|
||||
<android.version>4.1.1.4</android.version>
|
||||
|
||||
<!-- Test Dependencies -->
|
||||
<junit.version>4.11</junit.version>
|
||||
@@ -113,6 +116,11 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<version>${android.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user