monkeyWie / proxyee

HTTP proxy server,support HTTPS&websocket.MITM impl,intercept and tamper HTTPS traffic.
MIT License
1.52k stars 567 forks source link

httpResponse.content().toString(Charset.defaultCharset())乱码 #97

Closed zerorooot closed 4 years ago

zerorooot commented 4 years ago

使用例子“InterceptFullResponseProxyServer”访问 “https://api.zhihu.com/topstory/recommend?session_token=d71288761c49244bc043f55db9ecdb61&page_number=16&limit=6&action=down&after_id=99&ad_interval=2”时,返回的数据乱码 image

httpResponse.toString()返回的是

HttpObjectAggregator$AggregatedFullHttpResponse(decodeResult: success, version: HTTP/1.1, content: CompositeByteBuf(ridx: 0, widx: 7643, cap: 7643, components=1))
HTTP/1.1 200 OK
Date: Sat, 29 Aug 2020 09:27:26 GMT
Content-Type: application/json;charset=utf-8
Connection: keep-alive
Server: CLOUD ELB 1.0.0
Cache-Control: private, must-revalidate, no-cache, no-store
Content-Encoding: br
Vary: Accept-Encoding
Pragma: no-cache
X-Backend-Response: 0.277
X-SecNG-Response: 0.28200006484985
X-UDID: ADDg1qZGiA2PTlGzmCl7Xf_IY7oMuhAFnJ8=
x-lb-timing: 0.283
x-idc-id: 2
Set-Cookie: cookie
X-Daa-Tunnel: hop_count=1
X-Via: LIANTONG-FUJIAN_145(200:miss)
x-cdn-provider: tencent
x-edge-timing: 0.368
content-length: 7643

HttpRequest的数据如下:

DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
GET /topstory/recommend?session_token=d71288761c49244bc043f55db9ecdb61&page_number=16&limit=6&action=down&after_id=99&ad_interval=2 HTTP/1.1
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: cookie
host: api.zhihu.com
monkeyWie commented 4 years ago

可能是gbk编码?

zerorooot commented 4 years ago

不像,httpResponse里有“Content-Type: application/json;charset=utf-8”,而且不是api.zhu.com所有的请求都这样,只有个别。

zerorooot commented 4 years ago

部分响应信息如下

