Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

updated Requestable module to build a request/response context

If an exception is raise, the entire context is placed into the message
  • Loading branch information...
commit 72d8ace927f642b729043935832afba8f696f8ec 1 parent 2e0c999
@mwmitchell mwmitchell authored
View
6 examples/http.rb
@@ -2,6 +2,12 @@
solr = RSolr.connect
+response = solr.select(:q => 'asd')
+
+puts response.raw.inspect
+
+exit
+
# r = solr.request "/admin/cores", :action => "STATUS"
# puts r.inspect
View
2  lib/rsolr/client.rb
@@ -97,7 +97,7 @@ def delete_by_query(query)
end
# shortcut to RSolr::Message::Generator
- def message *opts
+ def message
@message ||= RSolr::Message::Generator.new
end
View
4 lib/rsolr/connection/net_http.rb
@@ -18,12 +18,12 @@ def connection
def get url
net_http_response = self.connection.get url
- {:body => net_http_response.body, :status_code => net_http_response.code.to_i, :message => net_http_response.message}
+ [net_http_response.body, net_http_response.code.to_i, net_http_response.message]
end
def post url, data, headers={}
net_http_response = self.connection.post url, data, headers
- {:body => net_http_response.body, :status_code => net_http_response.code.to_i, :message => net_http_response.message}
+ [net_http_response.body, net_http_response.code.to_i, net_http_response.message]
end
end
View
51 lib/rsolr/connection/requestable.rb
@@ -1,4 +1,8 @@
# A module that defines the interface and top-level logic for http based connection classes.
+# Requestable provides URL parsing and handles proxy logic.
+
+# It should probably be re-named to HttpRequest or something?
+
module RSolr::Connection::Requestable
include RSolr::Connection::Utils
@@ -27,36 +31,53 @@ def request path, params={}, *extra
extra = extra.dup
opts = extra[-1].kind_of?(Hash) ? extra.pop : {}
data = extra[0]
- context = create_request_context path, params, data
- if opts[:method] == :post
- raise "Don't send POST data when using :method => :post" unless data.to_s.empty?
- # force a POST, use the query string as the POST body
- context.merge! :data => hash_to_query(params), :headers => {'Content-Type' => 'application/x-www-form-urlencoded'}
- elsif data
- # standard POST, using "data" as the POST body
- context.merge! :headers => {'Content-Type' => 'text/xml; charset=utf-8'}
- end
+ context = create_request_context path, params, data, opts
error = nil
- response = {}
+
begin
- response = context[:data] ? self.post(context[:url], context[:data], context[:headers]) : self.get(context[:url])
+
+ if context[:data]
+ response = self.post context[:url], context[:data], context[:headers]
+ else
+ response = self.get context[:url]
+ end
+
+ body, status_code, message = response
+
+ # merge the response into the http context
+ context.merge!(:body => body, :status_code => status_code, :message => message)
+
rescue
- error = $!.to_s
+ # throw RequestError?
+ context[:message] = $!.to_s
end
- error = (response[:message].inspect || "Solr Error") unless response[:status_code] == 200
+ # if no :message but a non-200, throw a "SolrRequestError" ?
+
+ error = (context[:message] || "Non-200 Response Status Code") unless context[:status_code] == 200
raise RSolr::RequestError.new("#{error} -> #{context.inspect}") if error
- context.merge response
+ context
end
- def create_request_context path, params, data
+ # -> should this stuff be in a "ReqResContext" class? ->
+
+ def create_request_context path, params, data=nil, opts={}
url = build_url path, params
full_url = prepend_base url
context = {:path => path, :url => full_url, :params => params, :query => hash_to_query(params), :data => data}
+ if opts[:method] == :post
+ raise "Don't send POST data when using :method => :post" unless data.to_s.empty?
+ # force a POST, use the query string as the POST body
+ context.merge! :data => hash_to_query(params), :headers => {'Content-Type' => 'application/x-www-form-urlencoded'}
+ elsif data
+ # standard POST, using "data" as the POST body
+ context.merge! :headers => {'Content-Type' => 'text/xml; charset=utf-8'}
+ end
+ context
end
# accepts a path/string and optional hash of query params
View
35 spec/api/connection/net_http_spec.rb
@@ -12,23 +12,26 @@ def self.included base
include NetHttpHelper
it 'should forward simple, non-data calls to #get' do
+ net_http.should_receive(:create_request_context).
+ with("/select", {:q=>"a"}, nil, {}).
+ and_return(:path=>"/select", :params=>{:q=>"a"}, :data=>nil, :query=>"q=a", :url=>"http://127.0.0.1:8983/solr/select?q=a")
net_http.should_receive(:get).
with("http://127.0.0.1:8983/solr/select?q=a").
- and_return({:status_code=>200})
- net_http.request('/select', :q=>'a')
+ and_return(['', 200, 'OK'])
+ net_http.request('/select', :q=>'a')
end
it 'should forward :method=>:post calls to #post with a special header' do
net_http.should_receive(:post).
with("http://127.0.0.1:8983/solr/select?q=a", "q=a", {"Content-Type"=>"application/x-www-form-urlencoded"}).
- and_return({:status_code=>200})
+ and_return(["", 200, "OK"])
net_http.request('/select', {:q=>'a'}, :method=>:post)
end
it 'should forward data calls to #post' do
net_http.should_receive(:post).
with("http://127.0.0.1:8983/solr/update", "<optimize/>", {"Content-Type"=>"text/xml; charset=utf-8"}).
- and_return({:status_code=>200})
+ and_return(["", 200, "OK"])
net_http.request('/update', {}, '<optimize/>')
end
@@ -62,15 +65,13 @@ def self.included base
and_return(net_http_response)
context = net_http.send(:get, '/solr/select?q=1')
- context.should be_a(Hash)
+ context.should be_a(Array)
- keys = [:body, :status_code, :message]
- context.keys.size.should == keys.size
- context.keys.all?{|key| keys.include?(key) }.should == true
+ context.size.should == 3
- context[:body].should == 'The Response'
- context[:status_code].should == 200
- context[:message].should == 'OK'
+ context[0].should == 'The Response'
+ context[1].should == 200
+ context[2].should == 'OK'
end
it 'should make a POST request as expected' do
@@ -86,15 +87,13 @@ def self.included base
with('/solr/update', '<rollback/>', {}).
and_return(net_http_response)
context = net_http.send(:post, '/solr/update', '<rollback/>')
- context.should be_a(Hash)
+ context.should be_a(Array)
- keys = [:body, :status_code, :message]
- context.keys.size.should == keys.size
- context.keys.all?{|key| keys.include?(key) }.should == true
+ context.size.should == 3
- context[:body].should == 'The Response'
- context[:status_code].should == 200
- context[:message].should == 'OK'
+ context[0].should == 'The Response'
+ context[1].should == 200
+ context[2].should == 'OK'
end
end
View
98 spec/api/connection/requestable_spec.rb
@@ -46,45 +46,107 @@ def self.included base
end
+ context :prepend_base do
+
+ include RequestableHelper
+
+ it "should prepend the base url to the given string" do
+ requestable.prepend_base("/blah").should == 'http://127.0.0.1:8983/blah'
+ end
+
+ end
+
+ context :build_url do
+
+ include RequestableHelper
+
+ it 'should build a full path and create a query string' do
+ r = requestable
+ r.build_url("/select", :q=>1).should == '/solr/select?q=1'
+ end
+
+ it 'should build a full path without a query string' do
+ r = requestable
+ r.build_url("/select").should == '/solr/select'
+ end
+
+ end
+
+ context :create_request_context do
+
+ include RequestableHelper
+
+ it "should build a simple GET context" do
+ r = requestable
+ result = r.create_request_context('/select', :q=>'a', :fq=>'b')
+ result.should == {:path=>"/select", :params=>{:q=>"a", :fq=>"b"}, :data=>nil, :query=>"q=a&fq=b", :url=>"http://127.0.0.1:8983/solr/select?q=a&fq=b"}
+ end
+
+ it "should build a POST context" do
+ r = requestable
+ result = r.create_request_context('/select', {:wt => :xml}, '<commit/>')
+ result.should == {:path=>"/select", :params=>{:wt=>:xml}, :headers=>{"Content-Type"=>"text/xml; charset=utf-8"}, :data=>"<commit/>", :query=>"wt=xml", :url=>"http://127.0.0.1:8983/solr/select?wt=xml"}
+ end
+
+ it "should raise an exception when trying to use POST data AND :method => :post" do
+ r = requestable
+ lambda{
+ r.create_request_context('/select', {:wt => :xml}, '<commit/>', :method => :post)
+ }.should raise_error("Don't send POST data when using :method => :post")
+ end
+
+ it "should form-encoded POST context" do
+ r = requestable
+ result = r.create_request_context('/select', {:q => 'some gigantic query string that is too big for GET (for example)'}, nil, :method => :post)
+ result.should == {:path=>"/select", :params=>{:q=>"some gigantic query string that is too big for GET (for example)"}, :headers=>{"Content-Type"=>"application/x-www-form-urlencoded"}, :data=>"q=some+gigantic+query+string+that+is+too+big+for+GET+%28for+example%29", :query=>"q=some+gigantic+query+string+that+is+too+big+for+GET+%28for+example%29", :url=>"http://127.0.0.1:8983/solr/select?q=some+gigantic+query+string+that+is+too+big+for+GET+%28for+example%29"}
+ end
+
+ end
+
context :request do
include RequestableHelper
- it 'should send a get to itself' do
- expected_response = {:path=>"/blah", :params=>{:id=>1}, :query=>"id=1", :data=>nil, :url=>"http://127.0.0.1:8983/solr/blah?id=1", :status_code=>200}
+ it "should be able to build a request context, pass the url to #get and return a full context" do
+ requestable.should_receive(:create_request_context).
+ with("/admin/ping", {}, nil, {}).
+ and_return({:url => 'http://localhost:8983/solr/admin/ping'})
requestable.should_receive(:get).
- with("http://127.0.0.1:8983/solr/blah?id=1").
- and_return(expected_response)
- requestable.request('/blah', :id=>1).should == expected_response
+ with('http://localhost:8983/solr/admin/ping').
+ and_return(["asdfasdf", 200, "OK"])
+ response = requestable.request '/admin/ping'
+ response.should == {:status_code=>200, :message=>"OK", :url=>"http://localhost:8983/solr/admin/ping", :body=>"asdfasdf"}
+ end
+
+ it 'should send a get to itself with params' do
+ requestable.should_receive(:get).
+ with("http://127.0.0.1:8983/solr/blahasdf?id=1").
+ and_return(["", 200, "OK"])
+ r = requestable.request('/blahasdf', :id=>1)
+ r.should == {:status_code=>200, :path=>"/blahasdf", :params=>{:id=>1}, :message=>"OK", :data=>nil, :query=>"id=1", :url=>"http://127.0.0.1:8983/solr/blahasdf?id=1", :body=>""}
end
it 'should raise an error if the status_code is not 200' do
- expected_response = {:status_code => 503}
requestable.should_receive(:get).
with("http://127.0.0.1:8983/solr/blah?id=1").
- and_return(expected_response)
+ and_return( ["", 404, "Not Found"] )
lambda{
- requestable.request('/blah', :id=>1)
- }.should raise_error
+ requestable.request('/blah', :id=>1).should == true
+ }.should raise_error('Not Found -> {:status_code=>404, :path=>"/blah", :params=>{:id=>1}, :message=>"Not Found", :data=>nil, :query=>"id=1", :url=>"http://127.0.0.1:8983/solr/blah?id=1", :body=>""}')
end
it 'should send a post to itself if data is supplied' do
- expected_response = {:path=>"/blah", :params=>{:id=>1}, :query=>"id=1", :data=>"<commit/>", :headers=>{"Content-Type"=>"text/xml; charset=utf-8"}, :url=>"http://127.0.0.1:8983/solr/blah?id=1", :status_code=>200}
- my_data = "<commit/>"
- post_headers = {"Content-Type"=>"text/xml; charset=utf-8"}
requestable.should_receive(:post).
with("http://127.0.0.1:8983/solr/blah?id=1", "<commit/>", {"Content-Type"=>"text/xml; charset=utf-8"}).
- and_return(expected_response)
- requestable.request('/blah', {:id=>1}, my_data).should == expected_response
+ and_return(["", 200, "OK"])
+ requestable.request('/blah', {:id=>1}, "<commit/>")#.should == expected_response
end
it 'should send a post to itself when :method=>:post is set even if no POST data is supplied' do
- expected_response = {:path=>"/blah", :params=>{}, :query=>"", :data=>"", :headers=>{"Content-Type"=>"application/x-www-form-urlencoded"}, :url=>"http://127.0.0.1:8983/solr/blah", :status_code=>200}
- post_headers = {"Content-Type"=>"application/x-www-form-urlencoded"}
requestable.should_receive(:post).
with("http://127.0.0.1:8983/solr/blah", "", {"Content-Type"=>"application/x-www-form-urlencoded"}).
- and_return(expected_response)
- requestable.request('/blah', {}, :method => :post).should == expected_response
+ and_return(["", 200, "OK"])
+ requestable.request('/blah', {}, :method => :post)#.should == expected_response
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.