epp-client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Geoff Garside
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ = epp-client
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (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)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Geoff Garside. See LICENSE for details.
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "epp-client"
8
+ gem.summary = %Q{EPP (Extensible Provisioning Protocol) Client}
9
+ gem.description = %Q{Client for communicating with EPP services}
10
+ gem.email = "geoff@geoffgarside.co.uk"
11
+ gem.homepage = "http://github.com/geoffgarside/epp-client"
12
+ gem.authors = ["Geoff Garside"]
13
+ gem.add_development_dependency "shoulda", ">= 0"
14
+ gem.add_development_dependency "yard", ">= 0"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+
17
+ gem.add_dependency "libxml-ruby", ">= 0"
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/test_*.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/test_*.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ task :test => :check_dependencies
45
+
46
+ task :default => :test
47
+
48
+ begin
49
+ require 'yard'
50
+ YARD::Rake::YardocTask.new
51
+ rescue LoadError
52
+ task :yardoc do
53
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
54
+ end
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,65 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{epp-client}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Geoff Garside"]
12
+ s.date = %q{2010-12-20}
13
+ s.description = %q{Client for communicating with EPP services}
14
+ s.email = %q{geoff@geoffgarside.co.uk}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "epp-client.gemspec",
26
+ "lib/epp-client.rb",
27
+ "lib/epp-client/client.rb",
28
+ "lib/epp-client/hello_request.rb",
29
+ "lib/epp-client/old_server.rb",
30
+ "lib/epp-client/request.rb",
31
+ "lib/epp-client/response.rb",
32
+ "lib/epp-client/response_error.rb",
33
+ "lib/epp-client/server.rb",
34
+ "test/helper.rb",
35
+ "test/test_epp-client.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/geoffgarside/epp-client}
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{EPP (Extensible Provisioning Protocol) Client}
41
+ s.test_files = [
42
+ "test/helper.rb",
43
+ "test/test_epp-client.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
52
+ s.add_development_dependency(%q<yard>, [">= 0"])
53
+ s.add_runtime_dependency(%q<libxml-ruby>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<shoulda>, [">= 0"])
56
+ s.add_dependency(%q<yard>, [">= 0"])
57
+ s.add_dependency(%q<libxml-ruby>, [">= 0"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<shoulda>, [">= 0"])
61
+ s.add_dependency(%q<yard>, [">= 0"])
62
+ s.add_dependency(%q<libxml-ruby>, [">= 0"])
63
+ end
64
+ end
65
+
@@ -0,0 +1,14 @@
1
+ require 'openssl'
2
+ require 'socket'
3
+ require 'xml'
4
+
5
+ # EPP Module
6
+ module EPP
7
+ autoload :Client, File.dirname(__FILE__) + '/epp-client/client.rb'
8
+ autoload :Server, File.dirname(__FILE__) + '/epp-client/server.rb'
9
+ autoload :OldServer, File.dirname(__FILE__) + '/epp-client/old_server.rb'
10
+ autoload :Request, File.dirname(__FILE__) + '/epp-client/request.rb'
11
+ autoload :Response, File.dirname(__FILE__) + '/epp-client/response.rb'
12
+ autoload :ResponseError, File.dirname(__FILE__) + '/epp-client/response_error.rb'
13
+ autoload :HelloRequest, File.dirname(__FILE__) + '/epp-client/hello_request.rb'
14
+ end
@@ -0,0 +1,48 @@
1
+ module EPP
2
+ # Front facing EPP Client.
3
+ #
4
+ # Establishes a connection to an EPP server and allows for sending commands
5
+ # to that EPP server.
6
+ class Client
7
+ # Create new instance of EPP::Client.
8
+ #
9
+ # @param [String] tag EPP Tag
10
+ # @param [String] passwd EPP Tag password
11
+ # @param [String] host EPP Host address
12
+ # @param [Hash] options Options
13
+ # @option options [Boolean] :compatibility If compatibility mode should be used?
14
+ def initialize(tag, passwd, host, options = {})
15
+ @conn = if options.delete(:compatibility) == true
16
+ OldServer.new(tag, passwd, host, options)
17
+ else
18
+ Server.new(tag, passwd, host, options)
19
+ end
20
+ end
21
+
22
+ # Send hello command
23
+ def hello
24
+ @conn.connection do
25
+ @conn.hello
26
+ end
27
+ end
28
+
29
+ # Calls an EPP command after connecting to the EPP Server and logging in.
30
+ #
31
+ # @overload method_missing(command, payload)
32
+ # @param [String, #to_s] command EPP Command to call
33
+ # @param [XML::Node, XML::Document, String] payload EPP XML Payload
34
+ # @overload method_missing(command)
35
+ # @param [String, #to_s] command EPP Command to call
36
+ # @yield [xml] block to construct payload
37
+ # @yieldparam [XML::Node] xml XML Node of the command
38
+ # for the payload to be added into
39
+ # @return [Response] EPP Response object
40
+ def method_missing(command, payload = nil, &block)
41
+ @conn.connection do
42
+ @conn.with_login do
43
+ @conn.request(command, payload, &block)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,9 @@
1
+ module EPP
2
+ # An EPP Hello Request
3
+ class HelloRequest < Request
4
+ # Create new HelloRequest instance
5
+ def initialize
6
+ xml.root << XML::Node.new('hello')
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ module EPP
2
+ # Handles sending and receiving data to older EPP servers.
3
+ #
4
+ # These servers transmit the payload with CRLF at the end
5
+ # and recieve one byte at a time until EOF is reached.
6
+ class OldServer < Server
7
+ # Sends frame using old method
8
+ #
9
+ # @param [String] xml XML payload to send
10
+ def send_frame(xml)
11
+ @sock.write(xml + "\r\n")
12
+ end
13
+
14
+ # Receives frame using old method
15
+ #
16
+ # @return [String] XML Payload response
17
+ def recv_frame
18
+ data = ''
19
+ until @sock.eof?
20
+ data << @sock.read(1)
21
+ end
22
+ data
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,96 @@
1
+ module EPP
2
+ # An EPP XML Request
3
+ class Request
4
+ # Create new instance of EPP::Request.
5
+ #
6
+ # @overload initialize(command, payload, transaction_id)
7
+ # @param [String, #to_s] command EPP Command to call
8
+ # @param [XML::Node, XML::Document, String] payload XML Payload to transmit
9
+ # @param [String] transaction_id EPP Transaction ID
10
+ # @overload initialize(command, transaction_id) {|xml| payload }
11
+ # @param [String, #to_s] command EPP Command to call
12
+ # @param [String] transaction_id EPP Transaction ID
13
+ # @yield [xml] block to construct payload
14
+ # @yieldparam [XML::Node] xml XML Node of the command
15
+ # for the payload to be added into
16
+ def initialize(command, *args, &block)
17
+ @command = XML::Node.new(command)
18
+
19
+ cmd = XML::Node.new('command')
20
+ cmd << @command
21
+ xml.root << cmd
22
+
23
+ if block_given?
24
+ tid, _ = args
25
+ case block.arity
26
+ when 1
27
+ block.call(@command)
28
+ else
29
+ @command << block.call
30
+ end
31
+ else
32
+ payload, tid = args
33
+ unless payload.nil?
34
+ @command << case payload.class
35
+ when XML::Node
36
+ payload
37
+ when XML::Document
38
+ xml.import(payload.root)
39
+ else
40
+ doc = XML::Parser.string(payload.to_s).parse
41
+ xml.import(doc.root)
42
+ end
43
+ end
44
+ end
45
+
46
+ unless command == 'logout'
47
+ cmd << XML::Node.new('clTRID', tid || 'ABC-12345')
48
+ end
49
+ end
50
+
51
+ # Name of the receivers command
52
+ # @return [String] command name
53
+ def command
54
+ @command.name
55
+ end
56
+
57
+ # Receiver in XML form
58
+ # @return [XML::Document] XML of the receiver
59
+ def to_xml
60
+ xml
61
+ end
62
+
63
+ # Convert the receiver to a string
64
+ #
65
+ # @param [Hash] opts Formatting options, passed to the XML::Document
66
+ def to_s(opts = {})
67
+ xml.to_s({:indent => false}.merge(opts))
68
+ end
69
+
70
+ # @see Object#inspect
71
+ def inspect
72
+ xml.inspect
73
+ end
74
+
75
+ private
76
+ # Request XML Payload
77
+ # @see prepare_request
78
+ def xml
79
+ @xml ||= prepare_request
80
+ end
81
+
82
+ # Prepares the base XML for the request
83
+ #
84
+ # @return [XML::Document]
85
+ def prepare_request
86
+ xml = XML::Document.new('1.0')
87
+ xml.root = XML::Node.new('epp')
88
+ xml.root.namespaces.namespace =
89
+ XML::Namespace.new(xml.root, nil, 'urn:ietf:params:xml:ns:epp-1.0')
90
+ XML::Namespace.new(xml.root, 'xsi', 'http://www.w3.org/2001/XMLSchema-instance')
91
+ xml.root['xsi:schemaLocation'] = "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"
92
+
93
+ xml
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,63 @@
1
+ module EPP
2
+ # An EPP XML Response
3
+ class Response
4
+ # Creates an instance of an EPP::Response
5
+ #
6
+ # @param [String] xml_string XML Response
7
+ def initialize(xml_string)
8
+ @xml = XML::Parser.string(xml_string).parse
9
+ @xml.root.namespaces.default_prefix = 'e'
10
+ end
11
+
12
+ # Indicates if the response is successful.
13
+ # @return [Boolean] if the response is successful
14
+ def success?
15
+ code == 1000
16
+ end
17
+
18
+ # Response code
19
+ # @return [Integer] response code
20
+ def code
21
+ @code ||= result['code'].to_i
22
+ end
23
+
24
+ # Response message
25
+ # @return [String] response message
26
+ def message
27
+ @message ||= result.find('e:msg/text()').first.content.strip
28
+ end
29
+
30
+ # Response data
31
+ # @return [String] response data
32
+ def data
33
+ unless @data
34
+ list = @xml.find('/e:epp/e:response/e:resData/node()').reject{|n| n.empty?}
35
+ @data = list.size > 1 ? list : list[0]
36
+ end
37
+ @data
38
+ end
39
+
40
+ # Response Message Queue
41
+ # @return [XML::Node] message queue
42
+ def msgQ
43
+ @msgQ ||= @xml.find('/e:epp/e:response/e:msgQ').first
44
+ end
45
+
46
+ # @see Object#inspect
47
+ def inspect
48
+ @xml.inspect
49
+ end
50
+
51
+ # Returns a the formatted response XML
52
+ # @return [String] formatted XML response
53
+ def to_xml
54
+ @xml.to_s(:indent => true)
55
+ end
56
+
57
+ private
58
+ # @return [XML::Node] Result node
59
+ def result
60
+ @result ||= @xml.find('/e:epp/e:response/e:result').first
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,15 @@
1
+ module EPP
2
+ # Error response
3
+ class ResponseError < RuntimeError
4
+ attr_accessor :code, :xml
5
+ # Create new ResponseError
6
+ def initialize(code, msg, xml)
7
+ super(msg)
8
+ @code, @xml = code, xml
9
+ end
10
+ # @return [String] Formatted Response error
11
+ def to_s
12
+ "#{message} (code #{code})"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,207 @@
1
+ module EPP
2
+ # A server error
3
+ class ServerError < RuntimeError; end
4
+
5
+ # Handles sending and receiving data to EPP servers.
6
+ # Supports new style EPP servers which include length of payloads in transmission.
7
+ class Server
8
+
9
+ # Default Service URNs
10
+ DEFAULT_SERVICES = %w(urn:ietf:params:xml:ns:domain-1.0
11
+ urn:ietf:params:xml:ns:contact-1.0 urn:ietf:params:xml:ns:host-1.0)
12
+
13
+ # Default connection options
14
+ DEFAULTS = { :port => 700, :compatibility => false, :lang => 'en', :version => '1.0',
15
+ :extensions => [], :services => DEFAULT_SERVICES }
16
+
17
+ # Receive frame header length
18
+ # @private
19
+ HEADER_LEN = 4
20
+
21
+ # @param [String] tag EPP Tag
22
+ # @param [String] passwd EPP Tag password
23
+ # @param [String] host EPP Server address
24
+ # @param [Hash] options configuration options
25
+ # @option options [Integer] :port EPP Port number, default 700
26
+ # @option options [Boolean] :compatibility Compatibility mode, default false
27
+ # @option options [String] :lang EPP Language code, default 'en'
28
+ # @option options [String] :version EPP protocol version, default '1.0'
29
+ # @option options [Array<String>] :extensions EPP Extension URNs
30
+ # @option options [Array<String>] :services EPP Service URNs
31
+ def initialize(tag, passwd, host, options = {})
32
+ @tag, @passwd, @host = tag, passwd, host
33
+ @options = DEFAULTS.merge(options)
34
+ end
35
+
36
+ # Sends a Hello Request to the server
37
+ # @return [Boolean] True if greeting was returned
38
+ def hello
39
+ send_frame(HelloRequest.new.to_s)
40
+ return true if recv_frame =~ /<greeting>/
41
+ false
42
+ end
43
+
44
+ # Send request to server
45
+ #
46
+ # @overload request(command, payload)
47
+ # @param [String, #to_s] command EPP Command to call
48
+ # @param [XML::Node, XML::Document, String] payload EPP XML Payload
49
+ # @overload request(command)
50
+ # @param [String, #to_s] command EPP Command to call
51
+ # @yield [xml] block to construct payload
52
+ # @yieldparam [XML::Node] xml XML Node of the command
53
+ # for the payload to be added into
54
+ # @return [Response] EPP Response object
55
+ def request(command, payload = nil, &block)
56
+ req = if payload.nil? && block_given?
57
+ Request.new(command, next_tid, &block)
58
+ else
59
+ Request.new(command, payload, next_tid)
60
+ end
61
+
62
+ send_recv_frame(req.to_s)
63
+ end
64
+
65
+ # Runs a block while logged into the receiver
66
+ #
67
+ # @yield logged in EPP server session
68
+ # @example typical usage
69
+ # with_login do
70
+ # # .. do stuff with logged in session ..
71
+ # end
72
+ def with_login
73
+ login!
74
+
75
+ begin
76
+ yield
77
+ ensure
78
+ logout!
79
+ end
80
+ end
81
+
82
+ # EPP Server Connection
83
+ #
84
+ # @yield connected session
85
+ # @example typical usage
86
+ # connection do
87
+ # # .. do stuff with logged in session ..
88
+ # end
89
+ # @example usage with with_login
90
+ # connection do
91
+ # with_login do
92
+ # # .. do stuff with logged in session ..
93
+ # end
94
+ # end
95
+ def connection
96
+ @conn = TCPSocket.new(@host, @options[:port])
97
+ @sock = OpenSSL::SSL::SSLSocket.new(@conn)
98
+ @sock.sync_close
99
+
100
+ begin
101
+ @sock.connect
102
+ recv_frame # Perform initial recv
103
+
104
+ yield
105
+ ensure
106
+ @sock.close
107
+ @conn.close
108
+ conn = sock = nil
109
+ end
110
+ end
111
+ private
112
+ # @return [String] next transaction id
113
+ def next_tid
114
+ @tid ||= 0
115
+ @tid += 1
116
+ "%s-%06d" % [@tag, @tid]
117
+ end
118
+
119
+ # @return [Request] Login Request Payload
120
+ def login_request
121
+ Request.new('login', next_tid) do |login|
122
+ login << XML::Node.new('clID', @tag)
123
+ login << XML::Node.new('pw', @passwd)
124
+
125
+ options = XML::Node.new('options')
126
+ options << XML::Node.new('version', @options[:version])
127
+ options << XML::Node.new('lang', @options[:lang])
128
+ login << options
129
+
130
+ svcs = XML::Node.new('svcs')
131
+ @options[:services].each { |uri| svcs << XML::Node.new('objURI', uri) }
132
+ login << svcs
133
+
134
+ unless @options[:extensions].empty?
135
+ ext = XML::Node.new('svcExtension')
136
+ @options[:extensions].each do |uri|
137
+ ext << XML::Node.new('extURI', uri)
138
+ end
139
+ svcs << ext
140
+ end
141
+ end
142
+ end
143
+
144
+ # @return [Request] Logout Request Payload
145
+ def logout_request
146
+ Request.new('logout')
147
+ end
148
+
149
+ # Perform login
150
+ #
151
+ # @return [true] login successful
152
+ # @raise [ResponseError] login failed
153
+ # @see login_request
154
+ def login!
155
+ response = send_recv_frame(login_request.to_s)
156
+
157
+ return true if response.code == 1000
158
+ raise ResponseError.new(response.code, response.message, response.to_xml)
159
+ end
160
+
161
+ # Perform logout
162
+ #
163
+ # @return [true] logout successful
164
+ # @raise [ResponseError] logout failed
165
+ # @see logout_request
166
+ def logout!
167
+ response = send_recv_frame(logout_request.to_s)
168
+
169
+ return true if response.code == 1500
170
+ raise ResponseError.new(response.code, response.message, response.to_xml)
171
+ end
172
+
173
+ # Send a frame and receive its response
174
+ #
175
+ # @param [String] xml XML Payload to send
176
+ # @return [Response] EPP Response
177
+ # @see send_frame
178
+ # @see recv_frame
179
+ def send_recv_frame(xml)
180
+ send_frame(xml)
181
+ Response.new(recv_frame)
182
+ end
183
+
184
+ # Send XML frame
185
+ # @return [Integer] number of bytes written
186
+ def send_frame(xml)
187
+ @sock.write([xml.size + 4].pack("N") + xml)
188
+ end
189
+
190
+ # Receive XML frame
191
+ # @return [String] XML response
192
+ def recv_frame
193
+ header = @sock.read(HEADER_LEN)
194
+
195
+ if header.nil? && @sock.eof?
196
+ raise ServerError, "Connection terminated by remote host"
197
+ elsif header.nil?
198
+ raise ServerError, "Failed to read header from remote host"
199
+ else
200
+ len = header.unpack('N')[0]
201
+
202
+ raise ServerError, "Bad frame header from server, should be greater than #{HEADER_LEN}" unless len > HEADER_LEN
203
+ response = @sock.read(len - HEADER_LEN)
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'epp-client'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestEppClient < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: epp-client
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Geoff Garside
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-20 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: libxml-ruby
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ description: Client for communicating with EPP services
64
+ email: geoff@geoffgarside.co.uk
65
+ executables: []
66
+
67
+ extensions: []
68
+
69
+ extra_rdoc_files:
70
+ - LICENSE
71
+ - README.rdoc
72
+ files:
73
+ - .document
74
+ - LICENSE
75
+ - README.rdoc
76
+ - Rakefile
77
+ - VERSION
78
+ - epp-client.gemspec
79
+ - lib/epp-client.rb
80
+ - lib/epp-client/client.rb
81
+ - lib/epp-client/hello_request.rb
82
+ - lib/epp-client/old_server.rb
83
+ - lib/epp-client/request.rb
84
+ - lib/epp-client/response.rb
85
+ - lib/epp-client/response_error.rb
86
+ - lib/epp-client/server.rb
87
+ - test/helper.rb
88
+ - test/test_epp-client.rb
89
+ has_rdoc: true
90
+ homepage: http://github.com/geoffgarside/epp-client
91
+ licenses: []
92
+
93
+ post_install_message:
94
+ rdoc_options: []
95
+
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ hash: 3
113
+ segments:
114
+ - 0
115
+ version: "0"
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.3.7
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: EPP (Extensible Provisioning Protocol) Client
123
+ test_files:
124
+ - test/helper.rb
125
+ - test/test_epp-client.rb