I’m buildin an interface to work with the Nominet EPP service (http://www.nominet.org.uk/registrars/systems/nominetepp/) and I’m struggling on two seperate issues.
The first is that try as I might, I cannot get the code to communicate over the secure port of 700 on the testbed, it will only work on the non secure port despite me checking my firewall etc…
The second issue is actually reading responses from the testbed server. This is what I have so far using a simple login test:
<cfparam name="tag" default="my-nominet-tag">
<cfparam name="tagpw" default="my-password">
<cfparam name="testmode" default="true">
<cfswitch expression="#testmode#">
<cfcase value="true">
<cfset apiport="700">
<cfset apiurl="https://testbed-epp.nominet.org.uk">
</cfcase>
</cfswitch>
<cfxml variable="xmlcommand">
<cfoutput>
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<command>
<login>
<clID>#tag#</clID>
<pw>#tagpw#</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>http://www.nominet.org.uk/epp/xml/nom-domain-1.3</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-notifications-1.3</objURI>
</svcs>
</login>
<clTRID>ABC-12345</clTRID>
</command>
</epp>
</cfoutput>
</cfxml>
<!---
Connect to sockets through your ColdFusion application.
Mods by Raymond Camden
@param host Host to connect to. (Required)
@param port Port for connection. (Required)
@param message Message to be sent. (Required)
@return Returns a string.
@author George Georgiou (george1977@gmail.com)
@version 1, August 27, 2009
--->
<cffunction name="easySocket" access="private" returntype="any" hint="Uses Java Sockets to connect to a remote socket over TCP/IP" output="false">
<cfargument name="host" type="string" required="yes" default="localhost" hint="Host to connect to and send the message">
<cfargument name="port" type="numeric" required="Yes" default="8080" hint="Port to connect to and send the message">
<cfargument name="message" type="string" required="yes" default="" hint="The message to transmit">
<cfset var result = "">
<cfset var socket = createObject( "java", "java.net.Socket" )>
<cfset var streamOut = "">
<cfset var output = "">
<cfset var input = "">
<cftry>
<cfset socket.init(arguments.host,arguments.port)>
<cfcatch type="Object">
<cfset result = "Could not connected to host <strong>#arguments.host#</strong>, port <strong>#arguments.port#</strong>.">
<cfreturn result>
</cfcatch>
</cftry>
<cfif socket.isConnected()>
<cfset streamOut = socket.getOutputStream()>
<cfset output = createObject("java", "java.io.PrintWriter").init(streamOut)>
<cfset streamInput = socket.getInputStream()>
<cfset inputStreamReader= createObject( "java", "java.io.InputStreamReader").init(streamInput)>
<cfset input = createObject( "java", "java.io.BufferedReader").init(InputStreamReader)>
<cfset output.println(arguments.message)>
<cfset output.println()>
<cfset output.flush()>
<cfset result=input.readLine()>
<cfset result=REReplace(result, "#chr(10)#|#chr(13)#", "", "ALL")>
<cfset result = REReplace( result, "^[^<]*", "", "all" )>
<!---<cfset socket.close()>--->
<cfelse>
<cfset result = "Could not connected to host <strong>#arguments.host#</strong>, port <strong>#arguments.port#</strong>.">
</cfif>
<cfreturn result>
</cffunction>
<cfoutput>
<cfset response=easySocket(apiurl,apiport,xmlcommand)>
<cfset response=REReplace(response, "#chr(10)#|#chr(13)#", "", "ALL")>
<cfset response = REReplace( response, "^[^<]*", "", "all" )>
<cfdump var="#response#">
<cfset responseXML=RemoveChars(response,1,Find("<",response)-1)>
</cfoutput>
Now it should return an XML string string stating I’m logged in and I can then send the next command but I’m getting all sorts of funky characters in the return so the XML won’t parse.
Any ideas?
Well your first issue is you have white space in your XML. Move the CFOutput Tags outside of the cfxml tag and then do not indent the initial xml tag. Do it just like that and it might help a little.
<cfoutput>
<cfxml variable="xmlcommand"><?xml version="1.0" encoding="UTF-8"?>
As far as the port not working, I would actually send a contact form on Ray Camden’s website (www.coldfusionjedi.com). He built the CFC that you are using. He should 1. know that it doesn’t work with port 700 2. be the best person to figure out why it doesn’t work.
Thanks for the message, I’ve actually switched to using this custom tag:
And it’s connecting OK on port 700 but not returning any output from the EPP server. I’m still investigating but I’ve removed the whitespace now by both shifting the cfoutput tags and also applying Trim() to the xml.
The first is that try as I might, I cannot get the code to communicate over the secure port of 700 on the testbed, it will only work on the non secure port despite me checking my firewall etc…
Are you able to send a standard HTTP request, from ColdFusion, to the address you’re trying to call? If you write a short CFHTTP example, does that return anything?
Is your Webserver (IIS, Apache) setup to allow incoming / outgoing traffic through port 700? You’ll need that before anything will go out or come into ColdFusion.
Also make sure that the SSL certificates are recognised by ColdFusion as that can be a problem if you’re running version 6 (MX) or above. You need to import them into the keystore and truststore of JRun. Do a Google on it, plenty of example of how this can be done on there. ColdFusion will not make any calls to a domain it doesn’t recognise through those stores. You’ll be able to tell straight away though if that’s the problem when trying to CFHTTP.
OK using the rawsocket tag I have confirmed everything is working as it should be by doing a simple GET on www.google.co.uk. As expected, the tag grabbed the source code for Google so I know it’s working fine.
The server is open on port 700 and after speaking to Nominet they have confirmed that the login command is received and they say they are responding with the appropriate XML but nothing is being received here.
This is what the tag is sending:
POST / HTTP/1.1
Host: testbed-epp.nominet.org.uk:700
Content-type: application/x-www-form-urlencoded
Content-Length: 518
Accept: */*
<?xml version="1.0" encoding="UTF-8"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"><command><login><clID>**MY TAG**</clID><pw>** MY PASSWORD**</pw><options><version>1.0</version><lang>en</lang></options><svcs><objURI>http://www.nominet.org.uk/epp/xml/nom-domain-1.3</objURI><objURI>http://www.nominet.org.uk/epp/xml/nom-notifications-1.3</objURI></svcs></login><clTRID>newtest-123</clTRID></command></epp>
They are not being particularly helpful I must admit and I can’t believe that I’m the only one using ColdFusion on the EPP service 
It might be worth downloading an HTTP sniffers (or use the one that comes with JRun) to see what is coming in and going out with your HTTP requests.
Something like Wireshark would do the job.
They are not being particularly helpful I must admit and I can’t believe that I’m the only one using ColdFusion on the EPP service
We hit exactly the same problem last year trying to get ColdFusion sample code for a zip / postal code service we were using (QAS). Nothing at all so we had to build our own.
OK I’ve gone back to Rays original code as the rawsocket was simply not working.
I’ve got it talking to the testbed now on a non-ssl basis. I’ll figure out the ssl part later.
Now. My Input stream is of an undefined length. That is to say, I don’t know how long the xml string will be when returned from Nominet.
I can enclose this chunk:
<cfscript>
line = input.readLine();
</cfscript>
<cfset result=result & line & chr(13)>
within a loop of say 20 iterations and it works a treat returning the xml string and stopping after 20 lines but obvioulsy I need the whole xml string.
In response to the login command I would get:
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>54321-XYZ</svTRID>
</trID>
</response>
</epp>
I’ve tried this:
<cfif line NEQ "</epp>">
<cfbreak>
</cfif>
But it’s still being trapped in the loop.
How do I find out when I am at the end of my returned stream of xml data? I feel like I am so close yet so far! 
You should be parsing the string before you try and work with it
xmlParse(returnedString)
From there you can use ColdFusion’s XML functions to work through the nodes and lengths
Working with the xml is not the problem really, it’s working out when I am at the end of my returned stream.
For example.
If I loop over the stream 43 times (bear with me) I get this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nominet.org.uk/epp/xml/epp-1.0 epp-1.0.xsd">
<greeting>
<svID>Nominet EPP server testbed-epp.nominet.org.uk</svID>
<svDate>2009-11-03T18:13:47Z</svDate>
<svcMenu>
<version>1.0</version>
<lang>en</lang>
<objURI>http://www.nominet.org.uk/epp/xml/nom-domain-1.0</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-domain-1.1</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-domain-1.2</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-domain-1.3</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-domain-2.0</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-notifications-1.1</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-notifications-1.2</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-notifications-1.3</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-notifications-2.0</objURI>
<objURI>http://www.nominet.org.uk/epp/xml/nom-tag-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<svcExtension>
<extURI>http://www.nominet.org.uk/epp/xml/contact-nom-ext-1.0</extURI>
<extURI>http://www.nominet.org.uk/epp/xml/domain-nom-ext-1.0</extURI>
<extURI>http://www.nominet.org.uk/epp/xml/std-contact-id-1.0</extURI>
<extURI>http://www.nominet.org.uk/epp/xml/std-handshake-1.0</extURI>
<extURI>http://www.nominet.org.uk/epp/xml/std-notifications-1.0</extURI>
<extURI>http://www.nominet.org.uk/epp/xml/std-notifications-1.1</extURI>
<extURI>http://www.nominet.org.uk/epp/xml/std-release-1.0</extURI>
<extURI>http://www.nominet.org.uk/epp/xml/std-warning-1.1</extURI>
</svcExtension>
</svcMenu>
<dcp>
<access><all/></access>
<statement>
<purpose><admin/><prov/></purpose>
<recipient><ours/></recipient>
<retention><indefinite/></retention>
</statement>
</dcp>
</greeting
Note the missing > after the greeting node…
If I loop 44 times or more, the page hangs as I guess the end of the strem has been reached and CF doesn’t know how to proceed.
The problem is this line: line = input.readLine(); and I’ve got to try and figure out of the returned line is valid in which case loop again or not…
Is that the whole packet being returned there as it’s not closed at the end? If not can you put one in here and I’ll have look ;-). Bit confused as to where this missing > is from your example and the role of this input().readline.
Well I got the > back by removing one of my trim command. the readLine() function reads that line from the incoming stream from the socket.
Ahh ok seeing it all on my laptop. Serves me right for answering on my iPod :-).
I’m still a bit confused from your explanation as to what you’re trying to do here. Just to clarify, your original comment of:
That is to say, I don’t know how long the xml string will be when returned from Nominet.
Why do you need to know how long the string is? Yes it’s returned as a string but the structure of the returned packet is XML.
If I take your original example of:
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>54321-XYZ</svTRID>
</trID>
</response>
</epp>
I would parse the string in via xmlParse() first like so:
<cfset packet = '<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<trID>
<clTRID>ABC-12345</clTRID>
<svTRID>54321-XYZ</svTRID>
</trID>
</response>
</epp>' />
<cfset x = xmlParse(packet) />
<!--- Output for example --->
<cfdump var="#x#" />
That then gives me an XML document that I can start to work with. So if I want to know the number of nodes inside <response> I could get that from:
<cfset length = arrayLen(x.epp.response.xmlChildren) />
You could then loop over those child nodes and do what you need for each one.
Nominet will be returning a specific structure from their service. They have a reference to a XSD in your second example so you could look at that for a pattern, but the theory beyond that should be the same as above.
In terms of ColdFusion struggling I’m not sure what’s the problem there, I’d need to see your code, but this approach shouldn’t give it any problems.
Cheers,
James
I’ve got it talking to the testbed now on a non-ssl basis. I’ll figure out the ssl part later.
Did you try what I suggested at the start of this thread?
Just to finish off this thread, I finally got my code working but the only problem I have now is no hair! Communicating over an ssl socket is no fun at all so to save others the pain, I will be making the custom tag available for others here: www.cfnominet.com once it is complete 