Charles断点导致EOFException和MalformedChunkCodingException

时间:2017-05-29 13:12:42

标签: android okhttp3 charles-proxy

我使用Charles拦截来自我的Android应用程序的Web API调用,以便我可以操纵响应并测试超时和令牌过期等条件(当令牌过期时我得到403)。但是我从一段时间以来就得到了一个EOF异常,我无法弄清楚问题出在哪里。例外情况如下,

05-29 18:28:12.374 W/System.err: java.io.EOFException
05-29 18:28:12.374 W/System.err:     at okio.RealBufferedSource.require(RealBufferedSource.java:59)
05-29 18:28:12.374 W/System.err:     at okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.java:284)
05-29 18:28:12.374 W/System.err:     at okhttp3.internal.http1.Http1Codec$ChunkedSource.readChunkSize(Http1Codec.java:444)
05-29 18:28:12.374 W/System.err:     at okhttp3.internal.http1.Http1Codec$ChunkedSource.read(Http1Codec.java:425)
05-29 18:28:12.374 W/System.err:     at okio.RealBufferedSource.request(RealBufferedSource.java:66)
05-29 18:28:12.374 W/System.err:     at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:387)
05-29 18:28:12.375 W/System.err:     at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:371)
05-29 18:28:12.375 W/System.err:     at okhttp3.internal.Util.bomAwareCharset(Util.java:412)
05-29 18:28:12.375 W/System.err:     at okhttp3.ResponseBody.string(ResponseBody.java:173)
05-29 18:28:12.375 W/System.err:     at facilit.net.core.webapi.WebApi.workOrderGetList(WebApi.java:200)

起初我认为可能是因为我正在编辑响应,但似乎在断点处停止的任何Web API调用都会导致异常。始终是同样的例外。我尝试了不同的模拟器和我的设备。在所有情况下都是确切的结果。

请求代码

@Nullable
    public WorkOrderListResultObject workOrderGetList(@Nonnull JSONObject params) throws WebApiNotInitializedException, IOException {
        if (isInitialized()) {
            final RequestBody requestBody = getRequestBody(params);
            final Request request = getRequest(NetworkConstants.GET_WORK_ORDER_LIST_URL, requestBody);

            try {
                final okhttp3.Response response = mClient.newCall(request).execute();
                final String string = response.body().string();

                final WorkOrderListResultObject workOrderListResultObject = new WorkOrderListResultObject();
                workOrderListResultObject.setResponseString(string);
                workOrderListResultObject.setStatusCode(response.code());

                return workOrderListResultObject;
            } catch (IOException e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }

                throw e;
            }
        } else {
            throwNotInitializedException();

            return null;
        }
    }

private RequestBody getRequestBody(@Nonnull JSONObject params) {
        return RequestBody.create(mediaType, params.toString());
    }

private Request getRequest(@Nonnull String url, @Nonnull RequestBody requestBody) throws IllegalArgumentException {
        if (url.isEmpty()) {
            throw new IllegalArgumentException("url cannot be empty");
        }

        return new Request.Builder()
                .url(BuildConfig.FACILIT_SERVER_BASE_URL + url)
                .addHeader(NetworkConstants.CONSTANT_AUTHENTICATION_TOKEN, FacilitApplicationContext.getFacilitApplicationContext().getAuthenticationToken())
                .addHeader(NetworkConstants.CONSTANT_MOBILE_APP_VERSION, mVersionName)
                .addHeader(NetworkConstants.CONSTANT_MOBILE_PLATFORM_ID, mMobilePlatformValue)
                .addHeader(NetworkConstants.CONSTANT_APPLICATION_ID, mApplicationIDValue)
                .post(requestBody)
                .build();
    }

public static WebApi getInstance() {
        if (mInstance == null) {
            mInstance = new WebApi();
            mClient = new OkHttpClient.Builder()
                    .connectTimeout(TIME_OUT_MILLISECONDS, TimeUnit.MILLISECONDS)
                    .readTimeout(TIME_OUT_MILLISECONDS, TimeUnit.MILLISECONDS)
                    .writeTimeout(TIME_OUT_MILLISECONDS, TimeUnit.MILLISECONDS)
                    .build();
        }

        return mInstance;
    }

如果它有助于我在Web API中从传统的Apache API迁移到OkHttp和旧的Apache API,那么就会引发错误...

org.apache.http.MalformedChunkCodingException: Chunked stream ended unexpectedly
由于服务器设置更改,我非常怀疑是否发生了这种情况。

示例服务器响应,

HTTP/1.1 403 Forbidden
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 30 May 2017 05:16:38 GMT
Content-Length: 0

在OkHttp中使用拦截器后,我注意到以下区别, 如果没有在断点处停止:

Received response for http://webapitest.demo.net/api/workOrder/getList in 1979.3ms
                             Cache-Control: no-cache
                             Pragma: no-cache
                             Content-Type: application/json; charset=utf-8
                             Expires: -1
                             Server: Microsoft-IIS/8.5
                             X-AspNet-Version: 4.0.30319
                             X-Powered-By: ASP.NET
                             Date: Tue, 30 May 2017 12:45:41 GMT
                             Content-Length: 23461
                             Proxy-Connection: Keep-alive

如果停止:

Received response for http://webapitest.demo.net/api/workOrder/getList in 8169.2ms
                             Cache-Control: no-cache
                             Pragma: no-cache
                             Content-Type: application/json; charset=utf-8
                             Expires: -1
                             Server: Microsoft-IIS/8.5
                             X-AspNet-Version: 4.0.30319
                             X-Powered-By: ASP.NET
                             Date: Tue, 30 May 2017 12:46:36 GMT
                             Transfer-Encoding: chunked
                             Proxy-Connection: Keep-alive

1 个答案:

答案 0 :(得分:2)

在使用OkHttp拦截器注意到响应标头差异后,很明显Charles导致标题更改,我检查并确认缺少' Content-Length:23461'在OkHttp收到的响应头中是EOFException的原因。对API进行任何更改都不是一种选择,我确信我也没有对Charles进行设置更改。所以我尝试使用mitmproxy,但这太复杂了,所以我开始使用ZAP。它更符合Charles和IMO的目的。 ZAP是免费的,所以我后来甚至不打扰查尔斯。