android - 膨胀 gzip HTTP 响应正文时获取 "source exhausted prematurely"

标签 android gzip okhttp okio

当我尝试使用 okhttp 进行 HTTP 调用时出现以下错误:

W/System.err: java.io.EOFException: source exhausted prematurely
W/System.err:     at okio.InflaterSource.read(InflaterSource.java:83)
W/System.err:     at okio.GzipSource.read(GzipSource.java:80)
W/System.err:     at okio.Buffer.writeAll(Buffer.java:1135)
W/System.err:     at okio.RealBufferedSource.readString(RealBufferedSource.java:199)
W/System.err:     at okhttp3.ResponseBody.string(ResponseBody.java:176)
W/System.err:     at com.ethanwang.andplay.OKHttpTaskTag.doInBackground(OKHttpTaskTag.java:41)
W/System.err:     at com.ethanwang.andplay.OKHttpTaskTag.doInBackground(OKHttpTaskTag.java:20)
W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:295)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/System.err:     at java.lang.Thread.run(Thread.java:818)

我只能找到这个相关问题:https://github.com/square/okhttp/issues/2193但我已确保 Content-Length 是响应正文的正确长度。这是我记录的 okhttp 请求和响应:

要求:

    I/System.out: INFO: Sending request http://test.essaybot.com/msg/tag_search on Connection{test.essaybot.com:80, proxy=DIRECT@ hostAddress=test.essaybot.com/34.208.145.50:80 cipherSuite=none protocol=http/1.1}
I/System.out: Content-Type: application/x-www-form-urlencoded
I/System.out: Content-Length: 33
I/System.out: Host: test.essaybot.com
I/System.out: Connection: Keep-Alive
I/System.out: Accept-Encoding: gzip
I/System.out: User-Agent: okhttp/3.11.0

响应:

I/System.out: INFO: Received response for http://test.essaybot.com/msg/tag_search in 62.2ms
I/System.out: Cache-Control: no-cache
I/System.out: Content-Encoding: gzip
I/System.out: Content-Length: 139
I/System.out: Content-Type: application/json
I/System.out: Set-Cookie: PHP_SESSION=0Q4rZJplDjrUNB4ZbWAG; Path=/; Max-Age=2592000
I/System.out: Set-Cookie: VISITOR_ID=65xGr53M1xM0waK8; Path=/; Max-Age=31536000
I/System.out: Date: Wed, 29 Aug 2018 20:45:06 GMT
I/System.out: INFO: Received response body bytes: 
I/System.out:  [31, -117, 8, 0, 0, 0, 0, 0, 0, -1, 44, -51, 65, 10, -62, 64, 12, 5, -48, -85, 72, -42, 93, -72, -18, -50, -91, 103, 16, -111, -23, 52, -83, 31, 66, -90, 100, 50, -94, -120, 119, -105, 116, -70, 9, 47, -16, -109, -1, 37, 54, 123, 104, -95, -15, 60, -112, 113, 109, -30, 52, -34, -24, 50, -65, 88, -67, 25, -45, 16, 70, -34, 97, 30, 115, 49, -28, 20, -128, 9, -108, 107, 80, -33, 96, -1, -12, 12, 22, 100, 36, 57, 93, -43, 89, 4, 43, 107, -65, -34, -74, 61, 58, -49, -56, -114, -94, -31, 86, -35, -110, -32, -8, 54, -23, 20, 88, -95, 107, -81, 101, 115, -44, 99, -109, 92, -98, 69, 66, 21, -119, -18, -65, 63, 0, 0, 0, -1, -1] 
I/System.out:  With length: 139

服务器与我们的网络和 iOS 端完美配合。直到大约两个月前,它在 android 上也能正常工作,当时它突然停止工作,没有网络变化。还有什么可能导致此错误?

------------------------------------更新-------- ------------------------------

