Class: Vidispine::API::Client::HTTPClient

Inherits:
Object
  • Object
show all
Defined in:
lib/vidispine/api/client/http_client.rb

Defined Under Namespace

Classes: HTTPAuthorizationError

Constant Summary collapse

DEFAULT_HTTP_HOST_ADDRESS =
'localhost'
DEFAULT_HTTP_HOST_PORT =
8080
DEFAULT_USERNAME =
'admin'
DEFAULT_PASSWORD =
'password'
DEFAULT_BASE_PATH =
'/'
DEFAULT_HEADER_CONTENT_TYPE =
'application/json; charset=utf-8'
DEFAULT_HEADER_ACCEPTS =
'application/json'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = { }) ⇒ HTTPClient

Returns a new instance of HTTPClient.



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
# File 'lib/vidispine/api/client/http_client.rb', line 33

def initialize(args = { })
  args = args.dup

  @use_exceptions = args.fetch(:use_exceptions, true)

  initialize_logger(args)
  initialize_http(args)

  logger.debug { "#{self.class.name}::#{__method__} Arguments: #{args.inspect}" }

  @base_uri = args[:base_uri] || "http#{http.use_ssl? ? 's' : ''}://#{http.address}:#{http.port}"
  @default_base_path = args.fetch(:default_base_path, DEFAULT_BASE_PATH)

  @default_query_data = args[:default_query_data] || { }

  @username = args[:username] || DEFAULT_USERNAME
  @password = args[:password] || DEFAULT_PASSWORD

  @authorization_header_key = args.fetch(:authorization_header_key, 'Authorization')
  @authorization_header_value = args.fetch(:authorization_header_value, %(Basic #{["#{username}:#{password}"].pack('m').delete("\r\n")}))

  user_agent = args.fetch(:user_agent, false)
  content_type = args.fetch(:content_type_header, DEFAULT_HEADER_CONTENT_TYPE)
  accept_header = args.fetch(:accept_header, args.fetch(:accepts_header, DEFAULT_HEADER_ACCEPTS))

  @default_request_headers = { }
  @default_request_headers['Content-Type'] = content_type if content_type
  @default_request_headers['Accept'] = accept_header if accept_header
  @default_request_headers[@authorization_header_key] = @authorization_header_value if @authorization_header_key
  @default_request_headers['User-Agent'] = user_agent if user_agent

  @log_request_body = args.fetch(:log_request_body, true)
  @log_response_body = args.fetch(:log_response_body, true)
  @log_pretty_print_body = args.fetch(:log_pretty_print_body, true)

  @parse_response = args.fetch(:parse_response, true)
end

Instance Attribute Details

#authorization_header_keyObject

Returns the value of attribute authorization_header_key.



16
17
18
# File 'lib/vidispine/api/client/http_client.rb', line 16

def authorization_header_key
  @authorization_header_key
end

#authorization_header_valueObject

Returns the value of attribute authorization_header_value.



16
17
18
# File 'lib/vidispine/api/client/http_client.rb', line 16

def authorization_header_value
  @authorization_header_value
end

#base_uriObject

Returns the value of attribute base_uri.



12
13
14
# File 'lib/vidispine/api/client/http_client.rb', line 12

def base_uri
  @base_uri
end

#default_base_pathObject

Returns the value of attribute default_base_path.



12
13
14
# File 'lib/vidispine/api/client/http_client.rb', line 12

def default_base_path
  @default_base_path
end

#default_query_dataObject

Returns the value of attribute default_query_data.



12
13
14
# File 'lib/vidispine/api/client/http_client.rb', line 12

def default_query_data
  @default_query_data
end

#default_request_headersObject

Returns the value of attribute default_request_headers.



16
17
18
# File 'lib/vidispine/api/client/http_client.rb', line 16

def default_request_headers
  @default_request_headers
end

#httpObject

Returns the value of attribute http.



12
13
14
# File 'lib/vidispine/api/client/http_client.rb', line 12

def http
  @http
end

#http_host_addressObject

Returns the value of attribute http_host_address.



12
13
14
# File 'lib/vidispine/api/client/http_client.rb', line 12

def http_host_address
  @http_host_address
end

#http_host_portObject

Returns the value of attribute http_host_port.



12
13
14
# File 'lib/vidispine/api/client/http_client.rb', line 12

def http_host_port
  @http_host_port
end

#log_pretty_print_bodyObject

Returns the value of attribute log_pretty_print_body.



19
20
21
# File 'lib/vidispine/api/client/http_client.rb', line 19

def log_pretty_print_body
  @log_pretty_print_body
end

#log_request_bodyObject

Returns the value of attribute log_request_body.



19
20
21
# File 'lib/vidispine/api/client/http_client.rb', line 19

def log_request_body
  @log_request_body
end

#log_response_bodyObject

Returns the value of attribute log_response_body.



19
20
21
# File 'lib/vidispine/api/client/http_client.rb', line 19

def log_response_body
  @log_response_body
end

#loggerObject

Returns the value of attribute logger.



12
13
14
# File 'lib/vidispine/api/client/http_client.rb', line 12

def logger
  @logger
end

#passwordObject

Returns the value of attribute password.



14
15
16
# File 'lib/vidispine/api/client/http_client.rb', line 14

def password
  @password
end

#requestObject

Returns the value of attribute request.



21
22
23
# File 'lib/vidispine/api/client/http_client.rb', line 21

def request
  @request
end

#responseObject

Returns the value of attribute response.



21
22
23
# File 'lib/vidispine/api/client/http_client.rb', line 21

def response
  @response
end

#use_exceptionsObject

Returns the value of attribute use_exceptions.



21
22
23
# File 'lib/vidispine/api/client/http_client.rb', line 21

def use_exceptions
  @use_exceptions
end

#usernameObject

Returns the value of attribute username.



14
15
16
# File 'lib/vidispine/api/client/http_client.rb', line 14

def username
  @username
end

Instance Method Details

#build_and_send_request(method_name = :get, args = { }, options = { }) ⇒ Object

First builds and then sends the HTTP request

Parameters:

  • method_name (Symbol) (defaults to: :get)

    (:get)

  • args (Hash) (defaults to: { })
  • options (Hash) (defaults to: { })

Options Hash (args):

  • :headers (Hash) — default: {}
  • :path (String) — default: ''
  • :query (Hash) — default: {}
  • :body (Any) — default: nil

Options Hash (options):

  • :default_request_headers (Hash) — default: @default_request_headers


238
239
240
241
# File 'lib/vidispine/api/client/http_client.rb', line 238

def build_and_send_request(method_name = :get, args = { }, options = { })
  _request = build_request(method_name, args, options)
  send_request(_request)
end

#build_request(method_name = :get, args = { }, options = { }) ⇒ Object

Builds the HTTP request

Parameters:

  • method_name (Symbol) (defaults to: :get)

    (:get)

  • args (Hash) (defaults to: { })
  • options (Hash) (defaults to: { })

Options Hash (args):

  • :headers (Hash) — default: {}
  • :path (String) — default: ''
  • :query (Hash) — default: {}
  • :body (Any) — default: nil

Options Hash (options):

  • :default_request_headers (Hash) — default: @default_request_headers
  • :headers (Hash)
  • :query (Hash)


201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/vidispine/api/client/http_client.rb', line 201

def build_request(method_name = :get, args = { }, options = { })
  headers = args[:headers] || options[:headers] || { }
  path = args[:path] || ''
  query = args[:query] || options[:query] || { }
  body = args[:body]

  # Allow the default request headers to be overridden
  _default_request_headers = options.fetch(:default_request_headers, default_request_headers)
  _default_request_headers ||= { }
  _headers = _default_request_headers.merge(headers)

  @uri = build_uri(path, query, options)
  klass_name = request_method_name_to_class_name(method_name)
  klass = Net::HTTP.const_get(klass_name)

  _request = klass.new(@uri.request_uri, _headers)

  if _request.request_body_permitted?
    _body = (body and !body.is_a?(String)) ? JSON.generate(body) : body
    logger.debug { "Processing Body: '#{_body}'" }
    _request.body = _body if _body
  end

  _request
end

#build_uri(path = '', query = nil, options = { }) ⇒ URI

Compiles a full URI

Parameters:

  • path (String) (defaults to: '')
  • query (Hash|String|Nil) (defaults to: nil)
  • options (Hash) (defaults to: { })

Options Hash (options):

  • :default_query_data (Hash)
  • :default_base_path (Hash)

Returns:

  • (URI)


166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/vidispine/api/client/http_client.rb', line 166

def build_uri(path = '', query = nil, options = { })
  _default_query_data = options.fetch(:default_query_data, default_query_data) || { }
  _default_base_path = options.fetch(:default_base_path, default_base_path)

  query = { } if query.nil?

  _query = query.is_a?(Hash) ? (default_query_data.merge(query)).map { |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.respond_to?(:to_s) ? v.to_s : v)}" }.join('&') : query
  _path = "#{path}#{_query and _query.respond_to?(:empty?) and !_query.empty? ? "?#{_query}" : ''}"
  _path = File.join(_default_base_path, _path) if _default_base_path
  _path = File.join(base_uri, _path)
  URI.parse(_path)
end

#delete(path, options = { }) ⇒ Object



243
244
245
# File 'lib/vidispine/api/client/http_client.rb', line 243

def delete(path, options = { })
  build_and_send_request(:delete, { :path => path }, options)
end

#format_body_for_log_output(obj) ⇒ String

Formats a HTTPRequest or HTTPResponse body for log output.

Parameters:

  • obj (HTTPRequest|HTTPResponse)

Returns:

  • (String)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/vidispine/api/client/http_client.rb', line 110

def format_body_for_log_output(obj)
  if obj.content_type == 'application/json'
    if @log_pretty_print_body
      _body = obj.body
      output = JSON.pretty_generate(JSON.parse(_body)) rescue _body
      return output
    else
      return obj.body
    end
  elsif obj.content_type == 'application/xml'
    return obj.body
  else
    return obj.body.inspect
  end
end

#get(path, options = { }) ⇒ Object



247
248
249
# File 'lib/vidispine/api/client/http_client.rb', line 247

def get(path, options = { })
  build_and_send_request(:get, { :path => path }, options)
end

#head(path, options = { }) ⇒ Object



251
252
253
# File 'lib/vidispine/api/client/http_client.rb', line 251

def head(path, options = { })
  build_and_send_request(:head, { :path => path }, options)
end

#initialize_http(args = { }) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/vidispine/api/client/http_client.rb', line 81

def initialize_http(args = { })
  @http_host_address = args[:http_host_address] ||= DEFAULT_HTTP_HOST_ADDRESS
  @http_host_port = args[:http_host_port] ||= DEFAULT_HTTP_HOST_PORT
  @http = Net::HTTP.new(http_host_address, http_host_port)
  use_ssl = args[:http_host_use_ssl]
  if use_ssl
    http_verify_mode = args.fetch(:http_verify_mode, OpenSSL::SSL::VERIFY_NONE)
    http.use_ssl = true
    http.verify_mode = http_verify_mode if http_verify_mode
  end

  http
end

#initialize_logger(args = { }) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/vidispine/api/client/http_client.rb', line 71

def initialize_logger(args = { })
  @logger = args[:logger] ||= Logger.new(args[:log_to] || STDOUT)
  log_level = args[:log_level]
  if log_level
    @logger.level = log_level
    args[:logger] = @logger
  end
  @logger
end

#options(path, options = { }) ⇒ Object



255
256
257
# File 'lib/vidispine/api/client/http_client.rb', line 255

def options(path, options = { })
  build_and_send_request(:options, { :path => path }, options)
end

#post(path, body, options = { }) ⇒ Object



263
264
265
# File 'lib/vidispine/api/client/http_client.rb', line 263

def post(path, body, options = { })
  build_and_send_request(:post, { :path => path, :body => body }, options)
end

#put(path, body, options = { }) ⇒ Object



259
260
261
# File 'lib/vidispine/api/client/http_client.rb', line 259

def put(path, body, options = { })
  build_and_send_request(:put, { :path => path, :body => body }, options)
end

#request_method_name_to_class_name(method_name) ⇒ Object



180
181
182
# File 'lib/vidispine/api/client/http_client.rb', line 180

def request_method_name_to_class_name(method_name)
  method_name.to_s.capitalize
end

#response_parsedObject



143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/vidispine/api/client/http_client.rb', line 143

def response_parsed
  @response_parsed ||= begin
    response_body = response.respond_to?(:body) ? response.body : ''
    logger.debug { "Parsing Response. #{response_body.inspect}" }

    case response.content_type
    when 'application/json'
       response_body.empty? ? response_body : JSON.parse(response_body) # rescue response
    else
       response_body
    end
  end
end

#send_request(request) ⇒ Object

Parameters:

  • request (HTTPRequest)

Raises:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/vidispine/api/client/http_client.rb', line 127

def send_request(request)
  @response_parsed = nil
  @request = request
  logger.debug { %(REQUEST: #{request.method} http#{http.use_ssl? ? 's' : ''}://#{http.address}:#{http.port}#{request.path} HEADERS: #{request.to_hash.inspect} #{log_request_body and request.request_body_permitted? ? "\n-- BODY BEGIN --\n#{format_body_for_log_output(request)}\n-- BODY END --" : ''}) }

  @request_time_start = Time.now
  @response = http.request(request)
  @request_time_end = Time.now
  logger.debug { %(RESPONSE: #{response.inspect} HEADERS: #{response.to_hash.inspect} #{log_response_body and response.respond_to?(:body) ? "\n-- BODY BEGIN --\n#{format_body_for_log_output(response)}\n-- BODY END--" : ''}\nTook: #{@request_time_end - @request_time_start} seconds) }
  #logger.debug { "Parse Response? #{@parse_response}" }

  raise HTTPAuthorizationError if @use_exceptions && @response.code == '401'

  @parse_response ? response_parsed : response.body
end

#user_agentObject



103
104
105
# File 'lib/vidispine/api/client/http_client.rb', line 103

def user_agent
  default_request_headers['User-Agent']
end

#user_agent=(value) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/vidispine/api/client/http_client.rb', line 95

def user_agent=(value)
  if (value)
    default_request_headers['User-Agent'] = value
  else
    default_request_headers.delete('User-Agent')
  end
end