Class: KonoEppClient::Server

Inherits:
Object
  • Object
show all
Includes:
REXML, RequiresParameters
Defined in:
lib/epp/server.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from RequiresParameters

#requires!

Constructor Details

#initialize(attributes = {}) ⇒ Server

Required Attrbiutes

  • :server - The EPP server to connect to

  • :tag - The tag or username used with <login> requests.

  • :password - The password used with <login> requests.

Optional Attributes

  • :port - The EPP standard port is 700. However, you can choose a different port to use.

  • :clTRID - The client transaction identifier is an element that EPP specifies MAY be used to uniquely identify the command to the server. You are responsible for maintaining your own transaction identifier space to ensure uniqueness. Defaults to “ABC-12345”

  • :old_server - Set to true to read and write frames in a way that is compatible with older EPP servers. Default is false.

  • :lang - Set custom language attribute. Default is ‘en’.

  • :services - Use custom EPP services in the <login> frame. The defaults use the EPP standard domain, contact and host 1.0 services.

  • :extensions - URLs to custom extensions to standard EPP. Use these to extend the standard EPP (e.g., Nominet uses extensions). Defaults to none.

  • :version - Set the EPP version. Defaults to “1.0”.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/epp/server.rb', line 25

def initialize(attributes = {})
  requires!(attributes, :tag, :password, :server)

  @tag        = attributes[:tag]
  @password   = attributes[:password]
  @server     = attributes[:server]
  @port       = attributes[:port]       || 700
  @old_server = attributes[:old_server] || false
  @lang       = attributes[:lang]       || "en"
  @services   = attributes[:services]   || ["urn:ietf:params:xml:ns:domain-1.0", "urn:ietf:params:xml:ns:contact-1.0", "urn:ietf:params:xml:ns:host-1.0"]
  @extensions = attributes[:extensions] || []
  @version    = attributes[:version]    || "1.0"
  @transport  = attributes[:transport]  || :tcp
  @timeout    = attributes[:timeout]    || 30

  @logged_in  = false
end

Instance Attribute Details

#creditObject

Returns the value of attribute credit.



8
9
10
# File 'lib/epp/server.rb', line 8

def credit
  @credit
end

#extensionsObject

Returns the value of attribute extensions.



8
9
10
# File 'lib/epp/server.rb', line 8

def extensions
  @extensions
end

#langObject

Returns the value of attribute lang.



8
9
10
# File 'lib/epp/server.rb', line 8

def lang
  @lang
end

#old_serverObject

Returns the value of attribute old_server.



8
9
10
# File 'lib/epp/server.rb', line 8

def old_server
  @old_server
end

#passwordObject

Returns the value of attribute password.



8
9
10
# File 'lib/epp/server.rb', line 8

def password
  @password
end

#portObject

Returns the value of attribute port.



8
9
10
# File 'lib/epp/server.rb', line 8

def port
  @port
end

#serverObject

Returns the value of attribute server.



8
9
10
# File 'lib/epp/server.rb', line 8

def server
  @server
end

#servicesObject

Returns the value of attribute services.



8
9
10
# File 'lib/epp/server.rb', line 8

def services
  @services
end

#tagObject

Returns the value of attribute tag.



8
9
10
# File 'lib/epp/server.rb', line 8

def tag
  @tag
end

#timeoutObject

Returns the value of attribute timeout.



8
9
10
# File 'lib/epp/server.rb', line 8

def timeout
  @timeout
end

#versionObject

Returns the value of attribute version.



8
9
10
# File 'lib/epp/server.rb', line 8

def version
  @version
end

Instance Method Details

#change_password(new_password) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/epp/server.rb', line 88

def change_password( new_password )
   = KonoEppLogin.new( tag, password )

  # FIXME: Order matters
  .new_password = new_password

  .version = version
  .lang = lang

  .services = services
  .extensions = extensions

  send_command(  )
end

#close_connectionObject

Closes the connection to the EPP server.



50
51
52
# File 'lib/epp/server.rb', line 50

def close_connection
  @connection.close
end

#connect_and_helloObject



43
44
45
46
47
# File 'lib/epp/server.rb', line 43

def connect_and_hello
  open_connection

  hello
end

#create_contact(options) ⇒ Object



126
127
128
129
# File 'lib/epp/server.rb', line 126

def create_contact( options )
  contact = KonoEppCreateContact.new options
  send_command( contact )
end

#create_domain(options) ⇒ Object



141
142
143
144
# File 'lib/epp/server.rb', line 141

def create_domain( options )
  domain = KonoEppCreateDomain.new options
  send_command( domain )
end

#delete_contact(id) ⇒ Object



131
132
133
134
# File 'lib/epp/server.rb', line 131

def delete_contact( id )
  contact = KonoEppDeleteContact.new id
  send_command( contact )
end

#delete_domain(name) ⇒ Object



151
152
153
154
# File 'lib/epp/server.rb', line 151

def delete_domain( name )
  domain = KonoEppDeleteDomain.new name
  send_command( domain )
end

#helloObject

FIXME: Remove command wrappers?



114
115
116
# File 'lib/epp/server.rb', line 114

def hello
  response = Hpricot.XML( send_request( KonoEppHello.new.to_s ) )
end

#info_contact(id) ⇒ Object



156
157
158
159
# File 'lib/epp/server.rb', line 156

def info_contact( id )
  contact = KonoEppInfoContact.new id
  send_command( contact )
end

#info_domain(name) ⇒ Object



161
162
163
164
# File 'lib/epp/server.rb', line 161

def info_domain( name )
  info = KonoEppInfoDomain.new name
  send_command( info )
