Created
December 5, 2013 02:26
-
-
Save csaunders/7799209 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/.gitignore b/.gitignore | |
index 8b6632c..2a33328 100644 | |
--- a/.gitignore | |
+++ b/.gitignore | |
@@ -5,3 +5,4 @@ rdoc | |
pkg | |
doc | |
.yardoc | |
+.rbenv-version | |
diff --git a/Gemfile b/Gemfile | |
index bd074a7..95a7840 100644 | |
--- a/Gemfile | |
+++ b/Gemfile | |
@@ -1,9 +1,9 @@ | |
source "http://rubygems.org" | |
-gem "nokogiri", "~> 1.4.6" | |
+gem "libxml-ruby", "~> 2.6.0" | |
group :development do | |
- gem "libxml-ruby", "~> 2.1.2" | |
+ gem "nokogiri", "~> 1.4.6" | |
gem "jeweler" | |
gem "git" | |
gem "rake" | |
diff --git a/Gemfile.lock b/Gemfile.lock | |
index 2200795..e7b7d02 100644 | |
--- a/Gemfile.lock | |
+++ b/Gemfile.lock | |
@@ -1,24 +1,44 @@ | |
GEM | |
remote: http://rubygems.org/ | |
specs: | |
- diff-lcs (1.1.2) | |
+ activesupport (3.2.13) | |
+ i18n (= 0.6.1) | |
+ multi_json (~> 1.0) | |
+ bourne (1.1.2) | |
+ mocha (= 0.10.5) | |
+ diff-lcs (1.2.1) | |
git (1.2.5) | |
- jeweler (1.6.4) | |
+ i18n (0.6.1) | |
+ jeweler (1.8.4) | |
bundler (~> 1.0) | |
git (>= 1.2.5) | |
rake | |
- libxml-ruby (2.1.2) | |
+ rdoc | |
+ json (1.7.7) | |
+ libxml-ruby (2.6.0) | |
+ metaclass (0.0.1) | |
+ mocha (0.10.5) | |
+ metaclass (~> 0.0.1) | |
+ multi_json (1.7.1) | |
nokogiri (1.4.7) | |
- rake (0.9.2) | |
- rspec (2.6.0) | |
- rspec-core (~> 2.6.0) | |
- rspec-expectations (~> 2.6.0) | |
- rspec-mocks (~> 2.6.0) | |
- rspec-core (2.6.4) | |
- rspec-expectations (2.6.0) | |
- diff-lcs (~> 1.1.2) | |
- rspec-mocks (2.6.0) | |
- shoulda (2.11.3) | |
+ rake (10.0.3) | |
+ rdoc (4.0.0) | |
+ json (~> 1.4) | |
+ rspec (2.13.0) | |
+ rspec-core (~> 2.13.0) | |
+ rspec-expectations (~> 2.13.0) | |
+ rspec-mocks (~> 2.13.0) | |
+ rspec-core (2.13.1) | |
+ rspec-expectations (2.13.0) | |
+ diff-lcs (>= 1.1.3, < 2.0) | |
+ rspec-mocks (2.13.0) | |
+ shoulda (3.3.2) | |
+ shoulda-context (~> 1.0.1) | |
+ shoulda-matchers (~> 1.4.1) | |
+ shoulda-context (1.0.2) | |
+ shoulda-matchers (1.4.2) | |
+ activesupport (>= 3.0.0) | |
+ bourne (~> 1.1.2) | |
PLATFORMS | |
ruby | |
@@ -26,7 +46,7 @@ PLATFORMS | |
DEPENDENCIES | |
git | |
jeweler | |
- libxml-ruby (~> 2.1.2) | |
+ libxml-ruby (~> 2.6.0) | |
nokogiri (~> 1.4.6) | |
rake | |
rspec (~> 2.0) | |
diff --git a/README.rdoc b/README.rdoc | |
index 436ebd1..cd26664 100644 | |
--- a/README.rdoc | |
+++ b/README.rdoc | |
@@ -1,24 +1,27 @@ | |
-= OpenSRS http://travis-ci.org/voxxit/opensrs.png | |
+= OpenSRS | |
+ | |
+{<img src="https://travis-ci.org/voxxit/opensrs.png" />}[https://travis-ci.org/voxxit/opensrs] | |
+{<img src="https://codeclimate.com/github/voxxit/opensrs.png" />}[https://codeclimate.com/github/voxxit/opensrs] | |
This (unofficial) OpenSRS gem provides basic support to connect to, and utilize the OpenSRS API. This library has been well-tested in high-performance production | |
environments. More information on the API can be located here: | |
-http://opensrs.com/resources/documentation/opensrs_xmlapi.pdf | |
+http://www.opensrs.com/site/resources/documentation/api | |
== Installation | |
You can install this gem by doing the following: | |
$ gem install opensrs | |
- | |
+ | |
You can then include it in a Ruby project, like so: | |
require 'opensrs' | |
- | |
+ | |
Alternatively, you can include it in a Rails 2.x project in the <tt>environment.rb</tt> file, like so: | |
config.gem "opensrs" | |
- | |
+ | |
For Rails 3.x, use the <tt>Gemfile</tt>: | |
gem "opensrs" | |
@@ -55,7 +58,7 @@ Once you have a server connection class, you can build from this to create the m | |
:object => "BALANCE" | |
) | |
end | |
- | |
+ | |
Sometimes you might need to include attributes for the command, such as a cookie, or the data attributes themselves. You can do this, too: | |
def create_nameserver(nameserver) | |
@@ -69,7 +72,7 @@ Sometimes you might need to include attributes for the command, such as a cookie | |
} | |
) | |
end | |
- | |
+ | |
Responses from OpenSRS are returned in an OpenSRS::Response object, which gives you access to a multitude of things. | |
* <tt>response.response</tt> - This gives you the response in a Hash form, which is highly accessible to most other actions in your application. | |
@@ -92,6 +95,11 @@ http://github.com/voxxit/opensrs/issues | |
* Commit, do not mess with rakefile, version, or history. If you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull. | |
* Send me a pull request. Bonus points for topic branches. | |
+== Contributors (in order of appearance) | |
+ | |
+* Josh Delsman | |
+* Glenn Roberts | |
+ | |
== Copyright | |
-Copyright (c) 2010-2011 Josh Delsman. Distributed under the MIT license. See LICENSE for details. | |
\ No newline at end of file | |
+Copyright (c) 2010-2013 Josh Delsman. Distributed under the MIT license. See LICENSE for details. | |
diff --git a/lib/opensrs.rb b/lib/opensrs.rb | |
index 49571b6..a3490b4 100644 | |
--- a/lib/opensrs.rb | |
+++ b/lib/opensrs.rb | |
@@ -1,8 +1,8 @@ | |
require File.dirname(__FILE__) + '/opensrs/xml_processor' | |
-require File.dirname(__FILE__) + '/opensrs/xml_processor/nokogiri.rb' | |
+require File.dirname(__FILE__) + '/opensrs/xml_processor/libxml.rb' | |
require File.dirname(__FILE__) + '/opensrs/server.rb' | |
require File.dirname(__FILE__) + '/opensrs/response.rb' | |
require File.dirname(__FILE__) + '/opensrs/version.rb' | |
module OpenSRS | |
-end | |
+end | |
\ No newline at end of file | |
diff --git a/lib/opensrs/server.rb b/lib/opensrs/server.rb | |
index 1e78d55..ea8e82d 100644 | |
--- a/lib/opensrs/server.rb | |
+++ b/lib/opensrs/server.rb | |
@@ -5,33 +5,33 @@ require "openssl" | |
module OpenSRS | |
class BadResponse < StandardError; end | |
- | |
+ class TimeoutError < StandardError; end | |
+ | |
class Server | |
- attr_accessor :server, :username, :password, :key, :logger | |
+ attr_accessor :server, :username, :password, :key, :timeout, :open_timeout | |
def initialize(options = {}) | |
@server = URI.parse(options[:server] || "https://rr-n1-tor.opensrs.net:55443/") | |
@username = options[:username] | |
@password = options[:password] | |
@key = options[:key] | |
- @logger = options[:logger] | |
+ @timeout = options[:timeout] | |
+ @open_timeout = options[:open_timeout] | |
end | |
- def call(options = {}) | |
- attributes = { | |
- :protocol => "XCP" | |
- } | |
- | |
- xml = xml_processor.build(attributes.merge!(options)) | |
- log(xml, "Request XML for #{options[:object]} #{options[:action]}") | |
+ def call(data = {}) | |
+ xml = xml_processor.build({ :protocol => "XCP" }.merge!(data)) | |
+ | |
+ begin | |
+ response = http.post(server_path, xml, headers(xml)) | |
+ rescue Net::HTTPBadResponse | |
+ raise OpenSRS::BadResponse, "Received a bad response from OpenSRS. Please check that your IP address is added to the whitelist, and try again." | |
+ end | |
- response = http.post(server.path, xml, headers(xml)) | |
- log(response.body, "Response XML for #{options[:object]} #{options[:action]}") | |
parsed_response = xml_processor.parse(response.body) | |
- | |
return OpenSRS::Response.new(parsed_response, xml, response.body) | |
- rescue Net::HTTPBadResponse | |
- raise OpenSRS::BadResponse, "Received a bad response from OpenSRS. Please check that your IP address is added to the whitelist, and try again." | |
+ rescue Timeout::Error => err | |
+ raise OpenSRS::TimeoutError, err | |
end | |
def xml_processor | |
@@ -43,40 +43,35 @@ module OpenSRS | |
@@xml_processor = OpenSRS::XmlProcessor.const_get("#{name.to_s.capitalize}") | |
end | |
- OpenSRS::Server.xml_processor = :nokogiri | |
- | |
+ OpenSRS::Server.xml_processor = :libxml | |
+ | |
private | |
- | |
+ | |
def headers(request) | |
- headers = { | |
- "Content-Length" => request.length.to_s, | |
+ { "Content-Length" => request.length.to_s, | |
"Content-Type" => "text/xml", | |
"X-Username" => username, | |
"X-Signature" => signature(request) | |
} | |
- | |
- return headers | |
end | |
- | |
+ | |
def signature(request) | |
signature = Digest::MD5.hexdigest(request + key) | |
signature = Digest::MD5.hexdigest(signature + key) | |
signature | |
end | |
- | |
+ | |
def http | |
http = Net::HTTP.new(server.host, server.port) | |
http.use_ssl = (server.scheme == "https") | |
http.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
+ http.read_timeout = http.open_timeout = @timeout if @timeout | |
+ http.open_timeout = @open_timeout if @open_timeout | |
http | |
end | |
- def log(data, message) | |
- return unless logger | |
- | |
- message = "[OpenSRS] " + message | |
- line = [message, data].join("\n") | |
- logger.info(line) | |
+ def server_path | |
+ server.path.empty? ? '/' : server.path | |
end | |
end | |
end | |
diff --git a/lib/opensrs/version.rb b/lib/opensrs/version.rb | |
index b361625..3c72fb0 100644 | |
--- a/lib/opensrs/version.rb | |
+++ b/lib/opensrs/version.rb | |
@@ -1,5 +1,5 @@ | |
module OpenSRS | |
class Version | |
- VERSION = "0.3.2" | |
+ VERSION = "0.3.4" | |
end | |
end | |
diff --git a/lib/opensrs/xml_processor.rb b/lib/opensrs/xml_processor.rb | |
index 325cf7a..d3d87eb 100644 | |
--- a/lib/opensrs/xml_processor.rb | |
+++ b/lib/opensrs/xml_processor.rb | |
@@ -16,16 +16,16 @@ module OpenSRS | |
# Encodes individual elements, and their child elements, for the root XML document. | |
def self.encode_data(data, container = nil) | |
- case data | |
- when Array | |
- encode_dt_array(data, container) | |
- when Hash | |
- encode_dt_assoc(data, container) | |
- when String, Numeric, Date, Time, Symbol, NilClass | |
- data.to_s | |
+ case data.class.to_s | |
+ when "Array" then return encode_dt_array(data, container) | |
+ when "Hash" then return encode_dt_assoc(data, container) | |
+ when "String", "Numeric", "Date", "Time", "Symbol", "NilClass" | |
+ return data.to_s | |
else | |
- data.inspect | |
+ return data.inspect | |
end | |
+ | |
+ return nil | |
end | |
def self.encode_dt_array(data, container) | |
@@ -39,7 +39,7 @@ module OpenSRS | |
dt_array << item_node | |
end | |
- dt_array | |
+ return dt_array | |
end | |
def self.encode_dt_assoc(data, container) | |
@@ -53,7 +53,7 @@ module OpenSRS | |
dt_assoc << item_node | |
end | |
- dt_assoc | |
+ return dt_assoc | |
end | |
# Recursively decodes individual data elements from OpenSRS | |
@@ -74,4 +74,4 @@ module OpenSRS | |
end | |
-end | |
+end | |
\ No newline at end of file | |
diff --git a/opensrs.gemspec b/opensrs.gemspec | |
index e368ddf..204a471 100644 | |
--- a/opensrs.gemspec | |
+++ b/opensrs.gemspec | |
@@ -4,14 +4,14 @@ | |
# -*- encoding: utf-8 -*- | |
Gem::Specification.new do |s| | |
- s.name = %q{opensrs} | |
- s.version = "0.3.2" | |
+ s.name = "opensrs" | |
+ s.version = "0.3.4" | |
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= | |
s.authors = ["Josh Delsman"] | |
- s.date = %q{2011-08-08} | |
- s.description = %q{Provides support to utilize the OpenSRS API with Ruby/Rails.} | |
- s.email = %q{[email protected]} | |
+ s.date = "2013-04-04" | |
+ s.description = "Provides support to utilize the OpenSRS API with Ruby/Rails." | |
+ s.email = "[email protected]" | |
s.extra_rdoc_files = [ | |
"LICENSE", | |
"README.rdoc" | |
@@ -37,26 +37,26 @@ Gem::Specification.new do |s| | |
"spec/opensrs/xml_processor/nokogiri_spec.rb", | |
"spec/spec_helper.rb" | |
] | |
- s.homepage = %q{http://github.com/voxxit/opensrs} | |
+ s.homepage = "http://github.com/voxxit/opensrs" | |
s.licenses = ["MIT"] | |
s.require_paths = ["lib"] | |
- s.rubygems_version = %q{1.6.2} | |
- s.summary = %q{Provides support to utilize the OpenSRS API with Ruby/Rails.} | |
+ s.rubygems_version = "1.8.23" | |
+ s.summary = "Provides support to utilize the OpenSRS API with Ruby/Rails." | |
if s.respond_to? :specification_version then | |
s.specification_version = 3 | |
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then | |
- s.add_runtime_dependency(%q<nokogiri>, ["~> 1.4.6"]) | |
- s.add_development_dependency(%q<libxml-ruby>, ["~> 2.1.2"]) | |
+ s.add_runtime_dependency(%q<libxml-ruby>, ["~> 2.6.0"]) | |
+ s.add_development_dependency(%q<nokogiri>, ["~> 1.4.6"]) | |
s.add_development_dependency(%q<jeweler>, [">= 0"]) | |
s.add_development_dependency(%q<git>, [">= 0"]) | |
s.add_development_dependency(%q<rake>, [">= 0"]) | |
s.add_development_dependency(%q<shoulda>, [">= 0"]) | |
s.add_development_dependency(%q<rspec>, ["~> 2.0"]) | |
else | |
+ s.add_dependency(%q<libxml-ruby>, ["~> 2.6.0"]) | |
s.add_dependency(%q<nokogiri>, ["~> 1.4.6"]) | |
- s.add_dependency(%q<libxml-ruby>, ["~> 2.1.2"]) | |
s.add_dependency(%q<jeweler>, [">= 0"]) | |
s.add_dependency(%q<git>, [">= 0"]) | |
s.add_dependency(%q<rake>, [">= 0"]) | |
@@ -64,8 +64,8 @@ Gem::Specification.new do |s| | |
s.add_dependency(%q<rspec>, ["~> 2.0"]) | |
end | |
else | |
+ s.add_dependency(%q<libxml-ruby>, ["~> 2.6.0"]) | |
s.add_dependency(%q<nokogiri>, ["~> 1.4.6"]) | |
- s.add_dependency(%q<libxml-ruby>, ["~> 2.1.2"]) | |
s.add_dependency(%q<jeweler>, [">= 0"]) | |
s.add_dependency(%q<git>, [">= 0"]) | |
s.add_dependency(%q<rake>, [">= 0"]) | |
diff --git a/spec/opensrs/server_spec.rb b/spec/opensrs/server_spec.rb | |
index 4f5fabe..2664031 100644 | |
--- a/spec/opensrs/server_spec.rb | |
+++ b/spec/opensrs/server_spec.rb | |
@@ -1,21 +1,109 @@ | |
require 'spec_helper' | |
describe OpenSRS::Server do | |
- before(:each) do | |
- @server = OpenSRS::Server.new | |
+ let(:server) { OpenSRS::Server.new } | |
+ | |
+ describe '#new' do | |
+ it 'allows timeouts to be set' do | |
+ server = OpenSRS::Server.new({ :timeout => 90 }) | |
+ server.timeout.should == 90 | |
+ server.open_timeout.should be_nil | |
+ end | |
+ | |
+ it 'allows open timeouts to be set' do | |
+ server = OpenSRS::Server.new({ :timeout => 90, :open_timeout => 10 }) | |
+ server.timeout.should eq(90) | |
+ server.open_timeout.should eq(10) | |
+ end | |
+ | |
+ it 'leaves it up to Net::HTTP if no timeouts given' do | |
+ server.timeout.should be_nil | |
+ server.open_timeout.should be_nil | |
+ end | |
+ end | |
+ | |
+ describe ".call" do | |
+ let(:response) { double(:body => 'some response') } | |
+ let(:header) { {"some" => "header" } } | |
+ let(:xml) { '<some xml></some xml>' } | |
+ let(:response_xml) { xml } | |
+ let(:xml_processor) { double OpenSRS::XmlProcessor } | |
+ let(:http) { double(Net::HTTP, :use_ssl= => true, :verify_mode= => true) } | |
+ | |
+ before :each do | |
+ server.stub(:headers).and_return header | |
+ xml_processor.stub(:build).and_return xml | |
+ xml_processor.stub(:parse).and_return response_xml | |
+ server.stub(:xml_processor).and_return xml_processor | |
+ http.stub(:post).and_return response | |
+ Net::HTTP.stub(:new).and_return http | |
+ end | |
+ | |
+ it "builds XML request" do | |
+ xml_processor.should_receive(:build).with(:protocol => "XCP", :some => 'option') | |
+ server.call(:some => 'option') | |
+ end | |
+ | |
+ it "posts to given path" do | |
+ server.server = URI.parse 'http://with-path.com/endpoint' | |
+ http.should_receive(:post).with('/endpoint', xml, header).and_return double.as_null_object | |
+ server.call | |
+ end | |
+ | |
+ it "parses the response" do | |
+ xml_processor.should_receive(:parse).with(response.body) | |
+ server.call(:some => 'option') | |
+ end | |
+ | |
+ it "posts to root path" do | |
+ server.server = URI.parse 'http://root-path.com/' | |
+ http.should_receive(:post).with('/', xml, header).and_return double.as_null_object | |
+ server.call | |
+ end | |
+ | |
+ it "defaults path to '/'" do | |
+ server.server = URI.parse 'http://no-path.com' | |
+ http.should_receive(:post).with('/', xml, header).and_return double.as_null_object | |
+ server.call | |
+ end | |
+ | |
+ it 'allows overriding of default (Net:HTTP) timeouts' do | |
+ server.timeout = 90 | |
+ | |
+ http.should_receive(:open_timeout=).with(90) | |
+ http.should_receive(:read_timeout=).with(90) | |
+ | |
+ server.call( { :some => 'data' } ) | |
+ end | |
+ | |
+ it 'allows overriding of default (Net:HTTP) timeouts' do | |
+ server.timeout = 180 | |
+ server.open_timeout = 30 | |
+ | |
+ http.should_receive(:read_timeout=).with(180) | |
+ http.should_receive(:open_timeout=).with(180) | |
+ http.should_receive(:open_timeout=).with(30) | |
+ | |
+ server.call( { :some => 'data' } ) | |
+ end | |
+ | |
+ it 're-raises Net:HTTP timeouts' do | |
+ http.should_receive(:post).and_raise err = Timeout::Error.new('test') | |
+ expect { server.call }.to raise_exception OpenSRS::TimeoutError | |
+ end | |
end | |
describe "#test xml processor" do | |
context "on class initialization" do | |
- it { @server.xml_processor.should eql(OpenSRS::XmlProcessor::Nokogiri) } | |
+ it { server.xml_processor.should eql(OpenSRS::XmlProcessor::Libxml) } | |
end | |
context "on changing xml processor" do | |
before(:each) do | |
- OpenSRS::Server.xml_processor = :libxml | |
+ OpenSRS::Server.xml_processor = :nokogiri | |
end | |
- it { @server.xml_processor.should eql(OpenSRS::XmlProcessor::Libxml) } | |
+ it { server.xml_processor.should eql(OpenSRS::XmlProcessor::Nokogiri) } | |
end | |
end | |
end | |
diff --git a/spec/opensrs/version_spec.rb b/spec/opensrs/version_spec.rb | |
index dfa8268..fa40a60 100644 | |
--- a/spec/opensrs/version_spec.rb | |
+++ b/spec/opensrs/version_spec.rb | |
@@ -3,7 +3,7 @@ require 'spec_helper' | |
describe OpenSRS::Version do | |
describe "VERSION" do | |
it "should return version string" do | |
- OpenSRS::Version::VERSION.should eql("0.3.2") | |
+ OpenSRS::Version::VERSION.should eql("0.3.4") | |
end | |
end | |
-end | |
\ No newline at end of file | |
+end | |
diff --git a/spec/opensrs/xml_processor/nokogiri_spec.rb b/spec/opensrs/xml_processor/nokogiri_spec.rb | |
index fa47d93..4323e09 100644 | |
--- a/spec/opensrs/xml_processor/nokogiri_spec.rb | |
+++ b/spec/opensrs/xml_processor/nokogiri_spec.rb | |
@@ -1,9 +1,6 @@ | |
require 'spec_helper' | |
require 'date' | |
-class OrderedHash < Hash | |
-end | |
- | |
describe OpenSRS::XmlProcessor::Nokogiri do | |
describe ".build" do | |
it "should create XML for a nested hash" do | |
@@ -51,22 +48,6 @@ describe OpenSRS::XmlProcessor::Nokogiri do | |
it { @e.children[0].attributes["key"].value.should eql('name') } | |
end | |
- context "on a hash subclass" do | |
- before(:each) do | |
- ohash = OrderedHash.new | |
- ohash[:name] = 'kitten' | |
- @e = OpenSRS::XmlProcessor::Nokogiri.encode_data(ohash, @doc) | |
- end | |
- | |
- it { @e.should be_an_instance_of(::Nokogiri::XML::Element) } | |
- it { @e.name.should eql('dt_assoc') } | |
- | |
- it { @e.should have(1).children } | |
- it { @e.children[0].name.should eql('item') } | |
- it { @e.children[0].attributes["key"].value.should eql('name') } | |
- end | |
- | |
- | |
context "on a nested hash" do | |
before(:each) do | |
@e = OpenSRS::XmlProcessor::Nokogiri.encode_data({:suggestion => {:maximum => "10"}}, @doc) | |
@@ -244,4 +225,4 @@ describe OpenSRS::XmlProcessor::Nokogiri do | |
end | |
end | |
-end | |
+end | |
\ No newline at end of file | |
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb | |
index 7c6c8f2..65d02c8 100644 | |
--- a/spec/spec_helper.rb | |
+++ b/spec/spec_helper.rb | |
@@ -2,4 +2,5 @@ require 'opensrs/xml_processor.rb' | |
require 'opensrs/xml_processor/libxml.rb' | |
require 'opensrs/xml_processor/nokogiri.rb' | |
require 'opensrs/server.rb' | |
-require 'opensrs/version.rb' | |
\ No newline at end of file | |
+require 'opensrs/version.rb' | |
+require 'opensrs/response.rb' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment