summaryrefslogtreecommitdiff
path: root/test/net/http/utils.rb
blob: e343e16712e19d459369a352e039b2089d65c12b (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# frozen_string_literal: false
require 'webrick'
begin
  require "webrick/https"
rescue LoadError
  # SSL features cannot be tested
end
require 'webrick/httpservlet/abstract'

module TestNetHTTPUtils
  def start(&block)
    new().start(&block)
  end

  def new
    klass = Net::HTTP::Proxy(config('proxy_host'), config('proxy_port'))
    http = klass.new(config('host'), config('port'))
    http.set_debug_output logfile()
    http
  end

  def config(key)
    @config ||= self.class::CONFIG
    @config[key]
  end

  def logfile
    $DEBUG ? $stderr : NullWriter.new
  end

  def setup
    spawn_server
  end

  def teardown
    if @server
      @server.shutdown
      @server_thread.join
      WEBrick::Utils::TimeoutHandler.terminate
    end
    @log_tester.call(@log) if @log_tester
    # resume global state
    Net::HTTP.version_1_2
  end

  def spawn_server
    @log = []
    @log_tester = lambda {|log| assert_equal([], log ) }
    @config = self.class::CONFIG
    server_config = {
      :BindAddress => config('host'),
      :Port => 0,
      :Logger => WEBrick::Log.new(@log, WEBrick::BasicLog::WARN),
      :AccessLog => [],
      :ServerType => Thread,
    }
    server_config[:OutputBufferSize] = 4 if config('chunked')
    server_config[:RequestTimeout] = config('RequestTimeout') if config('RequestTimeout')
    if defined?(OpenSSL) and config('ssl_enable')
      server_config.update({
        :SSLEnable      => true,
        :SSLCertificate => config('ssl_certificate'),
        :SSLPrivateKey  => config('ssl_private_key'),
        :SSLTmpDhCallback => config('ssl_tmp_dh_callback'),
      })
    end
    @server = WEBrick::HTTPServer.new(server_config)
    @server.mount('/', Servlet, config('chunked'))
    @server_thread = @server.start
    @config['port'] = @server[:Port]
  end

  $test_net_http = nil
  $test_net_http_data = (0...256).to_a.map {|i| i.chr }.join('') * 64
  $test_net_http_data.force_encoding("ASCII-8BIT")
  $test_net_http_data_type = 'application/octet-stream'

  class Servlet < WEBrick::HTTPServlet::AbstractServlet
    def initialize(this, chunked = false)
      @chunked = chunked
    end

    def do_GET(req, res)
      if req['Accept'] != '*/*'
        res['Content-Type'] = req['Accept']
      else
        res['Content-Type'] = $test_net_http_data_type
      end
      res.body = $test_net_http_data
      res.chunked = @chunked
    end

    # echo server
    def do_POST(req, res)
      res['Content-Type'] = req['Content-Type']
      res['X-request-uri'] = req.request_uri.to_s
      res.body = req.body
      res.chunked = @chunked
    end

    def do_PATCH(req, res)
      res['Content-Type'] = req['Content-Type']
      res.body = req.body
      res.chunked = @chunked
    end
  end

  class NullWriter
    def <<(s) end
    def puts(*args) end
    def print(*args) end
    def printf(*args) end
  end

  def self.clean_http_proxy_env
    orig = {
      'http_proxy'      => ENV['http_proxy'],
      'http_proxy_user' => ENV['http_proxy_user'],
      'http_proxy_pass' => ENV['http_proxy_pass'],
      'no_proxy'        => ENV['no_proxy'],
    }

    orig.each_key do |key|
      ENV.delete key
    end

    yield
  ensure
    orig.each do |key, value|
      ENV[key] = value
    end
  end
end