jasl / wx_pay

An unofficial simple wechat pay gem

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Zlib::DataError: incorrect header check

caiguanhao opened this issue · comments

commented

可能是部分微信服务器升级了,现在执行 invoke_unifiedorder 等方法有几率会报 Zlib::DataError: incorrect header check 错误。

/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:382 → inflate
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:382 → block in inflate_adapter
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/protocol.rb:497 → call_block
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/protocol.rb:488 → <<
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/protocol.rb:163 → read
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:405 → read
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:293 → block in read_body_0
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:264 → inflater
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:283 → read_body_0
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:204 → read_body
/GEM_ROOT/gems/rest-client-2.1.0/lib/restclient/request.rb:739 → block (2 levels) in transmit
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http.rb:1518 → block in transport_request
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http/response.rb:165 → reading_body
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http.rb:1517 → transport_request
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http.rb:1479 → request
/GEM_ROOT/gems/airbrake-9.4.5/lib/airbrake/rails/net_http.rb:7 → block in request
/GEM_ROOT/gems/airbrake-9.4.5/lib/airbrake/rack.rb:21 → capture_timing
/GEM_ROOT/gems/airbrake-9.4.5/lib/airbrake/rails/net_http.rb:6 → request
/GEM_ROOT/gems/rest-client-2.1.0/lib/restclient/request.rb:471 → net_http_do_request
/GEM_ROOT/gems/rest-client-2.1.0/lib/restclient/request.rb:733 → block in transmit
/home/deploy/.rbenv/versions/2.6.4/lib/ruby/2.6.0/net/http.rb:920 → start
/GEM_ROOT/gems/rest-client-2.1.0/lib/restclient/request.rb:727 → transmit
/GEM_ROOT/gems/rest-client-2.1.0/lib/restclient/request.rb:163 → execute
/GEM_ROOT/gems/rest-client-2.1.0/lib/restclient/request.rb:63 → execute
/GEM_ROOT/gems/wx_pay-0.21.0/lib/wx_pay/service.rb:587 → invoke_remote
/GEM_ROOT/gems/wx_pay-0.21.0/lib/wx_pay/service.rb:78 → invoke_unifiedorder

应该是 RestClient 的问题,我暂时用 httprb 解决了

def self.invoke_refund(params, options = {})
  params = {
    appid: options.delete(:appid) || WxPay.appid,
    mch_id: options.delete(:mch_id) || WxPay.mch_id,
    key: options.delete(:key) || WxPay.key,
    nonce_str: SecureRandom.uuid.tr('-', ''),
  }.merge(params)
  params[:op_user_id] ||= params[:mch_id]
  options = {
    ssl_context: OpenSSL::SSL::SSLContext.new.tap do |ctx|
      ctx.set_params(
        cert: options.delete(:apiclient_cert) || WxPay.apiclient_cert,
        key:  options.delete(:apiclient_key) || WxPay.apiclient_key,
      )
      # ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end
  }.merge(options)
  WxPay::Result.new(Hash.from_xml(invoke_remote('/secapi/pay/refund', make_payload(params), options)))
end

def self.invoke_remote(url, payload, options = {})
  gateway_url = options.delete(:gateway_url) || GATEWAY_URL
  url = "#{gateway_url}#{url}"
  options[:body] = payload
  HTTP.timeout(5).headers(content_type: 'application/xml').post(url, options).to_s
end

方便来贡献一下代码?

我也发现偶尔报这个错误,这是 RestClient 的什么问题呢?

同样问题

刚刚分析了下,RestClilent支持的accept_encoding有限。httprb/http支持的更多一些,也许是因为这个原因吧。
def default_headers {:accept => '*/*; q=0.5, application/xml', :accept_encoding => 'gzip, deflate'} end

我根据 @caiguanhao 的代码修改了下wx_pay,
我直接发布到我的到生产环境了,先看看还会不会报错先。

刚刚分析了下,RestClilent支持的accept_encoding有限。httprb/http支持的更多一些,也许是因为这个原因吧。
def default_headers {:accept => '*/*; q=0.5, application/xml', :accept_encoding => 'gzip, deflate'} end

我根据 @caiguanhao 的代码修改了下wx_pay,已经发布到生产环境,看看还会不会报错。

搞好了PR回来呀,我现在不搞微信开发了,没测试环境了

收到,
我也用在多个项目上了,先试一个。 以前也有出现这个问题,也许1%,只是感觉今天特别频繁,几乎超过10%的感觉,不得不改了。
平常代码提交比较随意,如果代码没问题的话,明天我改好点后提交。

commented

我等不及更新,所以我的做法是复制需要的方法到自己的项目里 hotfix

把rest-client降到2.0.2也可以解决问题 rest-client/rest-client#740

我等不及更新,所以我的做法是复制需要的方法到自己的项目里 hotfix

把rest-client降到2.0.2也可以解决问题 rest-client/rest-client#740

我根据@caiguanhao的方案,提交了一个 pull request 等大佬合并。 降级临时解决是可行的。还是要一劳永逸的解决,不能挖坑。

commented
    RestClient::Request.execute(
      {
        method: :post,
        url: url,
        payload: payload,
        headers: { content_type: 'application/xml', accept_encoding: 'none' }
      }.merge(options)
    )

在headers中加上accept_encoding: 'none'

    RestClient::Request.execute(
      {
        method: :post,
        url: url,
        payload: payload,
        headers: { content_type: 'application/xml', accept_encoding: 'none' }
      }.merge(options)
    )

在headers中加上accept_encoding: 'none'

, accept_encoding: 'none'

accept_encoding: 'none' 这个none是从哪来的? 应该是 accept_encoding: 'identity' 吧? 内容不压缩,保持本来的样子。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Encoding
https://www.iana.org/assignments/http-parameters/http-parameters.xml#http-parameters-1

identity Reserved (synonym for "no encoding" in Accept-Encoding)

今天突然出现的问题。可能是因为微信支付今天的升级。

刚加了这行代码暂时解决:

WxPay.extra_rest_client_options = {headers: {"accept-encoding" => "none"}}

今天突然出现的问题。可能是因为微信支付今天的升级。

刚加了这行代码暂时解决:

WxPay.extra_rest_client_options = {headers: {"accept-encoding" => "none"}}

我在微信群里也听说跟最近 RestClient 有升级有关,降级也能解决,后边看看 RestClient 那边会不会发新版来解决(我不确定是他的bug)

我觉得你的这个做法比降级要好

试了WxPay.extra_rest_client_options = {headers: {"accept-encoding" => "identity"}} 可行,感觉这个更简单点

commented

rest-client 快三年没有更新,不知道下次什么时候会有别的问题影响收款,建议还是换掉。

rest-client 快三年没有更新,不知道下次什么时候会有别的问题影响收款,建议还是换掉。

资瓷!已经有PR了 #114 我感觉还有一些问题,处理掉就合并发版

如果我把这里的补丁打到 wx_pay 上如何?我看有些人没注意到这边有临时解决问题

当然我支持替换掉 restclient,我自己这几年也不用这个库了

先用上面的办法:降级或加参数(headers: {"accept-encoding" => "identity"})的解决更好一点,
提交的PR #114 ,httprb替换restclient的方案,也有个版本的小问题,rails6和rails5支持的版本不一样,里面提交的httprb版本不支持rails5,还需要修改下。