Skip to content

Commit

Permalink
Merge e319b17 into 4aed534
Browse files Browse the repository at this point in the history
  • Loading branch information
keeguon committed Jun 24, 2016
2 parents 4aed534 + e319b17 commit b3ac8dd
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 12 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ gem 'em-http-request', :require => false, :platforms => [:ruby,
gem 'em-synchrony', :require => false, :platforms => [:ruby, :jruby]
gem 'excon', '~> 0.21', :require => false, :platforms => [:ruby, :jruby]
gem 'net-http-persistent', '~> 2.8', :require => false
gem 'multipart-post', :require => false
gem 'http', :require => false

# coverage
Expand Down
10 changes: 5 additions & 5 deletions httpi.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Gem::Specification.new do |s|
s.add_dependency 'rack'
s.add_dependency 'socksify'

s.add_development_dependency 'rubyntlm', '~> 0.3.2'
s.add_development_dependency 'rake', '~> 10.0'
s.add_development_dependency 'rspec', '~> 2.14'
s.add_development_dependency 'mocha', '~> 0.13'
s.add_development_dependency 'puma', '~> 2.3.2'
s.add_development_dependency 'rubyntlm', '~> 0.3.2'
s.add_development_dependency 'rake', '~> 10.0'
s.add_development_dependency 'rspec', '~> 3.4.0'
s.add_development_dependency 'mocha', '~> 0.13'
s.add_development_dependency 'puma', '~> 2.3.2'
s.add_development_dependency 'webmock'

s.files = `git ls-files`.split("\n")
Expand Down
1 change: 1 addition & 0 deletions lib/httpi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require "httpi/adapter/excon"
require "httpi/adapter/net_http"
require "httpi/adapter/net_http_persistent"
require "httpi/adapter/net_http_multipart"
require "httpi/adapter/em_http"
require "httpi/adapter/rack"
require "httpi/adapter/http"
Expand Down
2 changes: 1 addition & 1 deletion lib/httpi/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Adapter
ADAPTERS = {}
ADAPTER_CLASS_MAP = {}

LOAD_ORDER = [:httpclient, :curb, :em_http, :excon, :http, :net_http, :net_http_persistent]
LOAD_ORDER = [:httpclient, :curb, :em_http, :excon, :http, :net_http]

class << self

Expand Down
2 changes: 1 addition & 1 deletion lib/httpi/adapter/net_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def request(method)
"#{method.to_s.upcase}"
end
do_request(method) do |http, http_request|
http_request.body = @request.body
if @request.on_body then
perform(http, http_request) do |res|
res.read_body do |seg|
Expand Down Expand Up @@ -186,6 +185,7 @@ def request_client(type)
request_class = Net::HTTP.const_get(:"#{type.to_s.capitalize}")

request_client = request_class.new @request.url.request_uri, @request.headers
request_client.body = @request.body if [:post, :put].include?(type)
request_client.basic_auth(*@request.auth.credentials) if @request.auth.basic?

if @request.auth.digest?
Expand Down
32 changes: 32 additions & 0 deletions lib/httpi/adapter/net_http_multipart.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module HTTPI
module Adapter
class NetHTTPMultipart < NetHTTP

register :net_http_multipart, :deps => %w(net/http/post/multipart)

private

def request_client(type)
if [:post, :put].include?(type)
request_class = Object.const_get("Net::HTTP::#{type.to_s.capitalize}::Multipart")

request_client = request_class.new @request.url.request_uri, @request.attachments, @request.headers

# set request body_stream
@request.body_stream = request_client.body_stream

request_client.basic_auth(*@request.auth.credentials) if @request.auth.basic?

if @request.auth.digest?
raise NotSupportedError, "Net::HTTP does not support HTTP digest authentication"
end

request_client
else
super(type)
end
end

end
end
end
18 changes: 17 additions & 1 deletion lib/httpi/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module HTTPI
class Request

# Available attribute writers.
ATTRIBUTES = [:url, :proxy, :headers, :body, :open_timeout, :read_timeout, :follow_redirect, :redirect_limit, :query]
ATTRIBUTES = [:url, :proxy, :headers, :body, :body_stream, :attachments, :open_timeout, :read_timeout, :follow_redirect, :redirect_limit, :query]

# Accepts a Hash of +args+ to mass assign attributes and authentication credentials.
def initialize(args = {})
Expand Down Expand Up @@ -98,6 +98,15 @@ def body=(params)
@body = params.kind_of?(Hash) ? build_query_from_hash(params) : params
end

attr_reader :body_stream

# Sets a body stream
def body_stream=(input)
@body = nil
@body_stream = input
input
end

# Sets the block to be called while processing the response. The block
# accepts a single parameter - the chunked response body.
def on_body(&block)
Expand All @@ -108,6 +117,13 @@ def on_body(&block)
@on_body
end

attr_writer :attachments

# Returns attachments if any - defaults to nil
def attachments
@attachments ||= nil
end

# Returns the <tt>HTTPI::Authentication</tt> object.
def auth
@auth ||= Auth::Config.new
Expand Down
2 changes: 1 addition & 1 deletion spec/httpi/adapter/em_http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@

it "raises an error for HTTP digest auth" do
request.auth.digest "username", "password"
expect { adapter.request(:get) }.to raise_error
expect { adapter.request(:get) }.to raise_error(HTTPI::NotSupportedError)
end
end

Expand Down
56 changes: 56 additions & 0 deletions spec/httpi/adapter/net_http_multipart_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require "spec_helper"
require "integration/support/server"

require "composite_io"

describe HTTPI::Adapter::NetHTTPMultipart do

subject(:adapter) { :net_http_multipart }

describe "Net::HTTP with multipart data" do
before :all do
@server = IntegrationServer.run
end

after :all do
@server.stop
end

it "executes POST requests with attachments" do
# create some IO
buffer = StringIO.new('hello world')

# create attachments hash
attachments = { "file" => UploadIO.new(buffer, 'text/plain') }

# create request with attachments
request = HTTPI::Request.new(url: @server.url + "/attachments", attachments: attachments)

# perform request
response = HTTPI.post(request, adapter)

# run tests
expect(response.body).to eq("files: #{attachments.keys.join(',')}")
expect(response.headers["Content-Type"]).to eq("text/plain")
end

it "executes PUT requests with attachments" do
# create some IO
buffer = StringIO.new('hello world')

# create attachments hash
attachments = { "file" => UploadIO.new(buffer, 'text/plain') }

# create request with attachments
request = HTTPI::Request.new(url: @server.url + "/attachments", attachments: attachments)

# perform request
response = HTTPI.put(request, adapter)

# run tests
expect(response.body).to eq("files: #{attachments.keys.join(',')}")
expect(response.headers["Content-Type"]).to eq("text/plain")
end
end

end
4 changes: 2 additions & 2 deletions spec/httpi/adapter/net_http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@
let(:response) { HTTPI.request(http_method, request, adapter) }

shared_examples_for 'any supported custom method' do
specify { response.body.should eq http_method.to_s }
specify { response.headers["Content-Type"].should eq('text/plain') }
specify { expect(response.body).to eq(http_method.to_s) }
specify { expect(response.headers["Content-Type"]).to eq('text/plain') }
end

context 'PATCH' do
Expand Down
3 changes: 3 additions & 0 deletions spec/httpi/httpi_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# find out why httpi doesn't load these automatically. [dh, 2012-12-15]
require "excon"
require "net/http/persistent"
require "net/http/post/multipart"
require "http"

unless RUBY_VERSION < "1.9"
Expand All @@ -19,6 +20,7 @@
let(:httpclient) { HTTPI::Adapter.load(:httpclient) }
let(:net_http) { HTTPI::Adapter.load(:net_http) }
let(:net_http_persistent) { HTTPI::Adapter.load(:net_http_persistent) }
let(:net_http_multipart) { HTTPI::Adapter.load(:net_http_multipart) }

before(:all) do
HTTPI::Adapter::Rack.mount('example.com', IntegrationServer::Application)
Expand Down Expand Up @@ -300,6 +302,7 @@
:curb => lambda { Curl::Easy },
:net_http => lambda { Net::HTTP },
:net_http_persistent => lambda { Net::HTTP::Persistent },
:net_http_multipart => lambda { Net::HTTP },
:em_http => lambda { EventMachine::HttpConnection },
:rack => lambda { Rack::MockRequest },
:excon => lambda { Excon::Connection },
Expand Down
14 changes: 13 additions & 1 deletion spec/integration/support/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ def self.respond_with(body)
}
end

map "/attachments" do
run lambda { |env|
request = Rack::Multipart.parse_multipart(env)

# retrieve file names
files = []
request.each { |k,v| files << v[:name] if v.has_key?(:tempfile) }

IntegrationServer.respond_with "files: #{files.join(',')}"
}
end

map "/repeat" do
run lambda { |env|
IntegrationServer.respond_with :body => env["rack.input"].read
Expand Down Expand Up @@ -63,7 +75,7 @@ def self.respond_with(body)
elsif env["HTTP_AUTHORIZATION"] =~ /(NTLM|Negotiate) (.+)/
# request 2: serve content
resp = IntegrationServer.respond_with "ntlm-auth"
else
else
resp = [401, {
"Content-Type" => "text/html; charset=us-ascii",
"WWW-Authenticate" => "NTLM\r\nNegotiate",
Expand Down

0 comments on commit b3ac8dd

Please sign in to comment.