Class: Alice::Connection

Inherits:
Object show all
Includes:
Addressable, Rack::Utils
Defined in:
lib/alice/connection.rb

Constant Summary collapse

HEADERS =
Hash.new { |h, k| k.respond_to?(:to_str) ? k : k.to_s.capitalize }.update \
:content_type    => "Content-Type",
:content_length  => "Content-Length",
:accept_charset  => "Accept-Charset",
:accept_encoding => "Accept-Encoding"
METHODS =
Set.new [:get, :post, :put, :delete, :head]
METHODS_WITH_BODIES =
Set.new [:post, :put]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url = nil, options = {}, &block) ⇒ Connection

:url :params :headers


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/alice/connection.rb', line 24

def initialize(url = nil, options = {}, &block)
  if url.is_a?(Hash)
    options = url
    url     = options[:url]
  end
  @headers          = HeaderHash.new
  @params           = {}
  @parallel_manager = options[:parallel]
  self.url_prefix = url if url
  merge_params  @params,  options[:params]  if options[:params]
  merge_headers @headers, options[:headers] if options[:headers]
  if block
    @builder = Builder.create_with_inner_app(&block)
  end
end

Instance Attribute Details

#builderObject (readonly)

Returns the value of attribute builder


19
20
21
# File 'lib/alice/connection.rb', line 19

def builder
  @builder
end

#headersObject

Returns the value of attribute headers


18
19
20
# File 'lib/alice/connection.rb', line 18

def headers
  @headers
end

#hostObject

Returns the value of attribute host


18
19
20
# File 'lib/alice/connection.rb', line 18

def host
  @host
end

#parallel_managerObject

Returns the value of attribute parallel_manager


18
19
20
# File 'lib/alice/connection.rb', line 18

def parallel_manager
  @parallel_manager
end

#paramsObject

Returns the value of attribute params


18
19
20
# File 'lib/alice/connection.rb', line 18

def params
  @params
end

#path_prefixObject

Returns the value of attribute path_prefix


19
20
21
# File 'lib/alice/connection.rb', line 19

def path_prefix
  @path_prefix
end

#portObject

Returns the value of attribute port


18
19
20
# File 'lib/alice/connection.rb', line 18

def port
  @port
end

#schemeObject

Returns the value of attribute scheme


18
19
20
# File 'lib/alice/connection.rb', line 18

def scheme
  @scheme
end

Instance Method Details

#build_url(url, params = nil) ⇒ Object

Takes a relative url for a request and combines it with the defaults set on the connection instance.

conn = Alice::Connection.new { ... }
conn.url_prefix = "https://sushi.com/api?token=abc"
conn.scheme      # => https
conn.path_prefix # => "/api"

conn.build_url("nigiri?page=2")      # => https://sushi.com/api/nigiri?token=abc&page=2
conn.build_url("nigiri", :page => 2) # => https://sushi.com/api/nigiri?token=abc&page=2

132
133
134
135
136
137
138
139
140
141
142
# File 'lib/alice/connection.rb', line 132

def build_url(url, params = nil)
  uri          = URI.parse(url.to_s)
  uri.scheme ||= @scheme
  uri.host   ||= @host
  uri.port   ||= @port
  if @path_prefix && uri.path !~ /^\//
    uri.path = "#{@path_prefix.size > 1 ? @path_prefix : nil}/#{uri.path}"
  end
  replace_query(uri, params)
  uri
end

#delete(url = nil, headers = nil, &block) ⇒ Object


56
57
58
# File 'lib/alice/connection.rb', line 56

def delete(url = nil, headers = nil, &block)
  run_request :delete, url, nil, headers, &block
end

#escape(s) ⇒ Object

Be sure to URI escape '+' symbols to %2B. Otherwise, they get interpreted as spaces.


177
178
179
180
181
# File 'lib/alice/connection.rb', line 177

def escape(s)
  s.to_s.gsub(/([^a-zA-Z0-9_.-]+)/n) do
    '%' << $1.unpack('H2'*bytesize($1)).join('%').tap { |c| c.upcase! }
  end