{"data":[{"id":"100_1598701274.949","type":"feed","offset":100,"verb":"TOPIC_ACKNOWLEDGED_ANSWER","created_time":1598701274,"updated_time":1598701274,"target":{"id":1441317068,"type":"answer","url":"https://api.zhihu.com/answers/1441317068","author":{"id":"8543557719e979ebb06011b403b5b299","type":"people","url":"https://api.zhihu.com/people/8543557719e979ebb06011b403b5b299","user_type":"people","url_token":"tuo-qia-ma-ke-zhi-guan","name":"\u6258\u5361\u9A6C\u514B\u4E4B\u51A0","headline":"\u4E0D\u9996\u5148\u4F7F\u7528\u79CD\u65CF\u6B67\u89C6","avatar_url":"https://pic3.zhimg.com/50/v2-55bb43d7e12eac56a14db018b99954f3_m.jpg","is_org":false,"gender":0,"badge":[],"followers_count":65706,"is_following":false,"is_followed":false},"created_time":1598686533,"updated_time":1598686579,"voteup_count":542,"thanks_count":37,"comment_count":45,"is_copyable":true,"question":{"id":417096776,"type":"question","url":"https://api.zhihu.com/questions/417096776","author":{"id":"0","type":"people","url":"","user_type":"people","url_token":"","name":"\u533F\u540D\u7528\u6237","headline":"","avatar_url":"https://pic4.zhimg.com/aadd7b895_m.jpg"},"title":"\u5982\u4F55\u8BC4\u4EF7\u300C\u4E2D\u56FD\u76EE\u524D\u53EA\u662F\u519C\u4E1A\u5927\u56FD\uFF0C\u800C\u4E0D\u662F\u519C\u4E1A\u5F3A\u56FD\u300D\u8FD9\u4E00\u89C2\u70B9\uFF1F","created":1598247349,"answer_count":96,"follower_count":168,"comment_count":1,"bound_topic_ids":[5341,5582,6200,29538,452144],"is_following":false,"excerpt":"","question_type":"normal"},"thumbnail":"","excerpt":"\u8BF4\u7684\u5B8C\u5168\u6B63\u786E\uFF0C\u6CA1\u6BDB\u75C5\uFF0C\u8FD9\u662F\u5BF9\u6211\u56FD\u519C\u4E1A\u53D1\u5C55\u73B0\u72B6\u6709\u6781\u4E3A\u6E05\u6670\u7684\u8BA4\u8BC6\u624D\u80FD\u8BF4\u51FA\u6765\u7684\u8BDD\u3002 \u4E2D\u56FD\u8FC7\u4E8E\u6F2B\u957F\u7684\u519C\u8015\u6587\u5316\uFF0C\u5BFC\u81F4\u6211\u4EEC\u5BF9\u519C\u4E1A\u6709\u4E00\u79CD\u9762\u671D\u9EC4\u571F\u80CC\u671D\u5929\u7684\u523B\u677F\u5370\u8C61\uFF0C\u800C\u8FD9\u79CD\u523B\u677F\u5370\u8C61\uFF0C\u5728\u76F8\u5F53\u5927\u7A0B\u5EA6\u4E0A\u5DF2\u7ECF\u4E0E\u73B0\u4EE3\u519C\u4E1A\u76F8\u8DDD\u751A\u8FDC\u4E86\uFF0C\u73B0\u4EE3\u519C\u4E1A\u968F\u7740\u4EBA\u7C7B\u79D1\u5B66\u6280\u672F\u7684\u8FDB\u6B65\uFF0C\u751F\u4EA7\u529B\u7684\u53D1\u5C55\uFF0C\u793E\u4F1A\u4F53\u7CFB\u7684\u590D\u6742\u5316\uFF0C\u5DF2\u7ECF\u9010\u6E10\u6F14\u53D8\u4E3A\u4E00\u79CD\u9700\u8981\u5168\u793E\u4F1A\u5171\u540C\u53C2\u4E0E\uFF0C\u6574\u4E2A\u4EA7\u4E1A\u4F53\u7CFB\u7EB5\u5411\u6574\u5408\uFF0C\u5E76\u6A2A\u5411\u6253\u901A\u591A\u4E2A\u884C\u4E1A\u7684\u6280\u672F\u5BC6\u96C6\u578B\uFF0C\u8D44\u672C\u5BC6\u96C6\u578B\u7684\u5C16\u7AEF\u524D\u6CBF\u4EA7\u4E1A\u3002 \u5728\u73B0\u4EE3\u519C\u4E1A\u4E2D\u2026","excerpt_new":"\u8BF4\u7684\u5B8C\u5168\u6B63\u786E\uFF0C\u6CA1\u6BDB\u75C5\uFF0C\u8FD9\u662F\u5BF9\u6211\u56FD\u519C\u4E1A\u53D1\u5C55\u73B0\u72B6\u6709\u6781\u4E3A\u6E05\u6670\u7684\u8BA4\u8BC6\u624D\u80FD\u8BF4\u51FA\u6765\u7684\u8BDD\u3002 \u4E2D\u56FD\u8FC7\u4E8E\u6F2B\u957F\u7684\u519C\u8015\u6587\u5316\uFF0C\u5BFC\u81F4\u6211\u4EEC\u5BF9\u519C\u4E1A\u6709\u4E00\u79CD\u9762\u671D\u9EC4\u571F\u80CC\u671D\u5929\u7684\u523B\u677F\u5370\u8C61\uFF0C\u800C\u8FD9\u79CD\u523B\u677F\u5370\u8C61\uFF0C\u5728\u76F8\u5F53\u5927\u7A0B\u5EA6\u4E0A\u5DF2\u7ECF\u4E0E\u73B0\u4EE3\u519C\u4E1A\u76F8\u8DDD\u751A\u8FDC\u4E86\uFF0C\u73B0\u4EE3\u519C\u4E1A\u968F\u7740\u4EBA\u7C7B\u79D1\u5B66\u6280\u672F\u7684\u8FDB\u6B65\uFF0C\u751F\u4EA7\u529B\u7684\u53D1\u5C55\uFF0C\u793E\u4F1A\u4F53\u7CFB\u7684\u590D\u6742\u5316\uFF0C\u5DF2\u7ECF\u9010\u6E10\u6F14\u53D8\u4E3A\u4E00\u79CD\u9700\u8981\u5168\u793E\u4F1A\u5171\u540C\u53C2\u4E0E\uFF0C\u6574\u4E2A\u4EA7\u4E1A\u4F53\u7CFB\u7EB5\u5411\u6574\u5408\uFF0C\u5E76\u6A2A\u5411\u6253\u901A\u591A\u4E2A\u884C\u4E1A\u7684\u6280\u672F\u5BC6\u96C6\u578B\uFF0C\u8D44\u672C\u5BC6\u96C6\u578B\u7684\u5C16\u7AEF\u524D\u6CBF\u4EA7\u4E1A\u3002 \u5728\u73B0\u4EE3\u519C\u4E1A\u4E2D\u2026","preview_type":"default","preview_text":"","visited_count":6518},"brief":"{\"source\": \"TS\", \"type\": \"answer\", \"id\": 1441317068}","uninterest_reasons":[{"reason_id":3,"reason_type":"topic","object_token":"19638604","object_type":"topic","reason_text":"\u519C\u5B66"},{"reason_id":3,"reason_type":"topic","object_token":"19566206","object_type":"topic","reason_text":"\u4E16\u754C"},{"reason_id":3,"reason_type":"topic","object_token":"19566933","object_type":"topic","reason_text":"\u793E\u4F1A"},{"reason_id":3,"reason_type":"topic","object_token":"20896627","object_type":"topic","reason_text":"\u4E2D\u56FD\u79D1\u6280"}
zerorooot commented 4 years ago

报错信息(部分)

at com.github.monkeywie.proxyee.intercept.common.FullResponseIntercept.afterResponse(FullResponseIntercept.java:32)
at com.github.monkeywie.proxyee.intercept.HttpProxyInterceptPipeline.afterResponse(HttpProxyInterceptPipeline.java:87)
at com.github.monkeywie.proxyee.intercept.HttpProxyIntercept.afterResponse(HttpProxyIntercept.java:31)
at com.github.monkeywie.proxyee.intercept.HttpProxyInterceptPipeline.afterResponse(HttpProxyInterceptPipeline.java:87)
at com.github.monkeywie.proxyee.handler.HttpProxyClientHandle.channelRead(HttpProxyClientHandle.java:31)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1518)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1267)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1314)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:440)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
monkeyWie commented 4 years ago

@zerorooot 看了下响应是br压缩格式,netty好像不支持,可以把请求头改一下,只支持gzip:

Accept-Encoding: gzip
zerorooot commented 4 years ago

确实如此,问题已解决,多谢i(o゚v゚)ノ (题外话,maven包还没有更新到最新,还请劳烦更新一下)

monkeyWie commented 4 years ago

@zerorooot 不客气,然后我发布了1.2.1版本到maven仓库,尽情食用吧😉