Fix Stream Closed IOException

Summary:
Original Issue: https://github.com/facebook/flipper/issues/993

The exception occurs when OkHttp and we try to read request body twice, while it can be only read once.

Hence, we will read request body after it is processed by OkHttp.

Tradeoff for this is requests on Flipper will not appear immediately after fired, but they will appear together with their responses.

There are ways we can get rid of the tradeoff. For example, as demonstrated in D21167308, OkHttp ^3.14.0 contains method `isOneShot`, which can be used to check if we can read request body more than once. Another example is to change server side to accept nullable variable so that we can send request body and others separately.

Reviewed By: passy

Differential Revision: D21175341

fbshipit-source-id: 053789a2c2f28cd8149ea1bb36fd0cfe1c668df7
This commit is contained in:
Chaiwat Ekkaewnumchai
2020-04-22 09:26:01 -07:00
committed by Facebook GitHub Bot
parent 1a692ccf08
commit f3edfb36db

View File

@@ -87,7 +87,7 @@ public class FlipperOkhttpInterceptor
public Response intercept(Interceptor.Chain chain) throws IOException {
final Request request = chain.request();
final String identifier = UUID.randomUUID().toString();
mPlugin.reportRequest(convertRequest(request, identifier));
final RequestInfo requestInfo = convertRequestWithoutBody(request, identifier);
// Check if there is a mock response
final Response mockResponse = mIsMockResponseSupported ? getMockResponse(request) : null;
@@ -95,6 +95,15 @@ public class FlipperOkhttpInterceptor
final ResponseBody body = response.body();
final ResponseInfo responseInfo = convertResponse(response, body, identifier);
responseInfo.isMock = mockResponse != null;
// Add request body
try {
if (request.body() != null) {
requestInfo.body = bodyToByteArray(request, mMaxBodyBytes);
}
} catch (IOException e) {
// We can safely ignore this as some requests don't allow their body to be read more than once
}
mPlugin.reportRequest(requestInfo);
mPlugin.reportResponse(responseInfo);
return response;
}
@@ -108,7 +117,8 @@ public class FlipperOkhttpInterceptor
return buffer.readByteArray(Math.min(buffer.size(), maxBodyBytes));
}
private RequestInfo convertRequest(Request request, String identifier) throws IOException {
private RequestInfo convertRequestWithoutBody(Request request, String identifier)
throws IOException {
final List<NetworkReporter.Header> headers = convertHeader(request.headers());
final RequestInfo info = new RequestInfo();
info.requestId = identifier;
@@ -116,9 +126,6 @@ public class FlipperOkhttpInterceptor
info.headers = headers;
info.method = request.method();
info.uri = request.url().toString();
if (request.body() != null) {
info.body = bodyToByteArray(request, mMaxBodyBytes);
}
return info;
}