Well okay. The problem was not, that s9y didn't POST the pingback (it did), but it posted with the wrong content type. Pingback needs text/xml.
So I patched the functions_trackbacks.inc.php to make pingbacks work:
Code: Select all
/**
* Check a HTTP response if it is a valid XML pingback response
*
* @access public
* @param string HTTP Response string
* @return mixed Boolean or error message
*/
function serendipity_pingback_is_success($resp) {
// This is very rudimentary, but the fault is printed later, so what..
if (preg_match('@<fault>@', $resp, $matches)) {
return false;
}
return true;
}
/**
* Perform a HTTP query for autodiscovering a pingback URL
*
* @access public
* @param string The HTML of the source URL
* @param string The source URL
* @param string The URL of our blog
* @return
*/
function serendipity_pingback_autodiscover($res, $loc, $url) {
global $serendipity;
if (!empty($_SERVER['X-PINGBACK'])) {
$pingback = $_SERVER['X-PINGBACK'];
} elseif (preg_match('@<link rel="pingback" href="([^"]+)" ?/?>@i', $res, $matches)) {
$pingback = $matches[1];
} else {
echo '<div>• ' . sprintf('PINGBACK: ' . TRACKBACK_FAILED, TRACKBACK_NOT_FOUND) . '</div>';
return false;
}
// xml-rpc pingback call
$query = "
<?xml version=\"1.0\"?>
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param>
<name>sourceURI</name>
<value><string>$url</string></value>
</param>
<param>
<name>targetURI</name>
<value><string>$loc</string></value>
</param>
</params>
</methodCall>";
echo '<div>• ' . sprintf('PINGBACK: ' . TRACKBACK_SENDING, htmlspecialchars($pingback)) . '</div>';
flush();
$response = _serendipity_send($pingback, $query,'text/html');
$success = serendipity_pingback_is_success($response);
if ($success == true) {
echo '<div>• ' . 'PINGBACK: ' . TRACKBACK_SENT .'</div>';
} else {
echo '<div>• ' . sprintf('PINGBACK: ' . TRACKBACK_FAILED, $response) . '</div>';
}
return $success;
}
/**
* Send a track/pingback ping
*
* @access public
* @param string The URL to send a trackback to
* @param string The XML data with the trackback contents
* @return string Reponse
*/
function _serendipity_send($loc, $data, $contenttype=null) {
global $serendipity;
$target = parse_url($loc);
if ($target['query'] != '') {
$target['query'] = '?' . str_replace('&', '&', $target['query']);
}
if (!is_numeric($target['port'])) {
$target['port'] = 80;
}
$uri = $target['scheme'] . '://' . $target['host'] . ':' . $target['port'] . $target['path'] . $target['query'];
require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
$options = array('allowRedirects' => true, 'maxRedirects' => 5, 'method' => 'POST');
serendipity_plugin_api::hook_event('backend_http_request', $options, 'trackback_send');
serendipity_request_start();
$req = &new HTTP_Request($uri, $options);
if (isset($contenttype)){
$req->addHeader('Content-Type',$contenttype);
}
$req->addRawPostData($data, true);
$res = $req->sendRequest();
if (PEAR::isError($res)) {
serendipity_request_end();
return false;
}
$fContent = $req->getResponseBody();
serendipity_request_end();
return $fContent;
}
You will easily see the differences in the code, using the cvs diff, so I posted the complete functions.
Only pingback
or trackback should be sent (actually s9y tries both), so first I try trackback, as it sends more infos, and if that fails, I try pingback.
Code: Select all
function serendipity_reference_autodiscover($loc, $url, $author, $title, $text) {
// .. code ..
serendipity_request_end();
if (strlen($fContent) != 0) {
$pingresult = serendipity_trackback_autodiscover($fContent, $parsed_loc, $url, $author, $title, $text, $loc);
if ($pingresult == false){
serendipity_pingback_autodiscover($fContent, $parsed_loc, $url);
}
flush();
} else {
echo '<div>• ' . TRACKBACK_NO_DATA . '</div>';
}
echo '<hr noshade="noshade" />';
}
There are two things, that should be changed:
1. As I don't want to change the languagefiles, I used the trackback language entries, and precede each entry with 'POSTBACK: ' inside the code. So 'PINGBACK: ' . TRACKBACK_ should be replaced with PINGBACK_ and the new language entries should be added.
2. serendipity_pingback_is_success is very simple, because I am not very firm to the php regular expressions (I used a lot of them in .NET and Java, but the PHP regEx seems to be somehow -hmm- other). I was not able to fetch something spreaded over more than one line. I know how the result XML looks like, so if someone introduces me in PHP regex's, I could make this more stable.
But now pingback works!
