Class: Elevate::HTTP::Request

Inherits:
Object
  • Object
show all
Defined in:
lib/elevate/http/request.rb

Overview

Encapsulates a HTTP request.

NSURLConnection is responsible for fulfilling the request. The response is buffered in memory as it is received, and made available through the response method.

Constant Summary collapse

METHODS =
[:get, :post, :put, :delete, :patch, :head, :options].freeze

Instance Method Summary collapse

Constructor Details

#initialize(method, url, options = {}) ⇒ Request

Initializes a HTTP request with the specified parameters.

Parameters:

  • method (String)

    HTTP method to use

  • url (String)

    URL to load

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

    Options to use

Options Hash (options):

  • :query (Hash)

    Hash to construct the query string from.

  • :headers (Hash)

    Headers to append to the request.

  • :credentials (Hash)

    Credentials to be used with HTTP Basic Authentication. Must have a :username and/or :password key.

  • :body (NSData)

    Raw bytes to use as the body.

  • :json (Hash, Array)

    Hash/Array to be JSON-encoded as the request body. Sets the Content-Type header to application/json.

  • :form (Hash)

    Hash to be form encoded as the request body. Sets the Content-Type header to application/x-www-form-urlencoded.

Raises:

  • (ArgumentError)

    if an illegal HTTP method is used

  • (ArgumentError)

    if the URL does not start with ‘http’

  • (ArgumentError)

    if the :body option is not an instance of NSData



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
# File 'lib/elevate/http/request.rb', line 44

def initialize(method, url, options={})
  raise ArgumentError, "invalid HTTP method" unless METHODS.include? method.downcase
  raise ArgumentError, "invalid URL" unless url.start_with? "http"
  raise ArgumentError, "invalid body type; must be NSData" if options[:body] && ! options[:body].is_a?(NSData)

  unless options.fetch(:query, {}).empty?
    url += "?" + URI.encode_query(options[:query])
  end

  options[:headers] ||= {}

  if root = options.delete(:json)
    options[:body] = NSJSONSerialization.dataWithJSONObject(root, options: 0, error: nil)
    options[:headers]["Content-Type"] = "application/json"
  elsif root = options.delete(:form)
    options[:body] = URI.encode_www_form(root).dataUsingEncoding(NSASCIIStringEncoding)
    options[:headers]["Content-Type"] ||= "application/x-www-form-urlencoded"
  end

  @request = NSMutableURLRequest.alloc.init
  @request.CachePolicy = NSURLRequestReloadIgnoringLocalCacheData
  @request.HTTPBody = options[:body]
  @request.HTTPMethod = method
  @request.URL = NSURL.URLWithString(url)

  headers = options.fetch(:headers, {})

  if credentials = options[:credentials]
    headers["Authorization"] = get_authorization_header(credentials)
  end

  headers.each do |key, value|
    @request.setValue(value.to_s, forHTTPHeaderField:key.to_s)
  end

  #@cache = self.class.cache
  @response = Response.new
  @response.url = url

  @connection = nil
  @future = Future.new
end

Instance Method Details

#cancelvoid

This method returns an undefined value.

Cancels an in-flight request.

This method is safe to call from any thread.



94
95
96
97
98
99
100
101
# File 'lib/elevate/http/request.rb', line 94

def cancel
  return unless sent?

  NetworkThread.cancel(@connection) if @connection
  ActivityIndicator.instance.hide

  @future.fulfill(nil)
end

#responseElevate::HTTP::Response?

Returns a response to this request, sending it if necessary

This method blocks the calling thread, unless interrupted.

Returns:



111
112
113
114
115
116
117
# File 'lib/elevate/http/request.rb', line 111

def response
  unless sent?
    send
  end

  @future.value
end

#sendvoid

This method returns an undefined value.

Sends this request. The caller is not blocked.



124
125
126
127
128
129
130
# File 'lib/elevate/http/request.rb', line 124

def send
  @connection = NSURLConnection.alloc.initWithRequest(@request, delegate:self, startImmediately:false)
  @request = nil

  NetworkThread.start(@connection)
  ActivityIndicator.instance.show
end

#sent?Boolean

Returns true if this request is in-flight

Returns:

  • (Boolean)

    true if this request is in-flight



138
139
140
# File 'lib/elevate/http/request.rb', line 138

def sent?
  @connection != nil
end