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