Skip to content

Commit

Permalink
Merge pull request #278 from httprb/ixti/update-request-api
Browse files Browse the repository at this point in the history
Update Request initializer API
  • Loading branch information
tarcieri committed Dec 19, 2015
2 parents dd7ac04 + 222cd8d commit f1359e8
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 74 deletions.
14 changes: 10 additions & 4 deletions lib/http/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,19 @@ def request(verb, uri, opts = {})
body = make_request_body(opts, headers)
proxy = opts.proxy

req = HTTP::Request.new(verb, uri, headers, proxy, body)
res = perform req, opts
req = HTTP::Request.new(
:verb => verb,
:uri => uri,
:headers => headers,
:proxy => proxy,
:body => body
)

res = perform(req, opts)
return res unless opts.follow

Redirector.new(opts.follow).perform req, res do |request|
perform request, opts
Redirector.new(opts.follow).perform(req, res) do |request|
perform(request, opts)
end
end

Expand Down
34 changes: 23 additions & 11 deletions lib/http/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,40 @@ class UnsupportedSchemeError < RequestError; end
attr_reader :uri
attr_reader :proxy, :body, :version

# :nodoc:
def initialize(verb, uri, headers = {}, proxy = {}, body = nil, version = "1.1") # rubocop:disable ParameterLists
@verb = verb.to_s.downcase.to_sym
@uri = normalize_uri uri
@scheme = @uri.scheme && @uri.scheme.to_s.downcase.to_sym
# @option opts [String] :version
# @option opts [#to_s] :verb HTTP request method
# @option opts [HTTP::URI, #to_s] :uri
# @option opts [Hash] :headers
# @option opts [Hash] :proxy
# @option opts [String] :body
def initialize(opts)
@verb = opts.fetch(:verb).to_s.downcase.to_sym
@uri = normalize_uri(opts.fetch :uri)
@scheme = @uri.scheme.to_s.downcase.to_sym if @uri.scheme

fail(UnsupportedMethodError, "unknown method: #{verb}") unless METHODS.include?(@verb)
fail(UnsupportedSchemeError, "unknown scheme: #{scheme}") unless SCHEMES.include?(@scheme)

@proxy = proxy
@body = body
@version = version

@headers = HTTP::Headers.coerce(headers || {})
@proxy = opts[:proxy] || {}
@body = opts[:body]
@version = opts[:version] || "1.1"
@headers = HTTP::Headers.coerce(opts[:headers] || {})

@headers[Headers::HOST] ||= default_host_header_value
@headers[Headers::USER_AGENT] ||= USER_AGENT
end

# Returns new Request with updated uri
def redirect(uri, verb = @verb)
req = self.class.new(verb, @uri.join(uri), headers, proxy, body, version)
req = self.class.new(
:verb => verb,
:uri => @uri.join(uri),
:headers => headers,
:proxy => proxy,
:body => body,
:version => version
)

req[Headers::HOST] = req.uri.host
req
end
Expand Down
12 changes: 7 additions & 5 deletions lib/http/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ class Response
# @option opts [String] :uri
def initialize(opts)
@version = opts.fetch(:version)
@uri = opts.include?(:uri) && HTTP::URI.parse(opts.fetch(:uri))
@status = HTTP::Response::Status.new opts.fetch(:status)
@headers = HTTP::Headers.coerce(opts.fetch(:headers, {}))
@uri = HTTP::URI.parse(opts.fetch :uri) if opts.include? :uri
@status = HTTP::Response::Status.new(opts.fetch :status)
@headers = HTTP::Headers.coerce(opts[:headers] || {})

if opts.include?(:connection)
encoding = opts[:encoding] || charset || Encoding::BINARY
@body = Response::Body.new(opts.fetch(:connection), encoding)
connection = opts.fetch(:connection)
encoding = opts[:encoding] || charset || Encoding::BINARY

@body = Response::Body.new(connection, encoding)
else
@body = opts.fetch(:body)
end
Expand Down
28 changes: 14 additions & 14 deletions spec/lib/http/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,48 +109,48 @@ def simple_response(body, status = 200)
before { allow(client).to receive :perform }

it "accepts params within the provided URL" do
expect(HTTP::Request).to receive(:new) do |_, uri|
expect(CGI.parse uri.query).to eq("foo" => %w(bar))
expect(HTTP::Request).to receive(:new) do |opts|
expect(CGI.parse opts[:uri].query).to eq("foo" => %w(bar))
end

client.get("http://example.com/?foo=bar")
end

it "combines GET params from the URI with the passed in params" do
expect(HTTP::Request).to receive(:new) do |_, uri|
expect(CGI.parse uri.query).to eq("foo" => %w(bar), "baz" => %w(quux))
expect(HTTP::Request).to receive(:new) do |opts|
expect(CGI.parse opts[:uri].query).to eq("foo" => %w(bar), "baz" => %w(quux))
end

client.get("http://example.com/?foo=bar", :params => {:baz => "quux"})
end

it "merges duplicate values" do
expect(HTTP::Request).to receive(:new) do |_, uri|
expect(uri.query).to match(/^(a=1&a=2|a=2&a=1)$/)
expect(HTTP::Request).to receive(:new) do |opts|
expect(opts[:uri].query).to match(/^(a=1&a=2|a=2&a=1)$/)
end

client.get("http://example.com/?a=1", :params => {:a => 2})
end

it "does not modifies query part if no params were given" do
expect(HTTP::Request).to receive(:new) do |_, uri|
expect(uri.query).to eq "deadbeef"
expect(HTTP::Request).to receive(:new) do |opts|
expect(opts[:uri].query).to eq "deadbeef"
end

client.get("http://example.com/?deadbeef")
end

it "does not corrupts index-less arrays" do
expect(HTTP::Request).to receive(:new) do |_, uri|
expect(CGI.parse uri.query).to eq "a[]" => %w(b c), "d" => %w(e)
expect(HTTP::Request).to receive(:new) do |opts|
expect(CGI.parse opts[:uri].query).to eq "a[]" => %w(b c), "d" => %w(e)
end

client.get("http://example.com/?a[]=b&a[]=c", :params => {:d => "e"})
end

it "properly encodes colons" do
expect(HTTP::Request).to receive(:new) do |_, uri|
expect(uri.query).to eq "t=1970-01-01T00%3A00%3A00Z"
expect(HTTP::Request).to receive(:new) do |opts|
expect(opts[:uri].query).to eq "t=1970-01-01T00%3A00%3A00Z"
end

client.get("http://example.com/", :params => {:t => "1970-01-01T00:00:00Z"})
Expand All @@ -162,8 +162,8 @@ def simple_response(body, status = 200)
client = HTTP::Client.new
allow(client).to receive(:perform)

expect(HTTP::Request).to receive(:new) do |*args|
expect(args.last).to eq('{"foo":"bar"}')
expect(HTTP::Request).to receive(:new) do |opts|
expect(opts[:body]).to eq '{"foo":"bar"}'
end

client.get("http://example.com/", :json => {:foo => :bar})
Expand Down
Loading

0 comments on commit f1359e8

Please sign in to comment.