Welcome to mirror list, hosted at ThFree Co, Russian Federation.

buffered_io.rb « http_v2 « gitlab « lib « gitlab-http « gems - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 478b9102deca06b4be5809269af6ed152065d552 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# frozen_string_literal: true

require 'net/http'
require 'webmock' if Rails.env.test?

# The Ruby 3.2 does change Net protocol. Please see;
# https://github.com/ruby/ruby/blob/ruby_3_2/lib/net/protocol.rb#L194-L206
# vs https://github.com/ruby/ruby/blob/ruby_3_1/lib/net/protocol.rb#L190-L200
NET_PROTOCOL_VERSION_0_2_0 = Gem::Version.new(Net::Protocol::VERSION) >= Gem::Version.new('0.2.0')

module Gitlab
  module HTTP_V2
    # Net::BufferedIO is overwritten by webmock but in order to test this class,
    # it needs to inherit from the original BufferedIO.
    # https://github.com/bblimke/webmock/blob/867f4b290fd133658aa9530cba4ba8b8c52c0d35/lib/webmock/http_lib_adapters/net_http.rb#L266
    parent_class = if const_defined?('WebMock::HttpLibAdapters::NetHttpAdapter::OriginalNetBufferedIO') &&
        Rails.env.test?
                     WebMock::HttpLibAdapters::NetHttpAdapter::OriginalNetBufferedIO
                   else
                     Net::BufferedIO
                   end

    class BufferedIo < parent_class
      HEADER_READ_TIMEOUT = 20

      # rubocop: disable Style/RedundantReturn
      # rubocop: disable Cop/LineBreakAfterGuardClauses
      # rubocop: disable Layout/EmptyLineAfterGuardClause

      # Original method:
      # https://github.com/ruby/ruby/blob/cdb7d699d0641e8f081d590d06d07887ac09961f/lib/net/protocol.rb#L190-L200
      def readuntil(terminator, ignore_eof = false, start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC))
        if NET_PROTOCOL_VERSION_0_2_0
          offset = @rbuf_offset
          begin
            until idx = @rbuf.index(terminator, offset) # rubocop:disable Lint/AssignmentInCondition
              if (elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) > HEADER_READ_TIMEOUT
                raise Gitlab::HTTP_V2::HeaderReadTimeout,
                  "Request timed out after reading headers for #{elapsed} seconds"
              end

              offset = @rbuf.bytesize
              rbuf_fill
            end

            return rbuf_consume(idx + terminator.bytesize - @rbuf_offset)
          rescue EOFError
            raise unless ignore_eof
            return rbuf_consume(@rbuf.size)
          end
        else
          begin
            until idx = @rbuf.index(terminator) # rubocop:disable Lint/AssignmentInCondition
              if (elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) > HEADER_READ_TIMEOUT
                raise Gitlab::HTTP_V2::HeaderReadTimeout,
                  "Request timed out after reading headers for #{elapsed} seconds"
              end

              rbuf_fill
            end

            return rbuf_consume(idx + terminator.size)
          rescue EOFError
            raise unless ignore_eof
            return rbuf_consume(@rbuf.size)
          end
        end
      end
      # rubocop: enable Style/RedundantReturn
      # rubocop: enable Cop/LineBreakAfterGuardClauses
      # rubocop: enable Layout/EmptyLineAfterGuardClause
    end
  end
end