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.
- data/VERSION +1 -1
- data/epp.gemspec +1 -1
- data/lib/epp/server.rb +80 -77
- data/test/test_epp.rb +17 -137
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.1
|
data/epp.gemspec
CHANGED
data/lib/epp/server.rb
CHANGED
@@ -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
|
-
|
151
|
-
socket.
|
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
|
-
|
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
|
-
|
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
|
data/test/test_epp.rb
CHANGED
@@ -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.
|
93
|
-
@ssl_sock.
|
94
|
-
@tcp_sock.
|
95
|
-
@ssl_sock.
|
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.
|
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).
|
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.
|
353
|
-
@tcp_sock.
|
354
|
-
@ssl_sock.
|
355
|
-
@tcp_sock.
|
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:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 1
|
10
|
+
version: 1.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Josh Delsman
|