Class: RaptorIO::Protocol::HTTP::Request

Inherits:
Message
  • Object
show all
Defined in:
lib/raptor-io/protocol/http/request.rb,
lib/raptor-io/protocol/http/request/manipulator.rb,
lib/raptor-io/protocol/http/request/manipulators.rb,
lib/raptor-io/protocol/http/request/manipulators/authenticator.rb,
lib/raptor-io/protocol/http/request/manipulators/redirect_follower.rb,
lib/raptor-io/protocol/http/request/manipulators/authenticators/ntlm.rb,
lib/raptor-io/protocol/http/request/manipulators/authenticators/basic.rb,
lib/raptor-io/protocol/http/request/manipulators/authenticators/digest.rb,
lib/raptor-io/protocol/http/request/manipulators/authenticators/negotiate.rb

Overview

HTTP Request.

Author:

Defined Under Namespace

Modules: Manipulators Classes: Error, Manipulator

Constant Summary collapse

CALLBACK_TYPES =

Acceptable response callback types.

[:on_complete, :on_failure, :on_success]

Instance Attribute Summary collapse

Attributes inherited from Message

#body, #headers, #version

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Message

#http_1_0?, #http_1_1?, #keep_alive?

Constructor Details

#initialize(options = {}) ⇒ Request

Note:

This class’ options are in addition to Message#initialize.

Returns a new instance of Request.

Parameters:

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

    Request options.

Options Hash (options):

  • :version (String) — default: '1.1'

    HTTP version to use.

  • :http_method (Symbol, String) — default: :get

    HTTP method to use.

  • :parameters (Hash) — default: {}

    Parameters to send. If performing a GET request and the URL has parameters of its own they will be merged and overwritten.

  • :timeout (Integer)

    Max time to wait for a response in seconds.

  • :continue (Bool)

    Whether or not to automatically continue on responses with status 100. Only applicable when the ‘Expect’ header has been set to ‘100-continue’.

  • :raw (Bool) — default: false

    ‘true` to not encode any of the given data for HTTP transmission, `false` otherwise.

See Also:



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/raptor-io/protocol/http/request.rb', line 81

def initialize( options = {} )
  super( options )

  clear_callbacks

  fail ArgumentError, "Missing ':url' option." if !@url

  @parameters  ||= {}
  @http_method ||= :get
  @continue    = true  if @continue.nil?
  @raw         = false if @raw.nil?
end

Instance Attribute Details

#callbacksObject

Returns the value of attribute callbacks.



51
52
53
# File 'lib/raptor-io/protocol/http/request.rb', line 51

def callbacks
  @callbacks
end

#client_addressString

Returns IP address – populated by Server.

Returns:



57
58
59
# File 'lib/raptor-io/protocol/http/request.rb', line 57

def client_address
  @client_address
end

#continueBool (readonly)

Note:

Defaults to ‘true`.

Returns Whether or not to automatically continue on responses with status 100.

Returns:

  • (Bool)

    Whether or not to automatically continue on responses with status 100.



44
45
46
# File 'lib/raptor-io/protocol/http/request.rb', line 44

def continue
  @continue
end

#http_methodSymbol

Returns HTTP method.

Returns:

  • (Symbol)

    HTTP method.



27
28
29
# File 'lib/raptor-io/protocol/http/request.rb', line 27

def http_method
  @http_method
end

#parametersHash

Returns Request parameters.

Returns:

  • (Hash)

    Request parameters.



36
37
38
# File 'lib/raptor-io/protocol/http/request.rb', line 36

def parameters
  @parameters
end

#parsed_urlURI (readonly)

Returns Parsed version of #url.

Returns:

  • (URI)

    Parsed version of #url.



33
34
35
# File 'lib/raptor-io/protocol/http/request.rb', line 33

def parsed_url
  @parsed_url
end

#rawBool

Note:

Defaults to ‘false`.

Returns Whether or not encode any of the given data for HTTP transmission.

Returns:

  • (Bool)

    Whether or not encode any of the given data for HTTP transmission.



49
50
51
# File 'lib/raptor-io/protocol/http/request.rb', line 49

def raw
  @raw
end

#root_redirect_idObject



54
55
56
# File 'lib/raptor-io/protocol/http/request.rb', line 54

def root_redirect_id
  @root_redirect_id
end

#timeoutInteger, Float

Returns Timeout in seconds.

Returns:

  • (Integer, Float)

    Timeout in seconds.



39
40
41
# File 'lib/raptor-io/protocol/http/request.rb', line 39

def timeout
  @timeout
end

#urlString

Returns URL of the targeted resource.

Returns:

  • (String)

    URL of the targeted resource.



30
31
32
# File 'lib/raptor-io/protocol/http/request.rb', line 30

def url
  @url
end

Class Method Details

.parse(request) ⇒ Request

Parameters:

  • request (String)

    HTTP request message to parse.

Returns:



282
283
284
285
286
287
288
289
290
291
292
# File 'lib/raptor-io/protocol/http/request.rb', line 282

def self.parse( request )
  data = {}
  first_line, headers_and_body = request.split( CRLF_PATTERN, 2 )
  data[:http_method], data[:url], data[:version] = first_line.scan( /([A-Z]+)\s+(.*)\s+HTTP\/([0-9\.]+)/ ).flatten
  headers, data[:body] = headers_and_body.split( HEADER_SEPARATOR_PATTERN, 2 )

  # Use Host to fill in the parsed_uri stuff.
  data[:headers] = Headers.parse( headers.to_s )

  new data
end

Instance Method Details

#clear_callbacksObject

Clears all callbacks.



95
96
97
98
# File 'lib/raptor-io/protocol/http/request.rb', line 95

def clear_callbacks
  @callbacks = CALLBACK_TYPES.inject( {} ) { |h, type| h[type] = []; h }
  nil
end

#connection_idInteger

Returns Identification for the remote host:port.

Returns:

  • (Integer)

    Identification for the remote host:port.



121
122
123
# File 'lib/raptor-io/protocol/http/request.rb', line 121

def connection_id
  "#{parsed_url.host}:#{parsed_url.port}".hash
end

#continue?Bool

Returns Whether or not to automatically continue on responses with status 100.

Returns:

  • (Bool)

    Whether or not to automatically continue on responses with status 100.



108
109
110
# File 'lib/raptor-io/protocol/http/request.rb', line 108

def continue?
  !!@continue
end

#dupRequest

Returns Duplicate of ‘self`.