end

#get(url = nil, headers = nil, &block) ⇒ Object


40
41
42
# File 'lib/alice/connection.rb', line 40

def get(url = nil, headers = nil, &block)
  run_request :get, url, nil, headers, &block
end

#head(url = nil, headers = nil, &block) ⇒ Object


52
53
54
# File 'lib/alice/connection.rb', line 52

def head(url = nil, headers = nil, &block)
  run_request :head, url, nil, headers, &block
end

#in_parallel(manager) ⇒ Object


77
78
79
80
81
82
83
# File 'lib/alice/connection.rb', line 77

def in_parallel(manager)
  @parallel_manager = manager
  yield
  @parallel_manager && @parallel_manager.run
ensure
  @parallel_manager = nil
end

#in_parallel?Boolean

Returns:

  • (Boolean)

73
74
75
# File 'lib/alice/connection.rb', line 73

def in_parallel?
  !!@parallel_manager
end

#merge_headers(existing_headers, new_headers) ⇒ Object

turns headers keys and values into strings. Look up symbol keys in the the HEADERS hash.

h = merge_headers(HeaderHash.new, :content_type => 'text/plain')
h['Content-Type'] # = 'text/plain'

169
170
171
172
173
# File 'lib/alice/connection.rb', line 169

def merge_headers(existing_headers, new_headers)
  new_headers.each do |key, value|
    existing_headers[HEADERS[key]] = value.to_s
  end
end

#merge_params(existing_params, new_params) ⇒ Object

turns param keys into strings


157
158
159
160
161
# File 'lib/alice/connection.rb', line 157

def merge_params(existing_params, new_params)
  new_params.each do |key, value|
    existing_params[key.to_s] = value
  end
end

#post(url = nil, body = nil, headers = nil, &block) ⇒ Object


44
45
46
# File 'lib/alice/connection.rb', line 44

def post(url = nil, body = nil, headers = nil, &block)
  run_request :post, url, body, headers, &block
end

#put(url = nil, body = nil, headers = nil, &block) ⇒ Object


48
49
50
# File 'lib/alice/connection.rb', line 48

def put(url = nil, body = nil, headers = nil, &block)
  run_request :put, url, body, headers, &block
end

#replace_query(uri, params) ⇒ Object


144
145
146
147
148
149
150
151
152
153
154
# File 'lib/alice/connection.rb', line 144

def replace_query(uri, params)
  url_params = @params.dup
  if uri.query && !uri.query.empty?
    merge_params url_params, parse_query(uri.query)
  end
  if params && !params.empty?
    merge_params url_params, params
  end
  uri.query = url_params.empty? ? nil : build_query(url_params)
  uri
end

#run_request(method, url, body, headers) ⇒ Object


60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/alice/connection.rb', line 60

def run_request(method, url, body, headers)
  if !METHODS.include?(method)
    raise ArgumentError, "unknown http method: #{method}"
  end

  Request.run(self, method) do |req|
    req.url(url)                if url
    req.headers.update(headers) if headers
    req.body = body             if body
    yield req if block_given?
  end
end

#to_appObject

return the assembled Rack application for this instance.


86
87
88
# File 'lib/alice/connection.rb', line 86

def to_app
  @builder.to_app
end

#url_prefix=(url) ⇒ Object

Parses the giving url with Addressable::URI and stores the individual components in this connection. These components serve as defaults for requests made by this connection.

conn = Alice::Connection.new { ... }
conn.url_prefix = "https://sushi.com/api"
conn.scheme      # => https
conn.path_prefix # => "/api"

conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri

101
102
103
104
105
106
107
108
109
110
# File 'lib/alice/connection.rb', line 101

def url_prefix=(url)
  uri              = URI.parse(url)
  self.scheme      = uri.scheme
  self.host        = uri.host
  self.port        = uri.port
  self.path_prefix = uri.path
  if uri.query && !uri.query.empty?
    merge_params @params, parse_query(uri.query)
  end
end