Ruby 关于客户端发送 gzip 压缩数据解析的问题

glorySpring · 2014年02月21日 · 最后由 climberjing 回复于 2015年12月04日 · 3427 次阅读

因为接口内传送的数据太大,所以上面决定要客户端压缩数据后再传给服务器后台,客户端方面是通过 ASIHTTPRequest 来进行的压缩,压缩格式为 gzip.

我想问的是: 后端要怎么接收数据呢? 或者说 服务器端要做什么配置才能接收到客户端发送来的数据呢?

各位大神有没有什么心得或者经验分享一下呗? 先谢过了...... 这个是我写的 middleware 的代码...可是已发送数据就报错了... 能说说应该怎么做吗?

class GzipRequest
  def initialize(app)
    @app = app
  end

  def method_handled?(env)
    !!(env['REQUEST_METHOD'] =~ /(POST|PUT)/)
  end

  def encoding_handled?(env)
    ['gzip', 'deflate'].include? env['HTTP_CONTENT_ENCODING']
  end

  def call(env)
    if method_handled?(env) && encoding_handled?(env)
      extracted = decode(env['rack.input'], env['HTTP_CONTENT_ENCODING'])

      env.delete('HTTP_CONTENT_ENCODING')
      env['CONTENT_LENGTH'] = extracted.length
      env['rack.input'] = StringIO.new(extracted)
    end

    status, headers, response = @app.call(env)
    return [status, headers, response]
  end

  def decode(input, content_encoding)
    case content_encoding
      when 'gzip' then Zlib::GzipReader.new(input).read
      when 'deflate' then Zlib::Inflate.inflate(input.read)
    end
  end
end

然后报错结果是

[2014-03-02 19:13:29] ERROR ArgumentError: invalid byte sequence in UTF-8
        /Users/kintaichi/.rvm/gems/ruby-2.0.0-p247/gems/rack-1.4.5/lib/rack/utils.rb:104:in `normalize_params'
        /Users/kintaichi/.rvm/gems/ruby-2.0.0-p247/gems/rack-1.4.5/lib/rack/utils.rb:96:in `block in parse_nested_query'

apache deflate 模块支持 input gzip,只要配置一下,后端的 app server 就和普通的 http request 一样获取 params 就可以了。

nginx 不支持,可以在 rails 里面写个 middleware 来处理

ActiveSupport::Gzip.decompress(request.raw_post)

#1 楼 @quakewang 谢谢....我试试...

#1 楼 @quakewang 不好意思,之前因为有时间耽误了,然后今天写了半天也不知道该从哪里下手......

#1 楼 @quakewang middleware 我加好了...里面应该怎么处理呢?

class GizpRequest
  def initialize(app)
    @app = app
  end
  def call(env)
    puts "=======#{@app.call(env)}"
  end
end

好吧,我解决了...谢了...

#5 楼 @glorySpring 服务器端要做什么配置才能接收到客户端发送来的数据呢 这个怎么做的?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号