Returns:

  • (Request)

    Duplicate of ‘self`.



272
273
274
275
276
277
278
# File 'lib/raptor-io/protocol/http/request.rb', line 272

def dup
  r = self.class.new( url: url )
  instance_variables.each do |iv|
    r.instance_variable_set iv, instance_variable_get( iv )
  end
  r
end

#effective_bodyString

Returns Response body to use.

Returns:

  • (String)

    Response body to use.



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/raptor-io/protocol/http/request.rb', line 168

def effective_body
  return '' if headers['Expect'] == '100-continue'
  return encode_if_not_raw(body.to_s)

  body_params = if !body.to_s.empty?
                  body.split('&').inject({}) do |h, pair|
                    k, v = pair.split('=', 2)
                    h.merge( decode_if_not_raw(k) => decode_if_not_raw(v) )
                  end
                else
                  {}
                end

  return '' if body_params.empty? && parameters.empty?

  body_params.merge( parameters ).map do |k, v|
    "#{encode_if_not_raw(k)}=#{encode_if_not_raw(v)}"
  end.join('&')
end

#effective_urlURI

Returns Location of the resource to request.

Returns:

  • (URI)

    Location of the resource to request.



158
159
160
161
162
163
164
165
# File 'lib/raptor-io/protocol/http/request.rb', line 158

def effective_url
  cparsed_url = parsed_url.dup
  cparsed_url.query = query_parameters.map do |k, v|
    "#{encode_if_not_raw(k)}=#{encode_if_not_raw(v)}"
  end.join('&') if query_parameters.any?

  cparsed_url.normalize
end

#handle_response(response) ⇒ Object

Handles the ‘response` to `self` by passing to the appropriate callbacks.

Parameters:



261
262
263
264
265
266
267
268
269
# File 'lib/raptor-io/protocol/http/request.rb', line 261

def handle_response( response )
  response.request = self

  type = (response.code.to_i == 0) ? :on_failure : :on_success

  @callbacks[type].each { |block| block.call response }
  @callbacks[:on_complete].each { |block| block.call response }
  true
end

#idempotent?Bool

Returns ‘true` if the request if idempotent, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the request if idempotent, `false` otherwise.



202
203
204
# File 'lib/raptor-io/protocol/http/request.rb', line 202

def idempotent?
  http_method != :post
end

#on_complete(&block) ⇒ Object

Assigns a block to be called with the response.

Parameters:

  • block (Block)

    Block to be passed the response.



# File 'lib/raptor-io/protocol/http/request.rb', line 243

#on_failure(&block) ⇒ Object

Assigns a block to be called if the request fails.

Parameters:

  • block (Block)

    Block to call on failure.



# File 'lib/raptor-io/protocol/http/request.rb', line 251

#on_success(&block) ⇒ Object

Assigns a block to be called with the response if the request was successful.

Parameters:

  • block (Block)

    Block to be passed the response.



# File 'lib/raptor-io/protocol/http/request.rb', line 247

#query_parametersHash

Returns Parameters to be used for the query part of the resource.

Returns:

  • (Hash)

    Parameters to be used for the query part of the resource.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/raptor-io/protocol/http/request.rb', line 142

def query_parameters
  query = parsed_url.query
  if !query
    return http_method == :get ? parameters : {}
  end

  qparams = query.split('&').inject({}) do |h, pair|
    k, v = pair.split('=', 2)
    h.merge( decode_if_not_raw(k) => decode_if_not_raw(v) )
  end
  return qparams if http_method != :get

  qparams.merge( parameters )
end

#raw?Bool

Returns Whether or not encode any of the given data for HTTP transmission.

Returns:

  • (Bool)

    Whether or not encode any of the given data for HTTP transmission.



102
103
104
# File 'lib/raptor-io/protocol/http/request.rb', line 102

def raw?
  !!@raw
end

#resourceString

Returns Server-side resource to request.

Returns:

  • (String)

    Server-side resource to request.



207
208
209
210
211
# File 'lib/raptor-io/protocol/http/request.rb', line 207

def resource
  req_resource  = "#{effective_url.path}"
  req_resource << "?#{effective_url.query}" if effective_url.query
  req_resource
end

#to_sString

Returns String representation of the request, ready for HTTP transmission.

Returns:

  • (String)

    String representation of the request, ready for HTTP transmission.



215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/raptor-io/protocol/http/request.rb', line 215

def to_s
  final_body = effective_body

  computed_headers = Headers.new( 'Host' => "#{effective_url.host}:#{effective_url.port}" )
  computed_headers['Content-Length'] = final_body.size.to_s if !final_body.to_s.empty?

  request = "#{http_method.to_s.upcase} #{resource} HTTP/#{version}#{CRLF}"
  request << computed_headers.merge(headers).to_s
  request << HEADER_SEPARATOR

  return request if final_body.to_s.empty?

  request << final_body.to_s
end