epp 1.3.0 → 1.3.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.
Files changed (5) hide show
  1. data/VERSION +1 -1
  2. data/epp.gemspec +1 -1
  3. data/lib/epp/server.rb +80 -77
  4. data/test/test_epp.rb +17 -137
  5. metadata +3 -3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0
1
+ 1.3.1
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{epp}
8
- s.version = "1.3.0"
8
+ s.version = "1.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Josh Delsman"]
@@ -34,64 +34,6 @@ module Epp #:nodoc:
34
34
  @logged_in = false
35
35
  end
36
36
 
37
- # Sends a standard login request to the EPP server.
38
- def login
39
- xml = new_epp_request
40
-
41
- command = xml.root.add_element("command")
42
- login = command.add_element("login")
43
-
44
- login.add_element("clID").text = tag
45
- login.add_element("pw").text = password
46
-
47
- options = login.add_element("options")
48
- options.add_element("version").text = version
49
- options.add_element("lang").text = lang
50
-
51
- services = login.add_element("svcs")
52
- services.add_element("objURI").text = "urn:ietf:params:xml:ns:domain-1.0"
53
- services.add_element("objURI").text = "urn:ietf:params:xml:ns:contact-1.0"
54
- services.add_element("objURI").text = "urn:ietf:params:xml:ns:host-1.0"
55
-
56
- extensions_container = services.add_element("svcExtension") unless extensions.empty?
57
-
58
- for uri in extensions
59
- extensions_container.add_element("extURI").text = uri
60
- end
61
-
62
- command.add_element("clTRID").text = "ABC-12345"
63
-
64
- response = Hpricot.XML(send_request(xml.to_s))
65
-
66
- result_message = (response/"epp"/"response"/"result"/"msg").text.strip
67
- result_code = (response/"epp"/"response"/"result").attr("code").to_i
68
-
69
- if result_code == 1000
70
- return true
71
- else
72
- raise EppErrorResponse.new(:xml => response, :code => result_code, :message => result_message)
73
- end
74
- end
75
-
76
- # Sends a standard logout request to the EPP server.
77
- def logout
78
- xml = new_epp_request
79
-
80
- command = xml.root.add_element("command")
81
- login = command.add_element("logout")
82
-
83
- response = Hpricot.XML(send_request(xml.to_s))
84
-
85
- result_message = (response/"epp"/"response"/"result"/"msg").text.strip
86
- result_code = (response/"epp"/"response"/"result").attr("code").to_i
87
-
88
- if result_code == 1500
89
- return true
90
- else
91
- raise EppErrorResponse.new(:xml => response, :code => result_code, :message => result_message)
92
- end
93
- end
94
-
95
37
  def new_epp_request
96
38
  xml = Document.new
97
39
  xml << XMLDecl.new("1.0", "UTF-8", "no")
@@ -105,14 +47,6 @@ module Epp #:nodoc:
105
47
  return xml
106
48
  end
107
49
 
108
- def connection
109
- @connection ||= TCPSocket.new(server, port)
110
- end
111
-
112
- def socket
113
- @socket ||= OpenSSL::SSL::SSLSocket.new(connection) if connection
114
- end
115
-
116
50
  # Sends an XML request to the EPP server, and receives an XML response.
117
51
  # <tt><login></tt> and <tt><logout></tt> requests are also wrapped
118
52
  # around the request, so we can close the socket immediately after
@@ -134,7 +68,7 @@ module Epp #:nodoc:
134
68
 
135
69
  return @response
136
70
  end
137
-
71
+
138
72
  # Wrapper which sends an XML frame to the server, and receives
139
73
  # the response frame in return.
140
74
  def send_request(xml)
@@ -147,18 +81,22 @@ module Epp #:nodoc:
147
81
  # the EPP <tt><greeting></tt> frame which is sent by the
148
82
  # server upon connection.
149
83
  def open_connection
150
- socket.sync_close
151
- socket.connect
84
+ @connection = TCPSocket.new(server, port)
85
+ @socket = OpenSSL::SSL::SSLSocket.new(@connection) if @connection
86
+
87
+ @socket.sync_close = true
88
+ @socket.connect
152
89
 
153
90
  get_frame
154
91
  end
155
92
 
