started extracting the http layer
This commit is contained in:
parent
bd1b114930
commit
b2a29d9eb7
|
@ -45,6 +45,7 @@ module CouchRest
|
||||||
autoload :ExtendedDocument, 'couchrest/more/extended_document'
|
autoload :ExtendedDocument, 'couchrest/more/extended_document'
|
||||||
autoload :CastedModel, 'couchrest/more/casted_model'
|
autoload :CastedModel, 'couchrest/more/casted_model'
|
||||||
|
|
||||||
|
require File.join(File.dirname(__FILE__), 'couchrest', 'core', 'http_abstraction')
|
||||||
require File.join(File.dirname(__FILE__), 'couchrest', 'mixins')
|
require File.join(File.dirname(__FILE__), 'couchrest', 'mixins')
|
||||||
|
|
||||||
# The CouchRest module methods handle the basic JSON serialization
|
# The CouchRest module methods handle the basic JSON serialization
|
||||||
|
@ -118,9 +119,9 @@ module CouchRest
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# set proxy for RestClient to use
|
# set proxy to use
|
||||||
def proxy url
|
def proxy url
|
||||||
RestClient.proxy = url
|
HttpAbstraction.proxy = url
|
||||||
end
|
end
|
||||||
|
|
||||||
# ensure that a database exists
|
# ensure that a database exists
|
||||||
|
@ -141,7 +142,7 @@ module CouchRest
|
||||||
def put(uri, doc = nil)
|
def put(uri, doc = nil)
|
||||||
payload = doc.to_json if doc
|
payload = doc.to_json if doc
|
||||||
begin
|
begin
|
||||||
JSON.parse(RestClient.put(uri, payload))
|
JSON.parse(HttpAbstraction.put(uri, payload))
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
if $DEBUG
|
if $DEBUG
|
||||||
raise "Error while sending a PUT request #{uri}\npayload: #{payload.inspect}\n#{e}"
|
raise "Error while sending a PUT request #{uri}\npayload: #{payload.inspect}\n#{e}"
|
||||||
|
@ -153,7 +154,7 @@ module CouchRest
|
||||||
|
|
||||||
def get(uri)
|
def get(uri)
|
||||||
begin
|
begin
|
||||||
JSON.parse(RestClient.get(uri), :max_nesting => false)
|
JSON.parse(HttpAbstraction.get(uri), :max_nesting => false)
|
||||||
rescue => e
|
rescue => e
|
||||||
if $DEBUG
|
if $DEBUG
|
||||||
raise "Error while sending a GET request #{uri}\n: #{e}"
|
raise "Error while sending a GET request #{uri}\n: #{e}"
|
||||||
|
@ -166,7 +167,7 @@ module CouchRest
|
||||||
def post uri, doc = nil
|
def post uri, doc = nil
|
||||||
payload = doc.to_json if doc
|
payload = doc.to_json if doc
|
||||||
begin
|
begin
|
||||||
JSON.parse(RestClient.post(uri, payload))
|
JSON.parse(HttpAbstraction.post(uri, payload))
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
if $DEBUG
|
if $DEBUG
|
||||||
raise "Error while sending a POST request #{uri}\npayload: #{payload.inspect}\n#{e}"
|
raise "Error while sending a POST request #{uri}\npayload: #{payload.inspect}\n#{e}"
|
||||||
|
@ -177,11 +178,11 @@ module CouchRest
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete uri
|
def delete uri
|
||||||
JSON.parse(RestClient.delete(uri))
|
JSON.parse(HttpAbstraction.delete(uri))
|
||||||
end
|
end
|
||||||
|
|
||||||
def copy uri, destination
|
def copy uri, destination
|
||||||
JSON.parse(RestClient.copy(uri, {'Destination' => destination}))
|
JSON.parse(HttpAbstraction.copy(uri, {'Destination' => destination}))
|
||||||
end
|
end
|
||||||
|
|
||||||
def paramify_url url, params = {}
|
def paramify_url url, params = {}
|
||||||
|
|
35
lib/couchrest/core/adapters/restclient.rb
Normal file
35
lib/couchrest/core/adapters/restclient.rb
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
module RestClientAdapter
|
||||||
|
|
||||||
|
module API
|
||||||
|
def proxy=(url)
|
||||||
|
RestClient.proxy = url
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy
|
||||||
|
RestClient.proxy
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(uri, headers={})
|
||||||
|
RestClient.get(uri, headers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def post(uri, payload, headers={})
|
||||||
|
RestClient.post(uri, payload, headers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def put(uri, payload, headers={})
|
||||||
|
RestClient.put(uri, payload, headers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(uri, headers={})
|
||||||
|
RestClient.delete(uri, headers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy(uri, headers)
|
||||||
|
RestClient::Request.execute( :method => :copy,
|
||||||
|
:url => uri,
|
||||||
|
:headers => headers)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -58,7 +58,7 @@ module CouchRest
|
||||||
keys = params.delete(:keys)
|
keys = params.delete(:keys)
|
||||||
funcs = funcs.merge({:keys => keys}) if keys
|
funcs = funcs.merge({:keys => keys}) if keys
|
||||||
url = CouchRest.paramify_url "#{@root}/_temp_view", params
|
url = CouchRest.paramify_url "#{@root}/_temp_view", params
|
||||||
JSON.parse(RestClient.post(url, funcs.to_json, {"Content-Type" => 'application/json'}))
|
JSON.parse(HttpAbstraction.post(url, funcs.to_json, {"Content-Type" => 'application/json'}))
|
||||||
end
|
end
|
||||||
|
|
||||||
# backwards compatibility is a plus
|
# backwards compatibility is a plus
|
||||||
|
@ -100,11 +100,8 @@ module CouchRest
|
||||||
|
|
||||||
# GET an attachment directly from CouchDB
|
# GET an attachment directly from CouchDB
|
||||||
def fetch_attachment(doc, name)
|
def fetch_attachment(doc, name)
|
||||||
# slug = escape_docid(docid)
|
|
||||||
# name = CGI.escape(name)
|
|
||||||
uri = url_for_attachment(doc, name)
|
uri = url_for_attachment(doc, name)
|
||||||
RestClient.get uri
|
HttpAbstraction.get uri
|
||||||
# "#{@uri}/#{slug}/#{name}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# PUT an attachment directly to CouchDB
|
# PUT an attachment directly to CouchDB
|
||||||
|
@ -112,14 +109,14 @@ module CouchRest
|
||||||
docid = escape_docid(doc['_id'])
|
docid = escape_docid(doc['_id'])
|
||||||
name = CGI.escape(name)
|
name = CGI.escape(name)
|
||||||
uri = url_for_attachment(doc, name)
|
uri = url_for_attachment(doc, name)
|
||||||
JSON.parse(RestClient.put(uri, file, options))
|
JSON.parse(HttpAbstraction.put(uri, file, options))
|
||||||
end
|
end
|
||||||
|
|
||||||
# DELETE an attachment directly from CouchDB
|
# DELETE an attachment directly from CouchDB
|
||||||
def delete_attachment doc, name
|
def delete_attachment doc, name
|
||||||
uri = url_for_attachment(doc, name)
|
uri = url_for_attachment(doc, name)
|
||||||
# this needs a rev
|
# this needs a rev
|
||||||
JSON.parse(RestClient.delete(uri))
|
JSON.parse(HttpAbstraction.delete(uri))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Save a document to CouchDB. This will use the <tt>_id</tt> field from
|
# Save a document to CouchDB. This will use the <tt>_id</tt> field from
|
||||||
|
@ -146,7 +143,7 @@ module CouchRest
|
||||||
slug = escape_docid(doc['_id'])
|
slug = escape_docid(doc['_id'])
|
||||||
begin
|
begin
|
||||||
CouchRest.put "#{@root}/#{slug}", doc
|
CouchRest.put "#{@root}/#{slug}", doc
|
||||||
rescue RestClient::ResourceNotFound
|
rescue HttpAbstraction::ResourceNotFound
|
||||||
p "resource not found when saving even tho an id was passed"
|
p "resource not found when saving even tho an id was passed"
|
||||||
slug = doc['_id'] = @server.next_uuid
|
slug = doc['_id'] = @server.next_uuid
|
||||||
CouchRest.put "#{@root}/#{slug}", doc
|
CouchRest.put "#{@root}/#{slug}", doc
|
||||||
|
@ -252,7 +249,7 @@ module CouchRest
|
||||||
def recreate!
|
def recreate!
|
||||||
delete!
|
delete!
|
||||||
create!
|
create!
|
||||||
rescue RestClient::ResourceNotFound
|
rescue HttpAbstraction::ResourceNotFound
|
||||||
ensure
|
ensure
|
||||||
create!
|
create!
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,10 +4,6 @@ module CouchRest
|
||||||
class Document < Response
|
class Document < Response
|
||||||
include CouchRest::Mixins::Attachments
|
include CouchRest::Mixins::Attachments
|
||||||
|
|
||||||
# def self.inherited(subklass)
|
|
||||||
# subklass.send(:extlib_inheritable_accessor, :database)
|
|
||||||
# end
|
|
||||||
|
|
||||||
extlib_inheritable_accessor :database
|
extlib_inheritable_accessor :database
|
||||||
attr_accessor :database
|
attr_accessor :database
|
||||||
|
|
||||||
|
|
48
lib/couchrest/core/http_abstraction.rb
Normal file
48
lib/couchrest/core/http_abstraction.rb
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
require 'couchrest/core/adapters/restclient'
|
||||||
|
|
||||||
|
# Abstraction layet for HTTP communications.
|
||||||
|
#
|
||||||
|
# By defining a basic API that CouchRest is relying on,
|
||||||
|
# it allows for easy experimentations and implementations of various libraries.
|
||||||
|
#
|
||||||
|
# Most of the API is based on the RestClient API that was used in the early version of CouchRest.
|
||||||
|
#
|
||||||
|
module HttpAbstraction
|
||||||
|
|
||||||
|
# here is the list of exception expected by CouchRest
|
||||||
|
# please convert the underlying errors in this set of known
|
||||||
|
# exceptions.
|
||||||
|
class ResourceNotFound < StandardError; end
|
||||||
|
class RequestFailed < StandardError; end
|
||||||
|
class RequestTimeout < StandardError; end
|
||||||
|
class ServerBrokeConnection < StandardError; end
|
||||||
|
class Conflict < StandardError; end
|
||||||
|
|
||||||
|
|
||||||
|
# # Here is the API you need to implement if you want to write a new adapter
|
||||||
|
# # See adapters/restclient.rb for more information.
|
||||||
|
#
|
||||||
|
# def self.proxy=(url)
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def self.proxy
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def self.get(uri, headers=nil)
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def self.post(uri, payload, headers=nil)
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def self.put(uri, payload, headers=nil)
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def self.delete(uri, headers=nil)
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def self.copy(uri, headers)
|
||||||
|
# end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
HttpAbstraction.extend(RestClientAdapter::API)
|
|
@ -162,7 +162,7 @@ module CouchRest
|
||||||
begin
|
begin
|
||||||
design_doc.view_on(db, view_name, opts, &block)
|
design_doc.view_on(db, view_name, opts, &block)
|
||||||
# the design doc may not have been saved yet on this database
|
# the design doc may not have been saved yet on this database
|
||||||
rescue RestClient::ResourceNotFound => e
|
rescue HttpAbstraction::ResourceNotFound => e
|
||||||
if retryable
|
if retryable
|
||||||
save_design_doc_on(db)
|
save_design_doc_on(db)
|
||||||
retryable = false
|
retryable = false
|
||||||
|
|
|
@ -51,63 +51,63 @@ if RUBY_VERSION.to_f < 1.9
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module RestClient
|
# module RestClient
|
||||||
def self.copy(url, headers={})
|
# # def self.copy(url, headers={})
|
||||||
Request.execute(:method => :copy,
|
# # Request.execute(:method => :copy,
|
||||||
:url => url,
|
# # :url => url,
|
||||||
:headers => headers)
|
# # :headers => headers)
|
||||||
end
|
# # end
|
||||||
|
#
|
||||||
# class Request
|
# # class Request
|
||||||
|
# #
|
||||||
|
# # def establish_connection(uri)
|
||||||
|
# # Thread.current[:connection].finish if (Thread.current[:connection] && Thread.current[:connection].started?)
|
||||||
|
# # p net_http_class
|
||||||
|
# # net = net_http_class.new(uri.host, uri.port)
|
||||||
|
# # net.use_ssl = uri.is_a?(URI::HTTPS)
|
||||||
|
# # net.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||||
|
# # Thread.current[:connection] = net
|
||||||
|
# # Thread.current[:connection].start
|
||||||
|
# # Thread.current[:connection]
|
||||||
|
# # end
|
||||||
|
# #
|
||||||
|
# # def transmit(uri, req, payload)
|
||||||
|
# # setup_credentials(req)
|
||||||
|
# #
|
||||||
|
# # Thread.current[:host] ||= uri.host
|
||||||
|
# # Thread.current[:port] ||= uri.port
|
||||||
|
# #
|
||||||
|
# # if (Thread.current[:connection].nil? || (Thread.current[:host] != uri.host))
|
||||||
|
# # p "establishing a connection"
|
||||||
|
# # establish_connection(uri)
|
||||||
|
# # end
|
||||||
|
# #
|
||||||
|
# # display_log request_log
|
||||||
|
# # http = Thread.current[:connection]
|
||||||
|
# # http.read_timeout = @timeout if @timeout
|
||||||
|
# #
|
||||||
|
# # begin
|
||||||
|
# # res = http.request(req, payload)
|
||||||
|
# # rescue
|
||||||
|
# # p "Net::HTTP connection failed, reconnecting"
|
||||||
|
# # establish_connection(uri)
|
||||||
|
# # http = Thread.current[:connection]
|
||||||
|
# # require 'ruby-debug'
|
||||||
|
# # req.body_stream = nil
|
||||||
|
# #
|
||||||
|
# # res = http.request(req, payload)
|
||||||
|
# # display_log response_log(res)
|
||||||
|
# # result res
|
||||||
|
# # else
|
||||||
|
# # display_log response_log(res)
|
||||||
|
# # process_result res
|
||||||
|
# # end
|
||||||
|
# #
|
||||||
|
# # rescue EOFError
|
||||||
|
# # raise RestClient::ServerBrokeConnection
|
||||||
|
# # rescue Timeout::Error
|
||||||
|
# # raise RestClient::RequestTimeout
|
||||||
|
# # end
|
||||||
|
# # end
|
||||||
#
|
#
|
||||||
# def establish_connection(uri)
|
|
||||||
# Thread.current[:connection].finish if (Thread.current[:connection] && Thread.current[:connection].started?)
|
|
||||||
# p net_http_class
|
|
||||||
# net = net_http_class.new(uri.host, uri.port)
|
|
||||||
# net.use_ssl = uri.is_a?(URI::HTTPS)
|
|
||||||
# net.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
||||||
# Thread.current[:connection] = net
|
|
||||||
# Thread.current[:connection].start
|
|
||||||
# Thread.current[:connection]
|
|
||||||
# end
|
# end
|
||||||
#
|
|
||||||
# def transmit(uri, req, payload)
|
|
||||||
# setup_credentials(req)
|
|
||||||
#
|
|
||||||
# Thread.current[:host] ||= uri.host
|
|
||||||
# Thread.current[:port] ||= uri.port
|
|
||||||
#
|
|
||||||
# if (Thread.current[:connection].nil? || (Thread.current[:host] != uri.host))
|
|
||||||
# p "establishing a connection"
|
|
||||||
# establish_connection(uri)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# display_log request_log
|
|
||||||
# http = Thread.current[:connection]
|
|
||||||
# http.read_timeout = @timeout if @timeout
|
|
||||||
#
|
|
||||||
# begin
|
|
||||||
# res = http.request(req, payload)
|
|
||||||
# rescue
|
|
||||||
# p "Net::HTTP connection failed, reconnecting"
|
|
||||||
# establish_connection(uri)
|
|
||||||
# http = Thread.current[:connection]
|
|
||||||
# require 'ruby-debug'
|
|
||||||
# req.body_stream = nil
|
|
||||||
#
|
|
||||||
# res = http.request(req, payload)
|
|
||||||
# display_log response_log(res)
|
|
||||||
# result res
|
|
||||||
# else
|
|
||||||
# display_log response_log(res)
|
|
||||||
# process_result res
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# rescue EOFError
|
|
||||||
# raise RestClient::ServerBrokeConnection
|
|
||||||
# rescue Timeout::Error
|
|
||||||
# raise RestClient::RequestTimeout
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ describe CouchRest do
|
||||||
describe "using a proxy for RestClient connections" do
|
describe "using a proxy for RestClient connections" do
|
||||||
it "should set proxy url for RestClient" do
|
it "should set proxy url for RestClient" do
|
||||||
CouchRest.proxy 'http://localhost:8888/'
|
CouchRest.proxy 'http://localhost:8888/'
|
||||||
proxy_uri = URI.parse(RestClient.proxy)
|
proxy_uri = URI.parse(HttpAbstraction.proxy)
|
||||||
proxy_uri.host.should eql( 'localhost' )
|
proxy_uri.host.should eql( 'localhost' )
|
||||||
proxy_uri.port.should eql( 8888 )
|
proxy_uri.port.should eql( 8888 )
|
||||||
CouchRest.proxy nil
|
CouchRest.proxy nil
|
||||||
|
|
Loading…
Reference in a new issue