Class: RestMan::Request::Transmit

Inherits:
ActiveMethod::Base
  • Object
show all
Defined in:
lib/restman/request/transmit.rb

Instance Method Summary collapse

Instance Method Details

#callObject



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
# File 'lib/restman/request/transmit.rb', line 9

def call
  # We set this to true in the net/http block so that we can distinguish
  # read_timeout from open_timeout. Now that we only support Ruby 2.0+,
  # this is only needed for Timeout exceptions thrown outside of Net::HTTP.
  established_connection = false

  request.setup_credentials req

  net = request.net_http_object(uri.hostname, uri.port)
  net.use_ssl = uri.is_a?(URI::HTTPS)
  net.ssl_version = request.ssl_version if request.ssl_version
  net.min_version = request.ssl_min_version if request.ssl_min_version
  net.max_version = request.ssl_max_version if request.ssl_max_version
  net.ssl_timeout = request.ssl_timeout if request.ssl_timeout
  net.ciphers = request.ssl_ciphers if request.ssl_ciphers

  net.verify_mode = request.verify_ssl

  net.cert = request.ssl_client_cert if request.ssl_client_cert
  net.key = request.ssl_client_key if request.ssl_client_key
  net.ca_file = request.ssl_ca_file if request.ssl_ca_file
  net.ca_path = request.ssl_ca_path if request.ssl_ca_path
  net.cert_store = request.ssl_cert_store if request.ssl_cert_store

  net.max_retries = request.max_retries

  net.keep_alive_timeout = request.keep_alive_timeout if request.keep_alive_timeout
  net.close_on_empty_response = request.close_on_empty_response if request.close_on_empty_response
  net.local_host = request.local_host if request.local_host
  net.local_port = request.local_port if request.local_port

  # We no longer rely on net.verify_callback for the main SSL verification
  # because it's not well supported on all platforms (see comments below).
  # But do allow users to set one if they want.
  if request.ssl_verify_callback
    net.verify_callback = request.ssl_verify_callback

    # Hilariously, jruby only calls the callback when cert_store is set to
    # something, so make sure to set one.
    # https://github.com/jruby/jruby/issues/597
    if RestMan::Platform.jruby?
      net.cert_store ||= OpenSSL::X509::Store.new
    end

    if request.ssl_verify_callback_warnings != false
      if print_verify_callback_warnings
        warn('pass :ssl_verify_callback_warnings => false to silence this')
      end
    end
  end

  if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE
    warn('WARNING: OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE')
    warn('This dangerous monkey patch leaves you open to MITM attacks!')
    warn('Try passing :verify_ssl => false instead.')
  end

  net.read_timeout = request.read_timeout
  net.open_timeout = request.open_timeout
  net.write_timeout = request.write_timeout

  RestMan.before_execution_procs.each do |before_proc|
    before_proc.call(req, request.args)
  end

  if request.before_execution_proc
    request.before_execution_proc.call(req, request.args)
  end

  request.log_request

  start_time = Time.now
  tempfile = nil

  net.start do |http|
    established_connection = true

    if request.block_response
      net_http_do_request(http, req, payload, &request.block_response)
    else
      res = net_http_do_request(http, req, payload) { |http_response|
        if request.raw_response
          # fetch body into tempfile
          tempfile = request.fetch_body_to_tempfile(http_response)
        else
          # fetch body
          http_response.read_body
        end
        http_response
      }
      if block_given?
        request.process_result(res, start_time, tempfile) do
          yield
        end
      else
        request.process_result(res, start_time, tempfile)
      end
    end
  end
rescue EOFError
  raise RestMan::ServerBrokeConnection
rescue Net::OpenTimeout => err
  raise RestMan::Exceptions::OpenTimeout.new(nil, err)
rescue Net::ReadTimeout => err
  raise RestMan::Exceptions::ReadTimeout.new(nil, err)
rescue Net::WriteTimeout => err
  raise RestMan::Exceptions::WriteTimeout.new(nil, err)
rescue Timeout::Error, Errno::ETIMEDOUT => err
  # handling for non-Net::HTTP timeouts
  if established_connection
    raise RestMan::Exceptions::ReadTimeout.new(nil, err)
  else
    raise RestMan::Exceptions::OpenTimeout.new(nil, err)
  end
end