156
93
  # Closes the connection to the EPP server.
157
94
  def close_connection
158
- socket.close
159
- connection.close
160
-
161
- connection.closed? and socket.closed?
95
+ @socket.close if @socket and not @socket.closed?
96
+ @connection.close if @connection and not @connection.closed?
97
+ @socket = @connection = nil
98
+
99
+ return true
162
100
  end
163
101
 
164
102
  # Receive an EPP frame from the server. Since the connection is blocking,
@@ -166,23 +104,24 @@ module Epp #:nodoc:
166
104
  # the connection is broken, a SocketError will be raised. Otherwise,
167
105
  # it will return a string containing the XML from the server.
168
106
  def get_frame
169
- header = socket.read(4)
107
+ raise SocketError.new("Connection closed by remote server") if !@socket or @socket.eof?
108
+
109
+ header = @socket.read(4)
170
110
 
171
- raise SocketError.new("Connection closed by remote server") if header.nil? and socket.eof?
172
111
  raise SocketError.new("Error reading frame from remote server") if header.nil?
173
112
 
174
113
  length = header_size(header)
175
114
 
176
115
  raise SocketError.new("Got bad frame header length of #{length} bytes from the server") if length < 5
177
116
 
178
- response = socket.read(length - 4)
117
+ response = @socket.read(length - 4)
179
118
  end
180
119
 
181
120
  # Send an XML frame to the server. Should return the total byte
182
121
  # size of the frame sent to the server. If the socket returns EOF,
183
122
  # the connection has closed and a SocketError is raised.
184
123
  def send_frame(xml)
185
- socket.write(packed(xml) + xml)
124
+ @socket.write(packed(xml) + xml)
186
125
  end
187
126
 
188
127
  # Pack the XML as a header for the EPP server.
@@ -195,5 +134,69 @@ module Epp #:nodoc:
195
134
  unpacked_header = header.unpack("N")
196
135
  unpacked_header[0]
197
136
  end
137
+
138
+ private
139
+
140
+ # Sends a standard login request to the EPP server.
141
+ def login
142
+ raise SocketError, "Socket must be opened before logging in" if !@socket or @socket.closed?
143
+
144
+ xml = new_epp_request
145
+
146
+ command = xml.root.add_element("command")
147
+ login = command.add_element("login")
148
+
149
+ login.add_element("clID").text = tag
150
+ login.add_element("pw").text = password
151
+
152
+ options = login.add_element("options")
153
+ options.add_element("version").text = version
154
+ options.add_element("lang").text = lang
155
+
156
+ services = login.add_element("svcs")
157
+ services.add_element("objURI").text = "urn:ietf:params:xml:ns:domain-1.0"
158
+ services.add_element("objURI").text = "urn:ietf:params:xml:ns:contact-1.0"
159
+ services.add_element("objURI").text = "urn:ietf:params:xml:ns:host-1.0"
160
+
161
+ extensions_container = services.add_element("svcExtension") unless extensions.empty?
162
+
163
+ for uri in extensions
164
+ extensions_container.add_element("extURI").text = uri
165
+ end
166
+
167
+ command.add_element("clTRID").text = "ABC-12345"
168
+
169
+ response = Hpricot.XML(send_request(xml.to_s))
170
+
171
+ result_message = (response/"epp"/"response"/"result"/"msg").text.strip
172
+ result_code = (response/"epp"/"response"/"result").attr("code").to_i
173
+
174
+ if result_code == 1000
175
+ return true
176
+ else
177
+ raise EppErrorResponse.new(:xml => response, :code => result_code, :message => result_message)
178
+ end
179
+ end
180
+
181
+ # Sends a standard logout request to the EPP server.
182
+ def logout
183
+ raise SocketError, "Socket must be opened before logging out" if !@socket or @socket.closed?
184
+
185
+ xml = new_epp_request
186
+
187
+ command = xml.root.add_element("command")
188
+ login = command.add_element("logout")
189
+
190
+ response = Hpricot.XML(send_request(xml.to_s))
191
+
192
+ result_message = (response/"epp"/"response"/"result"/"msg").text.strip
193
+ result_code = (response/"epp"/"response"/"result").attr("code").to_i
194
+
195
+ if result_code == 1500
196
+ return true
197
+ else
198
+ raise EppErrorResponse.new(:xml => response, :code => result_code, :message => result_message)
199
+ end
200
+ end
198
201
  end
