Bug: HttpLoggingInterceptor.Level.BODY breaks a streaming request
See original GitHub issueI’d like to report what I believe is a bug in HttpLoggingInterceptor.
The following fails to send the request body because of setLevel(HttpLogginInterceptor.Level.BODY)
. I’m guessing the HttpLoggingInterceptor reads from the stream which prevents the stream from making it to the request body. Rather than throw an error, the request silently proceeds with an empty request body. I could only validate this by using wireshark to inspect the network traffic. Without the setLevel
call the request body had the expected chunk size and binary data in the request body. With the setLevel
call the request body had just a chunk size of 0 and no request body.
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import okio.BufferedSink;
public class OkHttpMinimalPut {
public static void main(String[] args) throws IOException {
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(
new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
Request request = new Request.Builder()
.url(
new HttpUrl.Builder()
.scheme("http")
.host(args[0])
.port(Integer.parseInt(args[1]))
.addPathSegments("my/endpoint")
.addQueryParameter("fileName", "OkHttpMinimalPut.class")
.build()
)
.put(getJavaClass())
.build();
try ( Response response = client.newCall(request).execute() ) {
System.out.println("response=" + response.toString());
}
}
private static RequestBody getJavaClass() {
InputStream thisClass = OkHttpMinimalPut.class.getResourceAsStream("OkHttpMinimalPut.class");
return new RequestBody() {
@Override public MediaType contentType() {
return MediaType.parse("application/octet-stream");
}
@Override public void writeTo(BufferedSink sink) throws IOException {
byte[] data = new byte[1024];
int bytesRead;
while ( (bytesRead = thisClass.read(data)) > 0 ) {
sink.write(data, 0, bytesRead);
}
}
};
}
}
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:8 (3 by maintainers)
Top Results From Across the Web
okhttp loggin interceptor in multipart - Stack Overflow
I am trying to upload an image using okHTTP multi part into a server. the server does not accept my request ...
Read more >HttpLoggingInterceptor.Level (OkHttp Logging Interceptor 3.14 ...
Logs request and response lines. BODY. Logs request and response lines and their respective headers and bodies (if present).
Read more >Java – HttpLoggingInterceptor for http request & response logging ...
I'm using retrofit2 and I need to log all request and response. Request and response works ... setLevel(HttpLoggingInterceptor.Level.BODY); httpClient.
Read more >Retrofit 2 — How to Download Files from Server - Future Studio
In this blog post of our Retrofit launch sequence we'll show you one of the most requested topics: how to download files.
Read more >Example usage for com.squareup.okhttp Request httpUrl - Java2s.com
Usage · Override public · Response intercept(Chain chain) throws · IOException { · Level level = this.level; Request request = chain. · Level.NONE)...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’m not looking for a work-around. As I said in my original post, I used wireshark to validate this issue. So I can monitor/debug fine without Level.BODY.
I just logged this issue as a courtesy to your project. It would be unfortunate if others experienced what I did as I was getting started with OkHttp. It just made sense to me to use Level.BODY as I was learning so I could see that requests and responses were going through properly. But that put me in the uncomfortable situation of my code not working as the examples said it should. It took an unfortunate amount of effort to discover that it was HttpLoggingInterceptor that was breaking my code.
What if HttpLoggingInterceptor just output something like this in this scenario?
[streaming body cannot be intercepted]
That way I can still see in the logging that the streaming body is there and being sent even if it cannot be logged. And my code will not break because I have logging enabled.
Someone else reported the same issue: #3157