Rack rack.input variable getting truncated?

允我心安 提交于 2019-12-04 04:43:22

I'm not a ruby expert by any stretch. I also haven't tried to repro this problem in order to verify my results. But after digging through the rack and actionpack code, I might have something.

The doc for "rack.input" states: "The input stream is an IO-like object which contains the raw HTTP POST data."

So you're using that correctly, it would seem.

However, actionpack tries to parse JSON out of the body (if the content type is specified as JSON) and retrieves the body like this:

when :json
    body = request.raw_post

where "request" is actionpack's own Request class, and "raw_post" is defined like this:

def raw_post
  unless @env.include? 'RAW_POST_DATA'
    @env['RAW_POST_DATA'] = body.read(@env['CONTENT_LENGTH'].to_i)
    body.rewind if body.respond_to?(:rewind)
  end
  @env['RAW_POST_DATA']
end

and "Request.body" is:

def body
  if raw_post = @env['RAW_POST_DATA']
    raw_post.force_encoding(Encoding::BINARY) if raw_post.respond_to?(:force_encoding)
    StringIO.new(raw_post)
  else
    @env['rack.input']
  end
end

That all looks fine and good (though it's confusing to figure out who caches the value first :) ). It looks like the problem is in how the post data is read:

@env['RAW_POST_DATA'] = body.read(@env['CONTENT_LENGTH'].to_i)

So I'm guessing the problem is that since you change "rack.input" but don't update "CONTENT_LENGTH", actionpack is truncating the data since obviously the zipped content would've been shorter than the unzipped content.

Try updating "CONTENT_LENGTH" in your middleware code and see if that fixes it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!