199
202
  end
@@ -65,19 +65,6 @@ class EppTest < Test::Unit::TestCase
65
65
  assert_equal xml, @epp.new_epp_request.to_s
66
66
  end
67
67
 
68
- should "have a TCP socket" do
69
- TCPSocket.expects(:new).returns(@tcp_sock)
70
-
71
- assert @epp.connection
72
- end
73
-
74
- should "have a SSL socket" do
75
- TCPSocket.expects(:new).returns(@tcp_sock)
76
- OpenSSL::SSL::SSLSocket.expects(:new).returns(@ssl_sock)
77
-
78
- assert @epp.socket
79
- end
80
-
81
68
  should "open connection and receive a greeting" do
82
69
  prepare_socket!
83
70
 
@@ -89,39 +76,14 @@ class EppTest < Test::Unit::TestCase
89
76
 
90
77
  @epp.open_connection
91
78
 
92
- @tcp_sock.expects(:close).returns(nil)
93
- @ssl_sock.expects(:close).returns(nil)
94
- @tcp_sock.expects(:closed?).returns(true)
95
- @ssl_sock.expects(:closed?).returns(true)
79
+ @tcp_sock.stubs(:close).returns(nil)
80
+ @ssl_sock.stubs(:close).returns(nil)
81
+ @tcp_sock.stubs(:closed?).returns(true)
82
+ @ssl_sock.stubs(:closed?).returns(true)
96
83
 
97
84
  assert @epp.close_connection
98
85
  end
99
86
 
100
- should "return false if TCP socket not closed" do
101
- prepare_socket!
102
-
103
- @epp.open_connection
104
-
105
- @tcp_sock.expects(:close).returns(nil)
106
- @ssl_sock.expects(:close).returns(nil)
107
- @tcp_sock.expects(:closed?).returns(false)
108
-
109
- assert !@epp.close_connection
110
- end
111
-
112
- should "return false if SSL socket not closed" do
113
- prepare_socket!
114
-
115
- @epp.open_connection
116
-
117
- @tcp_sock.expects(:close).returns(nil)
118
- @ssl_sock.expects(:close).returns(nil)
119
- @tcp_sock.expects(:closed?).returns(true)
120
- @ssl_sock.expects(:closed?).returns(false)
121
-
122
- assert !@epp.close_connection
123
- end
124
-
125
87
  should "get frame from new EPP servers with a header of four bytes" do
126
88
  prepare_socket!
127
89
 
@@ -142,9 +104,6 @@ class EppTest < Test::Unit::TestCase
142
104
  @epp.open_connection
143
105
  @epp.close_connection
144
106
 
145
- @ssl_sock.expects(:read).with(4).returns(nil)
146
- @ssl_sock.expects(:eof?).returns(true)
147
-
148
107
  assert_raises SocketError do
149
108
  @epp.get_frame
150
109
  end
@@ -156,7 +115,7 @@ class EppTest < Test::Unit::TestCase
156
115
  @epp.open_connection
157
116
 
158
117
  @ssl_sock.expects(:read).with(4).returns(nil)
159
- @ssl_sock.expects(:eof?).returns(false)
118
+ @ssl_sock.stubs(:eof?).returns(false)
160
119
 
161
120
  assert_raises SocketError do
162
121
  @epp.get_frame
@@ -200,95 +159,10 @@ class EppTest < Test::Unit::TestCase
200
159
  assert receive, @epp.send_request(send)
201
160
  end
202
161
 
