Skip to content

Commit

Permalink
Given up on excon as streaming support was fake, trying httpclient
Browse files Browse the repository at this point in the history
  • Loading branch information
samlown committed Jul 9, 2015
1 parent fef4ea0 commit d863dd0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 30 deletions.
2 changes: 1 addition & 1 deletion couchrest.gemspec
Expand Up @@ -27,7 +27,7 @@ Gem::Specification.new do |s|
s.rubygems_version = %q{1.3.7}
s.summary = %q{Lean and RESTful interface to CouchDB.}

s.add_dependency("excon", ["~> 0.45.3"])
s.add_dependency("httpclient", ["~> 2.6.0"])
s.add_dependency("mime-types", [">= 1.15"])
s.add_dependency("multi_json", ["~> 1.0"])
s.add_development_dependency("json", [">= 1.7.0"])
Expand Down
2 changes: 1 addition & 1 deletion lib/couchrest.rb
Expand Up @@ -14,7 +14,7 @@

require 'multi_json'
require 'mime/types'
require 'excon'
require 'httpclient'

$:.unshift File.dirname(__FILE__) unless
$:.include?(File.dirname(__FILE__)) ||
Expand Down
56 changes: 29 additions & 27 deletions lib/couchrest/connection.rb
Expand Up @@ -62,42 +62,42 @@ def initialize(uri, options = {})

# Send a GET request.
def get(path, options = {}, &block)
execute(:get, path, options, nil, &block)
execute('GET', path, options, nil, &block)
end

# Send a PUT request.
def put(path, doc = nil, options = {})
execute(:put, path, options, doc)
execute('PUT', path, options, doc)
end

# Send a POST request.
def post(path, doc = nil, options = {}, &block)
execute(:post, path, options, doc, &block)
execute('POST', path, options, doc, &block)
end

# Send a DELETE request.
def delete(path, options = {})
execute(:delete, path, options)
execute('DELETE', path, options)
end

# Send a COPY request to the URI provided.
def copy(path, destination, options = {})
opts = options.nil? ? {} : options.dup
opts[:headers] = options[:headers].nil? ? {} : options[:headers].dup
opts[:headers]['Destination'] = destination
execute(:copy, path, opts)
execute('COPY', path, opts)
end

# Send a HEAD request.
def head(path, options = {})
options = options.merge(:raw => true) # No parsing!
execute(:head, path, options)
execute('HEAD', path, options)
end

# Close the connection. This will happen automatically if the current thread is
# killed, so shouldn't be used under normal circumstances.
def close
http.shutdown
http.reset
end

protected
Expand All @@ -114,35 +114,38 @@ def clean_uri(uri)
# Take a look at the options povided and try to apply them to the HTTP conneciton.
# We try to maintain RestClient compatability as this is what we used before.
def prepare_http_connection(opts)
http_opts = {
:persistent => true,
:tcp_nodelay => true
}
@http = HTTPClient.new

# SSL Certificate option mapping
http_opts[:ssl_verify_peer] = opts[:verify_ssl] if opts.include?(:verify_ssl)
http_opts[:client_cert] = opts[:ssl_client_cert] if opts.include?(:ssl_client_cert)
http_opts[:client_key] = opts[:ssl_client_key] if opts.include?(:ssl_client_key)
http_opts[:client_key_pass] = opts[:ssl_client_key_pass] if opts.include?(:ssl_client_key_pass)
if opts.include?(:verify_ssl)
http.ssl_config.verify_mode = opts[:verify_ssl] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
end
if opts.include?(:ssl_client_cert)
http.ssl_config.set_client_cert_file(
opts[:ssl_client_cert],
opts[:ssl_client_key],
opts[:ssl_client_key_pass]
)
end

# Timeout options
http_opts[:connect_timeout] = opts[:timeout] if opts.include?(:timeout)
http_opts[:read_timeout] = opts[:read_timeout] if opts.include?(:read_timeout)
http_opts[:open_timeout] = opts[:open_timeout] if opts.include?(:open_timeout)
http.receive_timeout = opts[:timeout] if opts.include?(:timeout)
http.connect_timeout = opts[:open_timeout] if opts.include?(:open_timeout)
http.send_timeout = opts[:read_timeout] if opts.include?(:read_timeout)

@http = Excon.new(uri.to_s, http_opts)
http
end

def execute(method, path, options, payload = nil, &block)
req = {
:method => method,
:path => path
:uri => uri + path
}

# Prepare the request headers
DEFAULT_HEADERS.merge(parse_and_convert_request_headers(options)).each do |key, value|
req[:headers] ||= {}
req[:headers][key] = value
req[:header] ||= {}
req[:header][key] = value
end

# Prepare the request body, if provided
Expand All @@ -156,12 +159,11 @@ def execute(method, path, options, payload = nil, &block)
def send_and_parse_response(req, options, &block)
if block_given?
parser = CouchRest::StreamRowParser.new
streamer = lambda do |chunk, remaining_bytes, total_bytes|
response = send_request(req) do |chunk|
parser.parse(chunk) do |doc|
block.call(parse_body(doc, options))
end
end
response = send_request(req.merge(:response_block => streamer))
handle_response_code(response)
parse_body(parser.header, options)
else
Expand All @@ -172,8 +174,8 @@ def send_and_parse_response(req, options, &block)
end

# Send request, and leave a reference to the response for debugging purposes
def send_request(req)
@last_response = http.request(req)
def send_request(req, &block)
@last_response = http.request(req.delete(:method), req.delete(:uri), req, &block)
end

def handle_response_code(response)
Expand All @@ -197,7 +199,7 @@ def parse_body(body, opts)
#
def payload_from_doc(req, doc, opts = {})
if doc.is_a?(IO) || doc.is_a?(Tempfile)
req[:headers]['Content-Type'] = mime_for(req[:path])
req[:header]['Content-Type'] = mime_for(req[:uri].path)
doc.read
elsif opts[:raw] || doc.nil?
doc
Expand Down
1 change: 0 additions & 1 deletion lib/couchrest/rest_api.rb
Expand Up @@ -60,7 +60,6 @@ def connection(url, options)
uri = URI url
conn = CouchRest::Connection.new(uri, options)
res = yield uri, conn
conn.close
res
end

Expand Down

0 comments on commit d863dd0

Please sign in to comment.