Use HTTPClient instead of Yadis HTTPFetcher in Linkback plugin

This commit is contained in:
Mikael Nordfeldth 2016-03-24 03:01:18 +01:00
parent 9fa18fa366
commit 4d382a59d0

View File

@ -31,7 +31,6 @@ if (!defined('STATUSNET')) {
exit(1); exit(1);
} }
require_once('Auth/Yadis/Yadis.php');
require_once(__DIR__ . '/lib/util.php'); require_once(__DIR__ . '/lib/util.php');
define('LINKBACKPLUGIN_VERSION', '0.1'); define('LINKBACKPLUGIN_VERSION', '0.1');
@ -114,34 +113,36 @@ class LinkbackPlugin extends Plugin
} }
// XXX: Do a HEAD first to save some time/bandwidth // XXX: Do a HEAD first to save some time/bandwidth
try {
$httpclient = new HTTPClient();
$response = $httpclient->get($url, ["User-Agent: {$this->userAgent()}",
"Accept: application/html+xml,text/html"]);
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); if (!in_array($response->getStatus(), array(200, 206))) {
throw new Exception('Invalid response code for GET request');
$result = $fetcher->get($url, }
array('User-Agent: ' . $this->userAgent(), } catch (Exception $e) {
'Accept: application/html+xml,text/html')); // something didn't work out in our GET request
if (!in_array($result->status, array('200', '206'))) {
return $orig; return $orig;
} }
// XXX: Should handle relative-URI resolution in these detections // XXX: Should handle relative-URI resolution in these detections
$wm = $this->getWebmention($result); $wm = $this->getWebmention($response);
if(!empty($wm)) { if(!empty($wm)) {
// It is the webmention receiver's job to resolve source // It is the webmention receiver's job to resolve source
// Ref: https://github.com/converspace/webmention/issues/43 // Ref: https://github.com/converspace/webmention/issues/43
$this->webmention($url, $wm); $this->webmention($url, $wm);
} else { } else {
$pb = $this->getPingback($result); $pb = $this->getPingback($response);
if (!empty($pb)) { if (!empty($pb)) {
// Pingback still looks for exact URL in our source, so we // Pingback still looks for exact URL in our source, so we
// must send what we have // must send what we have
$this->pingback($url, $pb); $this->pingback($url, $pb);
} else { } else {
$tb = $this->getTrackback($result); $tb = $this->getTrackback($response);
if (!empty($tb)) { if (!empty($tb)) {
$this->trackback($result->final_url, $tb); $this->trackback($response->getEffectiveUrl(), $tb);
} }
} }
} }
@ -151,22 +152,23 @@ class LinkbackPlugin extends Plugin
// Based on https://github.com/indieweb/mention-client-php // Based on https://github.com/indieweb/mention-client-php
// which is licensed Apache 2.0 // which is licensed Apache 2.0
function getWebmention($result) { function getWebmention(HTTP_Request2_Response $response) {
if (isset($result->headers['Link'])) { $link = $response->getHeader('Link');
// XXX: the fetcher only gives back one of each header, so this may fail on multiple Link headers if (!is_null($link)) {
if(preg_match('~<((?:https?://)?[^>]+)>; rel="webmention"~', $result->headers['Link'], $match)) { // XXX: the fetcher gives back a comma-separated string of all Link headers, I hope the parsing works reliably
if (preg_match('~<((?:https?://)?[^>]+)>; rel="webmention"~', $link, $match)) {
return $match[1]; return $match[1];
} elseif(preg_match('~<((?:https?://)?[^>]+)>; rel="http://webmention.org/?"~', $result->headers['Link'], $match)) { } elseif (preg_match('~<((?:https?://)?[^>]+)>; rel="http://webmention.org/?"~', $link, $match)) {
return $match[1]; return $match[1];
} }
} }
// FIXME: Do proper DOM traversal // FIXME: Do proper DOM traversal
if(preg_match('/<(?:link|a)[ ]+href="([^"]+)"[ ]+rel="[^" ]* ?webmention ?[^" ]*"[ ]*\/?>/i', $result->body, $match) if(preg_match('/<(?:link|a)[ ]+href="([^"]+)"[ ]+rel="[^" ]* ?webmention ?[^" ]*"[ ]*\/?>/i', $response->getBody(), $match)
|| preg_match('/<(?:link|a)[ ]+rel="[^" ]* ?webmention ?[^" ]*"[ ]+href="([^"]+)"[ ]*\/?>/i', $result->body, $match)) { || preg_match('/<(?:link|a)[ ]+rel="[^" ]* ?webmention ?[^" ]*"[ ]+href="([^"]+)"[ ]*\/?>/i', $response->getBody(), $match)) {
return $match[1]; return $match[1];
} elseif(preg_match('/<(?:link|a)[ ]+href="([^"]+)"[ ]+rel="http:\/\/webmention\.org\/?"[ ]*\/?>/i', $result->body, $match) } elseif (preg_match('/<(?:link|a)[ ]+href="([^"]+)"[ ]+rel="http:\/\/webmention\.org\/?"[ ]*\/?>/i', $response->getBody(), $match)
|| preg_match('/<(?:link|a)[ ]+rel="http:\/\/webmention\.org\/?"[ ]+href="([^"]+)"[ ]*\/?>/i', $result->body, $match)) { || preg_match('/<(?:link|a)[ ]+rel="http:\/\/webmention\.org\/?"[ ]+href="([^"]+)"[ ]*\/?>/i', $response->getBody(), $match)) {
return $match[1]; return $match[1];
} }
} }
@ -198,11 +200,11 @@ class LinkbackPlugin extends Plugin
} }
} }
function getPingback($result) { function getPingback(HTTP_Request2_Response $response) {
if (array_key_exists('X-Pingback', $result->headers)) { if ($response->getHeader('X-Pingback')) {
return $result->headers['X-Pingback']; return $response->getHeader('X-Pingback');
} else if(preg_match('/<(?:link|a)[ ]+href="([^"]+)"[ ]+rel="[^" ]* ?pingback ?[^" ]*"[ ]*\/?>/i', $result->body, $match) } elseif (preg_match('/<(?:link|a)[ ]+href="([^"]+)"[ ]+rel="[^" ]* ?pingback ?[^" ]*"[ ]*\/?>/i', $response->getBody(), $match)
|| preg_match('/<(?:link|a)[ ]+rel="[^" ]* ?pingback ?[^" ]*"[ ]+href="([^"]+)"[ ]*\/?>/i', $result->body, $match)) { || preg_match('/<(?:link|a)[ ]+rel="[^" ]* ?pingback ?[^" ]*"[ ]+href="([^"]+)"[ ]*\/?>/i', $response->getBody(), $match)) {
return $match[1]; return $match[1];
} }
} }
@ -242,10 +244,10 @@ class LinkbackPlugin extends Plugin
// Largely cadged from trackback_cls.php by // Largely cadged from trackback_cls.php by
// Ran Aroussi <ran@blogish.org>, GPL2 or any later version // Ran Aroussi <ran@blogish.org>, GPL2 or any later version
// http://phptrackback.sourceforge.net/ // http://phptrackback.sourceforge.net/
function getTrackback($result) function getTrackback(HTTP_Request2_Response $response)
{ {
$text = $result->body; $text = $response->getBody();
$url = $result->final_url; $url = $response->getEffectiveUrl();
if (preg_match_all('/(<rdf:RDF.*?<\/rdf:RDF>)/sm', $text, $match, PREG_SET_ORDER)) { if (preg_match_all('/(<rdf:RDF.*?<\/rdf:RDF>)/sm', $text, $match, PREG_SET_ORDER)) {
for ($i = 0; $i < count($match); $i++) { for ($i = 0; $i < count($match); $i++) {
@ -296,26 +298,22 @@ class LinkbackPlugin extends Plugin
// TRANS: Trackback title. // TRANS: Trackback title.
// TRANS: %1$s is a profile nickname, %2$s is a timestamp. // TRANS: %1$s is a profile nickname, %2$s is a timestamp.
$args = array('title' => sprintf(_m('%1$s\'s status on %2$s'), $args = array('title' => sprintf(_m('%1$s\'s status on %2$s'),
$profile->nickname, $profile->getNickname(),
common_exact_date($this->notice->created)), common_exact_date($this->notice->getCreated())),
'excerpt' => $this->notice->content, 'excerpt' => $this->notice->getContent(),
'url' => $this->notice->getUrl(), 'url' => $this->notice->getUrl(),
'blog_name' => $profile->nickname); 'blog_name' => $profile->getNickname());
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); try {
$httpclient = new HTTPClient(null, HTTPClient::METHOD_POST);
$result = $fetcher->post($endpoint, $response = $httpclient->post($endpoint, ["User-Agent: {$this->userAgent()}"], $args);
http_build_query($args), if ($response->getStatus() === 200) {
array('User-Agent: ' . $this->userAgent())); common_log(LOG_INFO, "Trackback success for '$url' ($endpoint): "._ve($response->getBody()));
if ($result->status != '200') {
common_log(LOG_WARNING,
"Trackback error for '$url' ($endpoint): ".
"$result->body");
} else { } else {
common_log(LOG_INFO, common_log(LOG_WARNING, "Trackback error for '$url' ($endpoint): "._ve($response->getBody()));
"Trackback success for '$url' ($endpoint): ". }
"'$result->body'"); } catch (Exception $e) {
common_log(LOG_INFO, "Trackback error for '$url' ($endpoint): "._ve($e->getMessage()));
} }
} }