203
- should "login to the server" do
204
- prepare_socket!
205
-
206
- @epp.open_connection
207
-
208
- send = xml_file("login_request.xml")
209
- receive = xml_file("login_response.xml")
210
-
211
- @ssl_sock.expects(:write).with(@epp.packed(send) + send)
212
- @ssl_sock.expects(:read).with(4).returns("\000\000\0019")
213
- @ssl_sock.expects(:read).with(309).returns(receive)
214
-
215
- assert @epp.login
216
- end
217
-
218
- should "login to the server with extensions" do
219
- prepare_socket!
220
-
221
- epp = Epp::Server.new(
222
- :server => "test-epp.nominet.org.uk",
223
- :tag => "TEST",
224
- :password => "test",
225
- :extensions => ["urn:ietf:params:xml:ns:rgp-1.0"]
226
- )
227
-
228
- epp.open_connection
229
-
230
- send = xml_file("login_with_extensions_request.xml")
231
- receive = xml_file("login_response.xml")
232
-
233
- @ssl_sock.expects(:write).with(epp.packed(send) + send)
234
- @ssl_sock.expects(:read).with(4).returns("\000\000\0019")
235
- @ssl_sock.expects(:read).with(309).returns(receive)
236
-
237
- assert epp.login
238
- end
239
-
240
- should "raise exception if login returns anything other than 1500 response" do
241
- prepare_socket!
242
-
243
- @epp.open_connection
244
-
245
- send = xml_file("login_request.xml")
246
- receive = xml_file("error.xml")
247
-
248
- @ssl_sock.expects(:write).with(@epp.packed(send) + send)
249
- @ssl_sock.expects(:read).with(4).returns("\000\000\001\231")
250
- @ssl_sock.expects(:read).with(405).returns(receive)
251
-
252
- assert_raises EppErrorResponse do
253
- @epp.login
254
- end
255
- end
256
-
257
- should "log out of the server" do
258
- prepare_socket!
259
-
260
- @epp.open_connection
261
-
262
- send = xml_file("logout_request.xml")
263
- receive = xml_file("logout_response.xml")
264
-
265
- @ssl_sock.expects(:write).with(@epp.packed(send) + send)
266
- @ssl_sock.expects(:read).with(4).returns("\000\000\001I")
267
- @ssl_sock.expects(:read).with(325).returns(receive)
268
-
269
- assert @epp.logout
270
- end
271
-
272
- should "raise exception if logout returns anything other than 1500 response" do
273
- prepare_socket!
274
-
275
- @epp.open_connection
276
-
277
- send = xml_file("logout_request.xml")
278
- receive = xml_file("error.xml")
279
-
280
- @ssl_sock.expects(:write).with(@epp.packed(send) + send)
281
- @ssl_sock.expects(:read).with(4).returns("\000\000\001\231")
282
- @ssl_sock.expects(:read).with(405).returns(receive)
283
-
284
- assert_raises EppErrorResponse do
285
- @epp.logout
286
- end
287
- end
288
-
289
162
  should "wrap a request around a logging in and logging out request" do
290
163
  prepare_socket!
291
164
  simulate_close!
165
+ check_socket!
292
166
 
293
167
  test_request = xml_file("test_request.xml")
294
168
  test_response = xml_file("test_response.xml")
@@ -342,17 +216,23 @@ class EppTest < Test::Unit::TestCase
342
216
  TCPSocket.expects(:new).returns(@tcp_sock)
343
217
  OpenSSL::SSL::SSLSocket.expects(:new).returns(@ssl_sock)
344
218
 
345
- @ssl_sock.expects(:sync_close).returns(false)
219
+ @ssl_sock.expects(:sync_close=).with(true)
346
220
  @ssl_sock.expects(:connect).returns(@ssl_sock)
347
221
  @ssl_sock.expects(:read).with(4).returns("\000\000\003\r")
348
222
  @ssl_sock.expects(:read).with(777).returns(@response)
223
+ @ssl_sock.stubs(:eof?)
224
+
225
+ end
226
+
227
+ def check_socket!
228
+ @ssl_sock.stubs(:closed?)
349
229
  end
350
230
 
351
231
  def simulate_close!
352
- @ssl_sock.expects(:close).returns(nil)
353
- @tcp_sock.expects(:close).returns(nil)
354
- @ssl_sock.expects(:closed?).returns(true)
355
- @tcp_sock.expects(:closed?).returns(true)
232
+ @ssl_sock.stubs(:close).returns(nil)
233
+ @tcp_sock.stubs(:close).returns(nil)
234
+ @ssl_sock.stubs(:closed?).returns(true)
235
+ @tcp_sock.stubs(:closed?).returns(true)
356
236
  end
357
237
 
358
238
  def xml_file(name)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 0
10
- version: 1.3.0
9
+ - 1
10
+ version: 1.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Josh Delsman