end

#logged_in?Boolean

Returns:

  • (Boolean)


103
104
105
106
107
108
109
110
111
# File 'lib/epp/server.rb', line 103

def logged_in?
  begin
    poll
  rescue
    return false
  end

  return true
end

#loginObject

Sends a standard login request to the EPP server.



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/epp/server.rb', line 75

def 
   = KonoEppLogin.new( tag, password )

  # FIXME: Order matters
  .version = version
  .lang = lang

  .services = services
  .extensions = extensions

  send_command(  )
end

#logoutObject

Sends a standard logout request to the EPP server.



172
173
174
# File 'lib/epp/server.rb', line 172

def logout
  send_command( KonoEppLogout.new, 1500 )
end

#open_connectionObject

established, then this method will call read and return the EPP <greeting> which is sent by the server upon connection.



243
244
245
246
247
248
249
250
# File 'lib/epp/server.rb', line 243

def open_connection
  Timeout.timeout @timeout do
    @connection = case @transport
      when :tcp then KonoEppClient::Transport::TcpTransport.new( server, port )
      when :http then KonoEppClient::Transport::HttpTransport.new( server, port )
    end
  end
end

#poll(id = nil) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/epp/server.rb', line 118

def poll( id = nil )
  poll = KonoEppPoll.new( id ? :ack : :req )

  poll.ack_id = id if id

  send_command( poll )
end

#readObject

Receive an EPP response from the server. Since the connection is blocking, this method will wait until the connection becomes available for use. If the connection is broken, a SocketError will be raised. Otherwise, it will return a string containing the XML from the server.



257
258
259
260
261
# File 'lib/epp/server.rb', line 257

def read
  Timeout.timeout @timeout do
    @connection.read
  end
end

#request(xml) ⇒ Object

Sends an XML request to the EPP server, and receives an XML response. <login> and <logout> requests are also wrapped around the request, so we can close the socket immediately after the request is made.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/epp/server.rb', line 58

def request( xml )
  # open_connection

  # @logged_in = true if login

  begin
    @response = send_request( xml )
  ensure
    if @logged_in && !old_server
      @logged_in = false if logout
    end
  end

  return @response
end

#send_command(command, expected_result = 1000..1999) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/epp/server.rb', line 184

def send_command( command, expected_result = 1000..1999 )
  namespaces = { 'extepp' => 'http://www.nic.it/ITNIC-EPP/extepp-2.0',
                 'xmlns' => "urn:ietf:params:xml:ns:epp-1.0" }

  xml = Nokogiri.XML( send_request( command.to_s ) )

  # TODO: multiple <response> RFC 3730 §2.6
  result = xml.at_xpath( "/xmlns:epp/xmlns:response[1]/xmlns:result",
                         namespaces )
  raise KonoEppErrorResponse.new( :message => 'Malformed response' ) if result.nil?

  xmlns_code = result.at_xpath( "@code" )
  raise KonoEppErrorResponse.new( :message => 'Malformed response' ) if xmlns_code.nil?

  response_code = xmlns_code.value.to_i

  xmlns_msg = result.xpath( "xmlns:msg/text ()",
                            namespaces )
  raise KonoEppErrorResponse.new( :message => 'Malformed response' ) if xmlns_msg.empty?

  result_message = xmlns_msg.text.strip

  # TODO: value

  xmlns_ext_reason = result.xpath( "xmlns:extValue/xmlns:reason",
                                   namespaces)
  result_message += ": #{xmlns_ext_reason.text.strip}" unless xmlns_ext_reason.empty?

  xmlns_reason_code = result.xpath( "xmlns:extValue/xmlns:value/extepp:reasonCode",
                                    namespaces )
  reason_code = xmlns_reason_code.text.strip.to_i unless xmlns_reason_code.empty?

  credit_msg = xml.xpath( "//extepp:credit/text ()",
                          namespaces )
  @credit = credit_msg.text.to_f unless credit_msg.empty?

  if expected_result === response_code
    return xml
  end

  args = { :xml           => xml,
           :response_code => response_code,
           :reason_code   => reason_code,
           :message       => result_message }

  case [ response_code, reason_code ]
    when [2200, 6004]
      raise KonoEppAuthenticationPasswordExpired.new( args )
    when [2002, 4015]
      raise KonoEppLoginNeeded.new( args )
    else
      raise KonoEppErrorResponse.new( args )
  end
end

#send_request(xml) ⇒ Object

Wrapper which sends XML to the server, and receives the response in return.



179
180
181
182
# File 'lib/epp/server.rb', line 179

def send_request( xml )
  write( xml )
  read
end

#transfer_domain(name, authinfo, op) ⇒ Object



166
167
168
169
# File 'lib/epp/server.rb', line 166

def transfer_domain( name, authinfo, op )
  transfer = KonoEppTransferDomain.new name, authinfo, op
  send_command( transfer )
end

#update_contact(options) ⇒ Object



136
137
138
139
# File 'lib/epp/server.rb', line 136

def update_contact( options )
  contact = KonoEppUpdateContact.new options
  send_command( contact )
end

#update_domain(options) ⇒ Object



146
147
148
149
# File 'lib/epp/server.rb', line 146

def update_domain( options )
  domain = KonoEppUpdateDomain.new options
  send_command( domain )
end

#write(xml) ⇒ Object

Send XML to the server. If the socket returns EOF, the connection has closed and a SocketError is raised.



265
266
267
268
269
# File 'lib/epp/server.rb', line 265

def write( xml )
  Timeout.timeout @timeout do
    @connection.write( xml )
  end
end