When specification is not specification - omnipotent RPC blog ping specification puzzle

I started implementing the pinging service on a Java blog using the Apache RPC Client libraries. However, I am a little confused, and I cannot find the final specification of what the ping answer for the blog should look like to verify that it is successful.

I looked at this, which looks like a (official?) Specification for pingback.
http://www.hixie.ch/specs/pingback/pingback-1.0

However, this indicates that error codes will be returned, for example.

http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php

A number of RPC servers, such as a Google blog search, seem to return the "flerror" and "message" element in their XML response, which looks more akin to this:

http://xmlrpc.scripting.com/weblogsCom.html

What's going on here? I understand that pingback was a bit of a hack on the Internet and it has become the standard, but I am confused by the need to code or really trust the answer. Can I trust below? and will it work on all ping server servers?

public boolean ping( String urlToPing, String title, String url, String urlChanges, String urlRSS ) throws MalformedURLException, XmlRpcException { XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); config.setServerURL( new URL( urlToPing ) ); XmlRpcClient client = new XmlRpcClient(); client.setConfig( config ); Object[] params = new Object[] { title, url, urlChanges, urlRSS }; HashMap result = ( HashMap )client.execute( "weblogUpdates.extendedPing", params ); try { errors.put( url, Boolean.parseBoolean( result.get( "flerror" ).toString() ) ); } catch( Exception e ) { log.error( "RPC Problem Parsing response to Boolean trying: " + result.get( "flerror" ) ); } return Boolean.parseBoolean( result.get( "flerror").toString()) ; } 
+4
source share
1 answer

Can I trust below? and will it work on all ping server servers?

The short answer is no. Various server implementations will have errors or incorrectly interpret the specification, so you cannot write code that will work on all ping server servers. The best you can do is be liberal in what you accept and try to deal with non-standard / buggy servers as much as you can.

pingback link says

If the pingback request is successful, then the return value MUST be the only string containing as much information as the server finds useful. This line is supposed to be used for debugging purposes.

If the result is unsuccessful, the server MUST respond with an RPC error value. The fault code must be either one of the codes listed above, or a common zero error code if the server cannot determine the correct fault code.

Thus, a client expecting the server to conform to the specification will do something like

 try { client.execute( "weblogUpdates.extendedPing", params ); } catch(XmlRpcException e) { //check the code of the rpc exception as shown below, //log the error, or perhaps rethrow it? return false; } 

If the server complies with the pingback specification, it must return one of the following trouble codes,

 0 A generic fault code. Servers MAY use this error code instead of any of the others if they do not have a way of determining the correct fault code. 0×0010 (16) The source URI does not exist. 0×0011 (17) The source URI does not contain a link to the target URI, and so cannot be used as a source. 0×0020 (32) The specified target URI does not exist. This MUST only be used when the target definitely does not exist, rather than when the target may exist but is not recognised. See the next error. 0×0021 (33) The specified target URI cannot be used as a target. It either doesn't exist, or it is not a pingback-enabled resource. For example, on a blog, typically only permalinks are pingback-enabled, and trying to pingback the home page, or a set of posts, will fail with this error. 0×0030 (48) The pingback has already been registered. 0×0031 (49) Access denied. 0×0032 (50) 

As you already mentioned, several pingback servers return an error code, so you should check this also with code, for example

 try { Object rpcRVal = client.execute( "weblogUpdates.extendedPing", params ); if(rpcRVal instanceof Map) { Object flError = ((Map) rpcRVal ).get("flerror"); if(flError != null && flError instanceof Boolean) { return ((Boolean) flError).booleanValue()); } } return true; } catch(XmlRpcException e) ... 
+2
source

All Articles