mirror of
https://github.com/square/okhttp.git
synced 2025-11-26 06:43:09 +03:00
Log plain text bodies only
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package okhttp3.logging;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
@@ -192,10 +193,14 @@ public final class HttpLoggingInterceptor implements Interceptor {
|
||||
}
|
||||
|
||||
logger.log("");
|
||||
logger.log(buffer.readString(charset));
|
||||
|
||||
logger.log("--> END " + request.method()
|
||||
+ " (" + requestBody.contentLength() + "-byte body)");
|
||||
if (isPlaintext(buffer)) {
|
||||
logger.log(buffer.readString(charset));
|
||||
logger.log("--> END " + request.method()
|
||||
+ " (" + requestBody.contentLength() + "-byte body)");
|
||||
} else {
|
||||
logger.log("--> END " + request.method() + " (binary "
|
||||
+ requestBody.contentLength() + "-byte body omitted)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +244,12 @@ public final class HttpLoggingInterceptor implements Interceptor {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isPlaintext(buffer)) {
|
||||
logger.log("");
|
||||
logger.log("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)");
|
||||
return response;
|
||||
}
|
||||
|
||||
if (contentLength != 0) {
|
||||
logger.log("");
|
||||
logger.log(buffer.clone().readString(charset));
|
||||
@@ -251,6 +262,29 @@ public final class HttpLoggingInterceptor implements Interceptor {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the body in question probably contains human readable text. Uses a small sample
|
||||
* of code points to detect unicode control characters commonly used in binary file signatures.
|
||||
*/
|
||||
static boolean isPlaintext(Buffer buffer) throws EOFException {
|
||||
try {
|
||||
Buffer prefix = new Buffer();
|
||||
long byteCount = buffer.size() < 64 ? buffer.size() : 64;
|
||||
buffer.copyTo(prefix, 0, byteCount);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (prefix.exhausted()) {
|
||||
break;
|
||||
}
|
||||
if (Character.isISOControl(prefix.readUtf8CodePoint())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (EOFException e) {
|
||||
return false; // Truncated UTF-8 sequence.
|
||||
}
|
||||
}
|
||||
|
||||
private boolean bodyEncoded(Headers headers) {
|
||||
String contentEncoding = headers.get("Content-Encoding");
|
||||
return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity");
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -638,6 +639,60 @@ public final class HttpLoggingInterceptorTest {
|
||||
.assertNoMoreLogs();
|
||||
}
|
||||
|
||||
@Test public void isPlaintext() throws IOException {
|
||||
assertTrue(HttpLoggingInterceptor.isPlaintext(new Buffer()));
|
||||
assertTrue(HttpLoggingInterceptor.isPlaintext(new Buffer().writeUtf8("abc")));
|
||||
assertTrue(HttpLoggingInterceptor.isPlaintext(new Buffer().writeByte(0x80)));
|
||||
assertFalse(HttpLoggingInterceptor.isPlaintext(new Buffer().writeByte(0x00)));
|
||||
assertFalse(HttpLoggingInterceptor.isPlaintext(new Buffer().writeByte(0xc0)));
|
||||
}
|
||||
|
||||
@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 + " http/1.1")
|
||||
.assertLogEqual("--> END GET")
|
||||
.assertLogMatch("<-- 200 OK " + url + " \\(\\d+ms\\)")
|
||||
.assertLogEqual("Content-Length: 9")
|
||||
.assertLogEqual("Content-Type: image/png; charset=utf-8")
|
||||
.assertLogMatch("OkHttp-Sent-Millis: \\d+")
|
||||
.assertLogMatch("OkHttp-Received-Millis: \\d+")
|
||||
.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")
|
||||
.assertLogMatch("OkHttp-Sent-Millis: \\d+")
|
||||
.assertLogMatch("OkHttp-Received-Millis: \\d+")
|
||||
.assertLogEqual("")
|
||||
.assertLogEqual("<-- END HTTP (binary 9-byte body omitted)")
|
||||
.assertNoMoreLogs();
|
||||
}
|
||||
|
||||
private Request.Builder request() {
|
||||
return new Request.Builder().url(url);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user