Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:Update
rubygem-puma.15815
chunked-request-handling.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File chunked-request-handling.patch of Package rubygem-puma.15815
commit b01169b5a98bc703b0e10a66f10ad57f3b8ad4cd Author: Evan Phoenix <evan@phx.io> Date: Sun Jul 24 22:02:23 2016 -0700 Implement chunked request handling. Fixes #620 (cherry picked from commit 5ec232d1d47283195275acccf8d53010b22416f2) Packager's note: this is needed for CVE-2020-11076.patch to apply. diff --git a/lib/puma/client.rb b/lib/puma/client.rb index ac2609a3a79e..c02b7baf90ba 100644 --- a/lib/puma/client.rb +++ b/lib/puma/client.rb @@ -7,6 +7,7 @@ class IO end require 'puma/detect' +require 'tempfile' if Puma::IS_JRUBY # We have to work around some OpenSSL buffer/io-readiness bugs @@ -113,9 +114,116 @@ module Puma # no body share this one object since it has no state. EmptyBody = NullIO.new + def setup_chunked_body(body) + @chunked_body = true + @partial_part_left = 0 + @prev_chunk = "" + + @body = Tempfile.new(Const::PUMA_TMP_BASE) + @body.binmode + @tempfile = @body + + return decode_chunk(body) + end + + def decode_chunk(chunk) + if @partial_part_left > 0 + if @partial_part_left <= chunk.size + @body << chunk[0..(@partial_part_left-3)] # skip the \r\n + chunk = chunk[@partial_part_left..-1] + else + @body << chunk + @partial_part_left -= chunk.size + return false + end + end + + if @prev_chunk.empty? + io = StringIO.new(chunk) + else + io = StringIO.new(@prev_chunk+chunk) + @prev_chunk = "" + end + + while !io.eof? + line = io.gets + if line.end_with?("\r\n") + len = line.strip.to_i(16) + if len == 0 + @body.rewind + @buffer = nil + @requests_served += 1 + @ready = true + return true + end + + len += 2 + + part = io.read(len) + + unless part + @partial_part_left = len + next + end + + got = part.size + + case + when got == len + @body << part[0..-3] # to skip the ending \r\n + when got <= len - 2 + @body << part + @partial_part_left = len - part.size + when got == len - 1 # edge where we get just \r but not \n + @body << part[0..-2] + @partial_part_left = len - part.size + end + else + @prev_chunk = line + return false + end + end + + return false + end + + def read_chunked_body + while true + begin + chunk = @io.read_nonblock(4096) + rescue Errno::EAGAIN + return false + rescue SystemCallError, IOError + raise ConnectionError, "Connection error detected during read" + end + + # No chunk means a closed socket + unless chunk + @body.close + @buffer = nil + @requests_served += 1 + @ready = true + raise EOFError + end + + return true if decode_chunk(chunk) + end + end + def setup_body @in_data_phase = true + @read_header = false + body = @parser.body + + te = @env[TRANSFER_ENCODING2] + + if te == CHUNKED + return setup_chunked_body(body) + end + + @chunked_body = false + cl = @env[CONTENT_LENGTH] unless cl @@ -150,8 +258,6 @@ module Puma @body_remain = remain - @read_header = false - return false end @@ -242,6 +348,10 @@ module Puma end def read_body + if @chunked_body + return read_chunked_body + end + # Read an odd sized chunk so we can read even sized ones # after this remain = @body_remain diff --git a/lib/puma/const.rb b/lib/puma/const.rb index d074ad23b925..7bf0efc2b4e0 100644 --- a/lib/puma/const.rb +++ b/lib/puma/const.rb @@ -228,6 +228,7 @@ module Puma CONTENT_LENGTH2 = "content-length".freeze CONTENT_LENGTH_S = "Content-Length: ".freeze TRANSFER_ENCODING = "transfer-encoding".freeze + TRANSFER_ENCODING2 = "HTTP_TRANSFER_ENCODING".freeze CONNECTION_CLOSE = "Connection: close\r\n".freeze CONNECTION_KEEP_ALIVE = "Connection: Keep-Alive\r\n".freeze @@ -235,6 +236,8 @@ module Puma TRANSFER_ENCODING_CHUNKED = "Transfer-Encoding: chunked\r\n".freeze CLOSE_CHUNKED = "0\r\n\r\n".freeze + CHUNKED = "chunked".freeze + COLON = ": ".freeze NEWLINE = "\n".freeze
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor