mirror of
https://github.com/square/okhttp.git
synced 2025-11-26 06:43:09 +03:00
Run in CircleCI. Also conditionally disables tests that show issues with Conscrypt/OkHttp (client auth etc).
871 lines
31 KiB
Java
871 lines
31 KiB
Java
/*
|
|
* 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 okhttp3.logging;
|
|
|
|
import java.io.IOException;
|
|
import java.net.UnknownHostException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.regex.Pattern;
|
|
import javax.annotation.Nullable;
|
|
import javax.net.ssl.HostnameVerifier;
|
|
import okhttp3.HttpUrl;
|
|
import okhttp3.MediaType;
|
|
import okhttp3.OkHttpClient;
|
|
import okhttp3.Protocol;
|
|
import okhttp3.RecordingHostnameVerifier;
|
|
import okhttp3.Request;
|
|
import okhttp3.RequestBody;
|
|
import okhttp3.Response;
|
|
import okhttp3.ResponseBody;
|
|
import okhttp3.logging.HttpLoggingInterceptor.Level;
|
|
import okhttp3.mockwebserver.MockResponse;
|
|
import okhttp3.mockwebserver.MockWebServer;
|
|
import okhttp3.tls.HandshakeCertificates;
|
|
import okio.Buffer;
|
|
import okio.BufferedSink;
|
|
import okio.ByteString;
|
|
import org.junit.Before;
|
|
import org.junit.Rule;
|
|
import org.junit.Test;
|
|
|
|
import static okhttp3.tls.internal.TlsUtil.localhost;
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.hamcrest.CoreMatchers.equalTo;
|
|
import static org.junit.Assert.fail;
|
|
import static org.junit.Assume.assumeThat;
|
|
|
|
public final class HttpLoggingInterceptorTest {
|
|
private static final MediaType PLAIN = MediaType.get("text/plain; charset=utf-8");
|
|
|
|
@Rule public final MockWebServer server = new MockWebServer();
|
|
|
|
private final HandshakeCertificates handshakeCertificates = localhost();
|
|
private final HostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
|
|
private OkHttpClient client;
|
|
private String host;
|
|
private HttpUrl url;
|
|
|
|
private final LogRecorder networkLogs = new LogRecorder();
|
|
private final HttpLoggingInterceptor networkInterceptor =
|
|
new HttpLoggingInterceptor(networkLogs);
|
|
|
|
private final LogRecorder applicationLogs = new LogRecorder();
|
|
private final HttpLoggingInterceptor applicationInterceptor =
|
|
new HttpLoggingInterceptor(applicationLogs);
|
|
|
|
private void setLevel(Level level) {
|
|
networkInterceptor.setLevel(level);
|
|
applicationInterceptor.setLevel(level);
|
|
}
|
|
|
|
@Before public void setUp() {
|
|
client = new OkHttpClient.Builder()
|
|
.addNetworkInterceptor(networkInterceptor)
|
|
.addInterceptor(applicationInterceptor)
|
|
.sslSocketFactory(
|
|
handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager())
|
|
.hostnameVerifier(hostnameVerifier)
|
|
.build();
|
|
|
|
host = server.getHostName() + ":" + server.getPort();
|
|
url = server.url("/");
|
|
}
|
|
|
|
@Test public void levelGetter() {
|
|
// The default is NONE.
|
|
assertThat(applicationInterceptor.getLevel()).isEqualTo(Level.NONE);
|
|
|
|
for (Level level : Level.values()) {
|
|
applicationInterceptor.setLevel(level);
|
|
assertThat(applicationInterceptor.getLevel()).isEqualTo(level);
|
|
}
|
|
}
|
|
|
|
@Test public void setLevelShouldPreventNullValue() {
|
|
try {
|
|
applicationInterceptor.setLevel(null);
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
}
|
|
|
|
@Test public void setLevelShouldReturnSameInstanceOfInterceptor() {
|
|
for (Level level : Level.values()) {
|
|
assertThat(applicationInterceptor.setLevel(level)).isSameAs(applicationInterceptor);
|
|
}
|
|
}
|
|
|
|
@Test public void none() throws IOException {
|
|
server.enqueue(new MockResponse());
|
|
client.newCall(request().build()).execute();
|
|
|
|
applicationLogs.assertNoMoreLogs();
|
|
networkLogs.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void basicGet() throws IOException {
|
|
setLevel(Level.BASIC);
|
|
|
|
server.enqueue(new MockResponse());
|
|
client.newCall(request().build()).execute();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, 0-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, 0-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void basicPost() throws IOException {
|
|
setLevel(Level.BASIC);
|
|
|
|
server.enqueue(new MockResponse());
|
|
client.newCall(request().post(RequestBody.create(PLAIN, "Hi?")).build()).execute();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> POST " + url + " (3-byte body)")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, 0-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> POST " + url + " http/1.1 (3-byte body)")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, 0-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void basicResponseBody() throws IOException {
|
|
setLevel(Level.BASIC);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setBody("Hello!")
|
|
.setHeader("Content-Type", PLAIN));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, 6-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, 6-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void basicChunkedResponseBody() throws IOException {
|
|
setLevel(Level.BASIC);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setChunkedBody("Hello!", 2)
|
|
.setHeader("Content-Type", PLAIN));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, unknown-length body\\)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms, unknown-length body\\)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void headersGet() throws IOException {
|
|
setLevel(Level.HEADERS);
|
|
|
|
server.enqueue(new MockResponse());
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void headersPost() throws IOException {
|
|
setLevel(Level.HEADERS);
|
|
|
|
server.enqueue(new MockResponse());
|
|
Request request = request().post(RequestBody.create(PLAIN, "Hi?")).build();
|
|
Response response = client.newCall(request).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> POST " + url)
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("Content-Length: 3")
|
|
.assertLogEqual("--> END POST")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> POST " + url + " http/1.1")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("Content-Length: 3")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END POST")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void headersPostNoContentType() throws IOException {
|
|
setLevel(Level.HEADERS);
|
|
|
|
server.enqueue(new MockResponse());
|
|
Request request = request().post(RequestBody.create(null, "Hi?")).build();
|
|
Response response = client.newCall(request).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> POST " + url)
|
|
.assertLogEqual("Content-Length: 3")
|
|
.assertLogEqual("--> END POST")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> POST " + url + " http/1.1")
|
|
.assertLogEqual("Content-Length: 3")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END POST")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void headersPostNoLength() throws IOException {
|
|
setLevel(Level.HEADERS);
|
|
|
|
server.enqueue(new MockResponse());
|
|
RequestBody body = new RequestBody() {
|
|
@Override public MediaType contentType() {
|
|
return PLAIN;
|
|
}
|
|
|
|
@Override public void writeTo(BufferedSink sink) throws IOException {
|
|
sink.writeUtf8("Hi!");
|
|
}
|
|
};
|
|
Response response = client.newCall(request().post(body).build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> POST " + url)
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("--> END POST")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> POST " + url + " http/1.1")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("Transfer-Encoding: chunked")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END POST")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void headersResponseBody() throws IOException {
|
|
setLevel(Level.HEADERS);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setBody("Hello!")
|
|
.setHeader("Content-Type", PLAIN));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 6")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 6")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyGet() throws IOException {
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse());
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP (0-byte body)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP (0-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyGet204() throws IOException {
|
|
setLevel(Level.BODY);
|
|
bodyGetNoBody(204);
|
|
}
|
|
|
|
@Test public void bodyGet205() throws IOException {
|
|
setLevel(Level.BODY);
|
|
bodyGetNoBody(205);
|
|
}
|
|
|
|
private void bodyGetNoBody(int code) throws IOException {
|
|
server.enqueue(new MockResponse()
|
|
.setStatus("HTTP/1.1 " + code + " No Content"));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- " + code + " No Content " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP (0-byte body)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- " + code + " No Content " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP (0-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyPost() throws IOException {
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse());
|
|
Request request = request().post(RequestBody.create(PLAIN, "Hi?")).build();
|
|
Response response = client.newCall(request).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> POST " + url)
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("Content-Length: 3")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hi?")
|
|
.assertLogEqual("--> END POST (3-byte body)")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP (0-byte body)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> POST " + url + " http/1.1")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("Content-Length: 3")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hi?")
|
|
.assertLogEqual("--> END POST (3-byte body)")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("<-- END HTTP (0-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyResponseBody() throws IOException {
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setBody("Hello!")
|
|
.setHeader("Content-Type", PLAIN));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 6")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hello!")
|
|
.assertLogEqual("<-- END HTTP (6-byte body)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 6")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hello!")
|
|
.assertLogEqual("<-- END HTTP (6-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyResponseBodyChunked() throws IOException {
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setChunkedBody("Hello!", 2)
|
|
.setHeader("Content-Type", PLAIN));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Transfer-encoding: chunked")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hello!")
|
|
.assertLogEqual("<-- END HTTP (6-byte body)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Transfer-encoding: chunked")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hello!")
|
|
.assertLogEqual("<-- END HTTP (6-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyResponseGzipEncoded() throws IOException {
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setHeader("Content-Encoding", "gzip")
|
|
.setHeader("Content-Type", PLAIN)
|
|
.setBody(new Buffer().write(ByteString.decodeBase64(
|
|
"H4sIAAAAAAAAAPNIzcnJ11HwQKIAdyO+9hMAAAA="))));
|
|
Response response = client.newCall(request().build()).execute();
|
|
|
|
ResponseBody responseBody = response.body();
|
|
assertThat(responseBody.string()).overridingErrorMessage(
|
|
"Expected response body to be valid").isEqualTo("Hello, Hello, Hello");
|
|
responseBody.close();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Encoding: gzip")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogMatch("Content-Length: \\d+")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hello, Hello, Hello")
|
|
.assertLogEqual("<-- END HTTP (19-byte, 29-gzipped-byte body)")
|
|
.assertNoMoreLogs();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hello, Hello, Hello")
|
|
.assertLogEqual("<-- END HTTP (19-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyResponseUnknownEncoded() throws IOException {
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse()
|
|
// It's invalid to return this if not requested, but the server might anyway
|
|
.setHeader("Content-Encoding", "br")
|
|
.setHeader("Content-Type", PLAIN)
|
|
.setBody(new Buffer().write(ByteString.decodeBase64(
|
|
"iwmASGVsbG8sIEhlbGxvLCBIZWxsbwoD"))));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Encoding: br")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogMatch("Content-Length: \\d+")
|
|
.assertLogEqual("<-- END HTTP (encoded body omitted)")
|
|
.assertNoMoreLogs();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Encoding: br")
|
|
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
|
.assertLogMatch("Content-Length: \\d+")
|
|
.assertLogEqual("<-- END HTTP (encoded body omitted)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void bodyGetMalformedCharset() throws IOException {
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setHeader("Content-Type", "text/html; charset=0")
|
|
.setBody("Body with unknown charset"));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Type: text/html; charset=0")
|
|
.assertLogMatch("Content-Length: \\d+")
|
|
.assertLogMatch("")
|
|
.assertLogEqual("Body with unknown charset")
|
|
.assertLogEqual("<-- END HTTP (25-byte body)")
|
|
.assertNoMoreLogs();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Type: text/html; charset=0")
|
|
.assertLogMatch("Content-Length: \\d+")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Body with unknown charset")
|
|
.assertLogEqual("<-- END HTTP (25-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void isPlaintext() {
|
|
assertThat(HttpLoggingInterceptor.isPlaintext(new Buffer())).isTrue();
|
|
assertThat(HttpLoggingInterceptor.isPlaintext(new Buffer().writeUtf8("abc"))).isTrue();
|
|
assertThat(HttpLoggingInterceptor.isPlaintext(new Buffer().writeUtf8("new\r\nlines"))).isTrue();
|
|
assertThat(HttpLoggingInterceptor.isPlaintext(new Buffer().writeUtf8("white\t space"))).isTrue();
|
|
assertThat(HttpLoggingInterceptor.isPlaintext(new Buffer().writeByte(0x80))).isTrue();
|
|
assertThat(HttpLoggingInterceptor.isPlaintext(new Buffer().writeByte(0x00))).isFalse();
|
|
assertThat(HttpLoggingInterceptor.isPlaintext(new Buffer().writeByte(0xc0))).isFalse();
|
|
}
|
|
|
|
@Test public void responseBodyIsBinary() throws IOException {
|
|
setLevel(Level.BODY);
|
|
Buffer buffer = new Buffer();
|
|
buffer.writeUtf8CodePoint(0x89);
|
|
buffer.writeUtf8CodePoint(0x50);
|
|
buffer.writeUtf8CodePoint(0x4e);
|
|
buffer.writeUtf8CodePoint(0x47);
|
|
buffer.writeUtf8CodePoint(0x0d);
|
|
buffer.writeUtf8CodePoint(0x0a);
|
|
buffer.writeUtf8CodePoint(0x1a);
|
|
buffer.writeUtf8CodePoint(0x0a);
|
|
server.enqueue(new MockResponse()
|
|
.setBody(buffer)
|
|
.setHeader("Content-Type", "image/png; charset=utf-8"));
|
|
Response response = client.newCall(request().build()).execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 9")
|
|
.assertLogEqual("Content-Type: image/png; charset=utf-8")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("<-- END HTTP (binary 9-byte body omitted)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 9")
|
|
.assertLogEqual("Content-Type: image/png; charset=utf-8")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("<-- END HTTP (binary 9-byte body omitted)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void connectFail() throws IOException {
|
|
setLevel(Level.BASIC);
|
|
client = new OkHttpClient.Builder()
|
|
.dns(hostname -> { throw new UnknownHostException("reason"); })
|
|
.addInterceptor(applicationInterceptor)
|
|
.build();
|
|
|
|
try {
|
|
client.newCall(request().build()).execute();
|
|
fail();
|
|
} catch (UnknownHostException expected) {
|
|
}
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("<-- HTTP FAILED: java.net.UnknownHostException: reason")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void http2() throws Exception {
|
|
server.useHttps(handshakeCertificates.sslSocketFactory(), false);
|
|
url = server.url("/");
|
|
|
|
setLevel(Level.BASIC);
|
|
|
|
server.enqueue(new MockResponse());
|
|
Response response = client.newCall(request().build()).execute();
|
|
assumeThat(response.protocol(), equalTo(Protocol.HTTP_2));
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogMatch("<-- 200 " + url + " \\(\\d+ms, 0-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " h2")
|
|
.assertLogMatch("<-- 200 " + url + " \\(\\d+ms, 0-byte body\\)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test
|
|
public void headersAreRedacted() throws Exception {
|
|
HttpLoggingInterceptor networkInterceptor =
|
|
new HttpLoggingInterceptor(networkLogs).setLevel(Level.HEADERS);
|
|
networkInterceptor.redactHeader("sEnSiTiVe");
|
|
|
|
HttpLoggingInterceptor applicationInterceptor =
|
|
new HttpLoggingInterceptor(applicationLogs).setLevel(Level.HEADERS);
|
|
applicationInterceptor.redactHeader("sEnSiTiVe");
|
|
|
|
client =
|
|
new OkHttpClient.Builder()
|
|
.addNetworkInterceptor(networkInterceptor)
|
|
.addInterceptor(applicationInterceptor)
|
|
.build();
|
|
|
|
server.enqueue(
|
|
new MockResponse().addHeader("SeNsItIvE", "Value").addHeader("Not-Sensitive", "Value"));
|
|
Response response =
|
|
client
|
|
.newCall(
|
|
request()
|
|
.addHeader("SeNsItIvE", "Value")
|
|
.addHeader("Not-Sensitive", "Value")
|
|
.build())
|
|
.execute();
|
|
response.body().close();
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> GET " + url)
|
|
.assertLogEqual("SeNsItIvE: ██")
|
|
.assertLogEqual("Not-Sensitive: Value")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("SeNsItIvE: ██")
|
|
.assertLogEqual("Not-Sensitive: Value")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
|
|
networkLogs
|
|
.assertLogEqual("--> GET " + url + " http/1.1")
|
|
.assertLogEqual("SeNsItIvE: ██")
|
|
.assertLogEqual("Not-Sensitive: Value")
|
|
.assertLogEqual("Host: " + host)
|
|
.assertLogEqual("Connection: Keep-Alive")
|
|
.assertLogEqual("Accept-Encoding: gzip")
|
|
.assertLogMatch("User-Agent: okhttp/.+")
|
|
.assertLogEqual("--> END GET")
|
|
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("Content-Length: 0")
|
|
.assertLogEqual("SeNsItIvE: ██")
|
|
.assertLogEqual("Not-Sensitive: Value")
|
|
.assertLogEqual("<-- END HTTP")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
@Test public void duplexRequestsAreNotLogged() throws Exception {
|
|
server.useHttps(handshakeCertificates.sslSocketFactory(), false); // HTTP/2
|
|
url = server.url("/");
|
|
|
|
setLevel(Level.BODY);
|
|
|
|
server.enqueue(new MockResponse()
|
|
.setBody("Hello response!"));
|
|
|
|
RequestBody asyncRequestBody = new RequestBody() {
|
|
@Override public @Nullable MediaType contentType() {
|
|
return null;
|
|
}
|
|
|
|
@Override public void writeTo(BufferedSink sink) throws IOException {
|
|
sink.writeUtf8("Hello request!");
|
|
sink.close();
|
|
}
|
|
|
|
@Override public boolean isDuplex() {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
Request request = request()
|
|
.post(asyncRequestBody)
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
assumeThat(response.protocol(), equalTo(Protocol.HTTP_2));
|
|
|
|
assertThat(response.body().string()).isEqualTo("Hello response!");
|
|
|
|
applicationLogs
|
|
.assertLogEqual("--> POST " + url)
|
|
.assertLogEqual("--> END POST (duplex request body omitted)")
|
|
.assertLogMatch("<-- 200 " + url + " \\(\\d+ms\\)")
|
|
.assertLogEqual("content-length: 15")
|
|
.assertLogEqual("")
|
|
.assertLogEqual("Hello response!")
|
|
.assertLogEqual("<-- END HTTP (15-byte body)")
|
|
.assertNoMoreLogs();
|
|
}
|
|
|
|
private Request.Builder request() {
|
|
return new Request.Builder().url(url);
|
|
}
|
|
|
|
static class LogRecorder implements HttpLoggingInterceptor.Logger {
|
|
private final List<String> logs = new ArrayList<>();
|
|
private int index;
|
|
|
|
LogRecorder assertLogEqual(String expected) {
|
|
assertThat(index).overridingErrorMessage("No more messages found").isLessThan(logs.size());
|
|
String actual = logs.get(index++);
|
|
assertThat(actual).isEqualTo(expected);
|
|
return this;
|
|
}
|
|
|
|
LogRecorder assertLogMatch(String pattern) {
|
|
assertThat(index).overridingErrorMessage("No more messages found").isLessThan(logs.size());
|
|
String actual = logs.get(index++);
|
|
assertThat(actual).matches(Pattern.compile(pattern, Pattern.DOTALL));
|
|
return this;
|
|
}
|
|
|
|
void assertNoMoreLogs() {
|
|
assertThat(logs.size()).overridingErrorMessage(
|
|
"More messages remain: " + logs.subList(index, logs.size())).isEqualTo(index);
|
|
}
|
|
|
|
@Override public void log(String message) {
|
|
logs.add(message);
|
|
}
|
|
}
|
|
}
|