question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: HttpLoggingInterceptor.Level.BODY breaks a streaming request

See original GitHub issue

I’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:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
sammeffordcommented, May 1, 2017

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.

0reactions
sammeffordcommented, Nov 17, 2017

Someone else reported the same issue: #3157

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found