Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix raw_post empty bug when when Transfer-Encoding: chunked #47336

Merged
merged 2 commits into from Feb 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions actionpack/lib/action_dispatch/http/request.rb
Expand Up @@ -290,6 +290,7 @@ def media_type

# Returns the content length of the request as an integer.
def content_length
return raw_post.bytesize if headers.key?("Transfer-Encoding")
guilleiguaran marked this conversation as resolved.
Show resolved Hide resolved
super.to_i
end

Expand Down Expand Up @@ -344,9 +345,8 @@ def server_software
# work with raw requests directly.
def raw_post
unless has_header? "RAW_POST_DATA"
raw_post_body = body
set_header("RAW_POST_DATA", raw_post_body.read(content_length))
raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
set_header("RAW_POST_DATA", read_body_stream)
body_stream.rewind if body_stream.respond_to?(:rewind)
end
get_header "RAW_POST_DATA"
end
Expand Down Expand Up @@ -472,6 +472,12 @@ def check_method(name)
def default_session
Session.disabled(self)
end

def read_body_stream
body_stream.rewind if body_stream.respond_to?(:rewind)
return body_stream.read if headers.key?("Transfer-Encoding") # Read body stream until EOF if "Transfer-Encoding" is present
body_stream.read(content_length)
end
end
end

Expand Down
53 changes: 53 additions & 0 deletions railties/test/railties/http_request_test.rb
@@ -0,0 +1,53 @@
# frozen_string_literal: true

require "isolation/abstract_unit"
require "stringio"
require "rack/test"
require "active_support/core_ext/module/delegation"

module RailtiesTest
class HttpRequestTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
include Rack::Test::Methods

def setup
build_app

app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
post "posts", to: "posts#create"
end
RUBY

controller "posts", <<-RUBY
class PostsController < ApplicationController
def create
render json: {
raw_post: request.raw_post,
content_length: request.content_length
}
end
end
RUBY
end

def teardown
teardown_app
end

class TestInput < StringIO
undef_method :size
end
pedro108 marked this conversation as resolved.
Show resolved Hide resolved

test "parses request raw_post correctly when request has Transfer-Encoding header without a Content-Length value" do
require "#{app_path}/config/environment"

header "Transfer-Encoding", "gzip, chunked;foo=bar"
post "/posts", TestInput.new("foo=bar") # prevents Rack::MockRequest from adding a Content-Length

json_response = JSON.parse(last_response.body)
assert_equal 7, json_response["content_length"]
assert_equal "foo=bar", json_response["raw_post"]
end
end
end