enter image description here 缓冲区中的数据似乎是可读的,因为上面的调试器中有可读文本 ([size=185 text={"err_no":0,"result":["Adventure","Advice","Art ","Africa","Airli…]) 在缓冲区变量之后注释。此外,来自调试器的数据与记录的数据不同:

data = {byte[8192]@4418} 
 0 = 123
 1 = 34
 2 = 101
 3 = 114
 4 = 114
 5 = 95
 6 = 110
 7 = 111
 8 = 34
 9 = 58
 10 = 48
 11 = 44
 12 = 34
 13 = 114
 14 = 101
 15 = 115
 16 = 117
 17 = 108
 18 = 116
 19 = 34
 20 = 58
 21 = 91
 22 = 34
 23 = 65
 24 = 100
 25 = 118
 26 = 101
 27 = 110
 28 = 116
 29 = 117
 30 = 114
 31 = 101
 32 = 34
 33 = 44
 34 = 34
 35 = 65
 36 = 100
 37 = 118
 38 = 105
 39 = 99
 40 = 101
 41 = 34
 42 = 44
 43 = 34
 44 = 65
 45 = 114
 46 = 116
 47 = 34
 48 = 44
 49 = 34
 50 = 65
 51 = 102
 52 = 114
 53 = 105
 54 = 99
 55 = 97
 56 = 34
 57 = 44
 58 = 34
 59 = 65
 60 = 105
 61 = 114
 62 = 108
 63 = 105
 64 = 110
 65 = 101
 66 = 115
 67 = 34
 68 = 44
 69 = 34
 70 = 65
 71 = 110
 72 = 120
 73 = 105
 74 = 101
 75 = 116
 76 = 121
 77 = 34
 78 = 44
 79 = 34
 80 = 65
 81 = 114
 82 = 116
 83 = 105
 84 = 102
 85 = 105
 86 = 99
 87 = 105
 88 = 97
 89 = 108
 90 = 32
 91 = 73
 92 = 110
 93 = 116
 94 = 101
 95 = 108
 96 = 108
 97 = 105
 98 = 103
 99 = 101
 100 = 110
 101 = 99
 102 = 101
 103 = 34
 104 = 44
 105 = 34
 106 = 65
 107 = 112
 108 = 112
 109 = 115
 110 = 34
 111 = 44
 112 = 34
 113 = 65
 114 = 100
 115 = 100
 116 = 105
 117 = 99
 118 = 116
 119 = 105
 120 = 111
 121 = 110
 122 = 34
 123 = 44
 124 = 34
 125 = 65
 126 = 117
 127 = 115
 128 = 116
 129 = 114
 130 = 97
 131 = 108
 132 = 105
 133 = 97
 134 = 34
 135 = 44
 136 = 34
 137 = 65
 138 = 105
 139 = 114
 140 = 98
 141 = 110
 142 = 98
 143 = 34
 144 = 44
 145 = 34
 146 = 65
 147 = 103
 148 = 105
 149 = 110
 150 = 103
 151 = 34
 152 = 44
 153 = 34
 154 = 65
 155 = 100
 156 = 118
 157 = 101
 158 = 114
 159 = 116
 160 = 105
 161 = 115
 162 = 105
 163 = 110
 164 = 103
 165 = 34
 166 = 44
 167 = 34
 168 = 65
 169 = 108
 170 = 99
 171 = 111
 172 = 104
 173 = 111
 174 = 108
 175 = 34
 176 = 44
 177 = 34
 178 = 65
 179 = 115
 180 = 105
 181 = 97
 182 = 34
 183 = 93
 184 = 125
 185 = 0
 186 = 0
 187 = 0
 188 = 0
 189 = 0
 190 = 0
 191 = 0
 192 = 0
 193 = 0
 194 = 0
 195 = 0
 196 = 0
 197 = 0
 198 = 0
 199 = 0 

--------------------更新-------------------- -

我使用调试器来跟踪问题,gzip 响应似乎被解压了两次。如附图所示,InflaterSource.java 中的读取被调用了两次。第二次解压抛异常。

The first time <code>read</code> is called 第一次调用read

The second time <code>read</code> is called 第二次调用read,抛出异常

最佳答案

服务器数据已损坏。它应该包含一个 gzip 预告片以指示流的结尾并且丢失了。

关于android - 膨胀 gzip HTTP 响应正文时获取 "source exhausted prematurely",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52085898/

相关文章:

java - OkHttp 3.11 和 TLS 1.2 支持

android - 如何使背景图像持久化

java - android studio 找不到指定的文件

android - 无法在 SQLiteOpenHelper.onCreate(SQLiteDatabase) 中插入数据

linux - zgrep 在搜索之前是否解压缩文件?

grails - 在Heroku压缩,gzip,过期标签中改进Grails应用

Android通过向右和向左拖动搜索栏来控制 View 高度

python - 只读取 gzip JSON 文件的第一行

java - okhttp3 在 java maven 项目中导致 java.lang.NoClassDefFoundError

android - 在我的服务器和我的客户端之间启用 HTTPS 通信