104 lines
3 KiB
Ruby
104 lines
3 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
if Gitlab::Runtime.puma?
|
||
|
raise "Remove this monkey patch: #{__FILE__}" unless Puma::Const::VERSION == '5.1.1'
|
||
|
|
||
|
if ENV['GITLAB_TEMPFILE_IMMEDIATE_UNLINK'] == '1'
|
||
|
# This is copied from https://github.com/puma/puma/blob/v5.1.1/lib/puma/client.rb,
|
||
|
# with two additions: both times we create a temporary file, we immediately
|
||
|
# call `#unlink`. This means that if the process gets terminated without being
|
||
|
# able to clean up itself, the temporary file will not linger on the file
|
||
|
# system. We will try to get this patch accepted upstream if it works for us
|
||
|
# (we just need to check if the temporary file responds to `#unlink` as that
|
||
|
# won't work on Windows, for instance).
|
||
|
module Puma
|
||
|
class Client
|
||
|
private
|
||
|
|
||
|
def setup_body
|
||
|
@body_read_start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
||
|
|
||
|
if @env[HTTP_EXPECT] == CONTINUE
|
||
|
# TODO allow a hook here to check the headers before
|
||
|
# going forward
|
||
|
@io << HTTP_11_100
|
||
|
@io.flush
|
||
|
end
|
||
|
|
||
|
@read_header = false
|
||
|
|
||
|
body = @parser.body
|
||
|
|
||
|
te = @env[TRANSFER_ENCODING2]
|
||
|
|
||
|
if te
|
||
|
if te.include?(",")
|
||
|
te.split(",").each do |part|
|
||
|
if CHUNKED.casecmp(part.strip) == 0 # rubocop:disable Metrics/BlockNesting
|
||
|
return setup_chunked_body(body)
|
||
|
end
|
||
|
end
|
||
|
elsif CHUNKED.casecmp(te) == 0
|
||
|
return setup_chunked_body(body)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
@chunked_body = false
|
||
|
|
||
|
cl = @env[CONTENT_LENGTH]
|
||
|
|
||
|
unless cl
|
||
|
@buffer = body.empty? ? nil : body
|
||
|
@body = EmptyBody
|
||
|
set_ready
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
remain = cl.to_i - body.bytesize
|
||
|
|
||
|
if remain <= 0
|
||
|
@body = StringIO.new(body)
|
||
|
@buffer = nil
|
||
|
set_ready
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
if remain > MAX_BODY
|
||
|
@body = Tempfile.new(Const::PUMA_TMP_BASE)
|
||
|
@body.binmode
|
||
|
@body.unlink # This is the changed part
|
||
|
@tempfile = @body
|
||
|
else
|
||
|
# The body[0,0] trick is to get an empty string in the same
|
||
|
# encoding as body.
|
||
|
@body = StringIO.new body[0,0] # rubocop:disable Layout/SpaceAfterComma
|
||
|
end
|
||
|
|
||
|
@body.write body
|
||
|
|
||
|
@body_remain = remain
|
||
|
|
||
|
return false # rubocop:disable Style/RedundantReturn
|
||
|
end
|
||
|
|
||
|
def setup_chunked_body(body)
|
||
|
@chunked_body = true
|
||
|
@partial_part_left = 0
|
||
|
@prev_chunk = ""
|
||
|
|
||
|
@body = Tempfile.new(Const::PUMA_TMP_BASE)
|
||
|
@body.binmode
|
||
|
@body.unlink # This is the changed part
|
||
|
@tempfile = @body
|
||
|
@chunked_content_length = 0
|
||
|
|
||
|
if decode_chunk(body)
|
||
|
@env[CONTENT_LENGTH] = @chunked_content_length
|
||
|
return true # rubocop:disable Style/RedundantReturn
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|