Class: Gateway::HTTP

Inherits:
Base
  • Object
show all
Defined in:
lib/gateway/http.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, opts) ⇒ HTTP

Returns a new instance of HTTP.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/gateway/http.rb', line 32

def initialize(name, opts)
  super
  @address   = self.class.normalize_uri(opts[:uri])
  @use_ssl  = @address.scheme == "https"
  @host     = @address.host
  @port     = @address.port
  @header   = opts[:header] || {}

  #TCP socket optimizations
  @socket_options = []
  @socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
                      Socket.const_defined? :TCP_NODELAY
  @socket_options << opts[:socket_options] if opts[:socket_options]
end

Instance Attribute Details

#addressObject (readonly)

Returns the value of attribute address.



29
30
31
# File 'lib/gateway/http.rb', line 29

def address
  @address
end

#headerObject

Returns the value of attribute header.



30
31
32
# File 'lib/gateway/http.rb', line 30

def header
  @header
end

#hostObject (readonly)

Returns the value of attribute host.



29
30
31
# File 'lib/gateway/http.rb', line 29

def host
  @host
end

#portObject (readonly)

Returns the value of attribute port.



29
30
31
# File 'lib/gateway/http.rb', line 29

def port
  @port
end

#use_sslObject (readonly)

Returns the value of attribute use_ssl.



29
30
31
# File 'lib/gateway/http.rb', line 29

def use_ssl
  @use_ssl
end

Class Method Details

.normalize_uri(uri) ⇒ Object



22
23
24
25
26
27
# File 'lib/gateway/http.rb', line 22

def self.normalize_uri uri
  return uri if uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
  uri = uri.to_s
  uri = "http://#{uri}" unless /^(http|https):\/\// =~ uri
  URI.parse(uri)
end

Instance Method Details

#absolute_url(req) ⇒ Object



72
73
74
# File 'lib/gateway/http.rb', line 72

def absolute_url(req)
  address + req.path
end

#allow_body?(req) ⇒ Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/gateway/http.rb', line 146

def allow_body?(req)
  req.is_a?(Net::HTTP::Post) || req.is_a?(Net::HTTP::Put)
end

#delete(path, header = nil, opts = {}) ⇒ Object



96
97
98
99
# File 'lib/gateway/http.rb', line 96

def delete(path, header=nil, opts={})
  req = prepare_request(:delete, path, nil, header)
  request(req, opts)
end

#get(path, header = nil, opts = {}) ⇒ Object



81
82
83
84
# File 'lib/gateway/http.rb', line 81

def get(path, header=nil, opts={})
  req = prepare_request(:get, path, nil, header)
  request(req, opts)
end

#head(path, header = nil, opts = {}) ⇒ Object



76
77
78
79
# File 'lib/gateway/http.rb', line 76

def head(path, header=nil, opts={})
  req = prepare_request(:head, path, nil, header)
  request(req, opts)
end

#idempotent?(req) ⇒ Boolean

Returns:

  • (Boolean)


101
102
103
104
105
106
107
# File 'lib/gateway/http.rb', line 101

def idempotent?(req)
  case req
  when Net::HTTP::Delete, Net::HTTP::Get, Net::HTTP::Head,
       Net::HTTP::Options, Net::HTTP::Put, Net::HTTP::Trace then
    true
  end
end

#open_timeoutObject



154
155
156
# File 'lib/gateway/http.rb', line 154

def open_timeout
  options[:open_timeout]
end

#pipeline(requests, opts = {}, &block) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/gateway/http.rb', line 47

def pipeline(requests, opts={}, &block)
  msg = requests.map{|r| absolute_url(r).to_s }.join(',')

  execute('pipeline', msg, opts) do |conn|
    start conn unless conn.started?
    conn.pipeline(requests.dup, &block)
  end
end

#post(path, body = nil, header = nil, opts = {}) ⇒ Object



86
87
88
89
# File 'lib/gateway/http.rb', line 86

def post(path, body=nil, header=nil, opts={})
  req = prepare_request(:post, path, body, header)
  request(req, opts)
end

#prepare_request(method, path, body, header) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/gateway/http.rb', line 127

def prepare_request(method, path, body, header)
  klass = Net::HTTP.const_get method.to_s.capitalize

  header = self.header.merge(header || {})
  req   = klass.new path, header

  if allow_body?(req)
    if body.is_a?(Hash)
      req.set_form_data body
    elsif body.respond_to?(:rewind) && body.respond_to?(:read)
      body.rewind
      req.body = body.read
    else
      req.body = body.to_s
    end
  end
  req
end

#put(path, body = nil, header = nil, opts = {}) ⇒ Object



91
92
93
94
# File 'lib/gateway/http.rb', line 91

def put(path, body=nil, header=nil, opts={})
  req = prepare_request(:put, path, body, header)
  request(req, opts)
end

#read_timeoutObject



150
151
152
# File 'lib/gateway/http.rb', line 150

def read_timeout
  options[:read_timeout]
end

#request(req, opts = {}) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/gateway/http.rb', line 56

def request(req, opts={})
  opts = {
    :persistent => false,
    :retry      => false
  }.merge(opts) unless idempotent?(req)

  action = req.method.downcase.to_sym

  execute(action, absolute_url(req), opts) do |conn|
    start conn unless conn.started?
    rsp = conn.request(req)
    validate_response(req, rsp, valid_responses(opts)) if validate_response?(opts)
    rsp
  end
end

#valid_responses(opts) ⇒ Object



113
114
115
# File 'lib/gateway/http.rb', line 113

def valid_responses(opts)
  opts.fetch(:valid_responses, [ Net::HTTPSuccess ])
end

#validate_response(req, rsp, valid_rsp) ⇒ Object

Raises:

  • (Gateway::BadResponse)


117
118
119
120
121
122
123
124
125
# File 'lib/gateway/http.rb', line 117

def validate_response(req, rsp, valid_rsp)
  is_valid = valid_rsp.any?{|klass| rsp.is_a?(klass) }

  raise Gateway::BadResponse.new(
    "Invalid Response",
    :status => rsp.code,
    :url => absolute_url(req)
  ) unless is_valid
end

#validate_response?(opts) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/gateway/http.rb', line 109

def validate_response?(opts)
  opts.fetch(:validate_response, true)
end