epp 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
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