added pingback capabilities

git-svn-id: http://yolanda.mister-muffin.de/svn@314 7eef14d0-6ed0-489d-bf55-20463b2d70db
This commit is contained in:
josch 2008-04-22 20:08:02 +00:00
parent 0a27a8c730
commit bc77df2335
7 changed files with 227 additions and 8 deletions

View file

@ -15,8 +15,8 @@ NameVirtualHost *
AllowEncodedSlashes On AllowEncodedSlashes On
RewriteEngine On RewriteEngine On
RewriteRule ^/video/(.*)/([0-9]*)/(.*)$ /video.pl?title=$1&id=$2&$3 RewriteRule ^/video/(.*)/([0-9]+)/(.*)$ /video.pl?title=$1&id=$2&$3
RewriteRule ^/embedded/(.*)/([0-9]*)/(.*)$ /video.pl?title=$1&id=$2&embed=true&$3 RewriteRule ^/embedded/(.*)/([0-9]+)/(.*)$ /video.pl?title=$1&id=$2&embed=true&$3
RewriteRule ^/download/([0-9]+)/(.*)$ /download.pl?id=$1&$2 RewriteRule ^/download/([0-9]+)/(.*)$ /download.pl?id=$1&$2
ErrorLog /var/log/apache2/error.log ErrorLog /var/log/apache2/error.log

View file

@ -235,9 +235,6 @@ sub urlencode
sub output_page sub output_page
{ {
use XML::LibXSLT;
use XML::LibXML;
my $parser = XML::LibXML->new(); my $parser = XML::LibXML->new();
my $xslt = XML::LibXSLT->new(); my $xslt = XML::LibXSLT->new();
@ -303,6 +300,7 @@ sub output_page
return $session->header( return $session->header(
-type=>$stylesheet->media_type, -type=>$stylesheet->media_type,
-charset=>$stylesheet->output_encoding, -charset=>$stylesheet->output_encoding,
"x-pingback"=>$config->{"url_root"}."/pingback.pl"
), ),
$output->toString; $output->toString;
#$stylesheet->output_as_bytes($output); <= for future use with XML::LibXSLT (>= 1.62) #$stylesheet->output_as_bytes($output); <= for future use with XML::LibXSLT (>= 1.62)

View file

@ -7,8 +7,12 @@ use XML::Simple qw(:strict);
use Digest::SHA qw(sha256_hex); use Digest::SHA qw(sha256_hex);
use LWPx::ParanoidAgent; use LWPx::ParanoidAgent;
use Net::OpenID::Consumer; use Net::OpenID::Consumer;
use CGI::Carp qw(fatalsToBrowser set_message);
use File::Copy; use File::Copy;
use XML::LibXSLT;
use XML::LibXML;
use LWP::UserAgent;
use HTTP::Request;
use CGI::Carp qw(fatalsToBrowser set_message);
set_message("It's not a bug, it's a feature!!<br />(include this error message in your bugreport here: <a href=\"http://yolanda.mister-muffin.de/newticket\">Yolanda bugtracker</a>)"); set_message("It's not a bug, it's a feature!!<br />(include this error message in your bugreport here: <a href=\"http://yolanda.mister-muffin.de/newticket\">Yolanda bugtracker</a>)");

View file

@ -117,7 +117,19 @@ $dbh->do(qq{create table
id int auto_increment not null, id int auto_increment not null,
userid int not null, userid int not null,
videoid int not null, videoid int not null,
text varchar(255) not null, text text not null,
timestamp bigint not null,
primary key (id)
)
}) or die $dbh->errstr;
$dbh->do(qq{create table
pingbacks
(
id int auto_increment not null,
source varchar(255) not null,
videoid int not null,
text text not null,
timestamp bigint not null, timestamp bigint not null,
primary key (id) primary key (id)
) )

137
trunk/pingback.pl Normal file
View file

@ -0,0 +1,137 @@
require "functions.pl";
#initialize session data
CGI::Session->name($config->{"page_cookie_name"});
$query = new CGI;
$session = new CGI::Session;
if ($query->param("POSTDATA"))
{
my $xmlpost = XMLin($query->param("POSTDATA"), ForceArray => 0, KeyAttr => 0);
if (!$@)
{
my $method = $xmlpost->{"methodName"};
my $source = $xmlpost->{"params"}->{"param"}[0]->{"value"}->{"string"};
my $target = $xmlpost->{"params"}->{"param"}[1]->{"value"}->{"string"};
if ($method eq "pingback.ping")
{
if ($source =~ /^http:\/\// and $target =~ /^http:\/\//)
{
#fetch the source URI to verify that the source does indeed link to the target.
my $request = HTTP::Request->new(GET => $source);
my $ua = LWP::UserAgent->new;
my $response = $ua->request($request);
if ($response->is_success)
{
#TODO: sanitize regex to grep site content
if (my ($text) = $response->content =~ m/(\S*.{0,17}$target.{0,17}\S*)/)
{
#check data to ensure that the target exists and is a valid entry.
my ($vid) = $target =~ /^$config->{'url_root'}\/video\/.*\/(\d+)\/.*/;
my $sth = $dbh->prepare("select id from videos where id = ? limit 1");
my $rowcount = $sth->execute($vid) or die $dbh->errstr;
$sth->finish() or die $dbh->errstr;
if ($rowcount)
{
#check that the pingback has not already been registered.
$sth = $dbh->prepare("select id from pingbacks where videoid = ? limit 1");
$rowcount = $sth->execute($vid) or die $dbh->errstr;
$sth->finish() or die $dbh->errstr;
if ($rowcount eq "0E0")
{
#record the pingback.
$dbh->do(qq{insert into pingbacks (source, videoid, text, timestamp) values (?, ?, ?, unix_timestamp())}, undef,
$source, $vid, $text) or die $dbh->errstr;
my $xml = ();
$xml->{'params'}->{'param'}->{'value'}->{'string'} = ["Pingback from $source to $target registered. Keep the web talking! :-)"];
print $session->header(
-type=>'application/xml',
-charset=>'UTF-8',
);
print XMLout(
$xml,
XMLDecl => 1,
KeyAttr => {},
RootName => 'methodResponse'
);
}
else
{
send_error(48, "The pingback has already been registered.");
}
}
else
{
send_error(33, "The specified target URI cannot be used as a target.");
}
}
else
{
send_error(17, "The source URI does not contain a link to the target URI, and so cannot be used as a source.");
}
}
else
{
send_error(16, "The source URI does not exist.");
}
}
else
{
send_error(-32602, "server error. invalid method parameters");
}
}
else
{
send_error(-32601, "server error. requested method not found");
}
}
else
{
send_error(-32700,"parse error. not well formed");
}
}
else
{
print $session->header;
print "XML-RPC server only accepts POST requests with http content-type defined.";
}
sub send_error
{
my ($faultCode, $faultString) = @_;
my $xml = ();
push @{$xml->{'fault'}->{'value'}->{'struct'}->{'member'}},
{
"name" => ["faultCode"],
"value" => [$faultCode]
};
push @{$xml->{'fault'}->{'value'}->{'struct'}->{'member'}},
{
"name" => ["faultString"],
"value" => [$faultString]
};
print $session->header(
-type=>'application/xml',
-charset=>'UTF-8',
);
print XMLout(
$xml,
XMLDecl => 1,
KeyAttr => {},
RootName => 'methodResponse'
);
}

View file

@ -80,6 +80,71 @@ if($query->url_param('id'))
#add to database #add to database
$dbh->do(qq{insert into comments (userid, videoid, text, timestamp) values (?, ?, ?, unix_timestamp())}, undef, $dbh->do(qq{insert into comments (userid, videoid, text, timestamp) values (?, ?, ?, unix_timestamp())}, undef,
$userinfo->{'id'}, $id, $query->param('comment')) or die $dbh->errstr; $userinfo->{'id'}, $id, $query->param('comment')) or die $dbh->errstr;
#send pingbacks to every url in the comment
my (@matches) = $query->param('comment') =~ /(http:\/\/\S+)/gi;
foreach $match (@matches)
{
#ask for http header only - if pingbacks are implemented right, then we wont need the full site
my $request = HTTP::Request->new(HEAD => $match);
my $ua = LWP::UserAgent->new;
my $response = $ua->request($request);
if ($response->is_success)
{
my $pingbackurl = $response->header("x-pingback");
#if there was no x-pingback header, fetch the website and search for link element
if (!$pingbackurl)
{
$request = HTTP::Request->new(GET => $match);
$response = $ua->request($request);
if ($response->is_success)
{
($pingbackurl) = $response->content =~ /<link rel="pingback" href="([^"]+)" ?\/?>/;
}
}
#if requests were successful, send the pingbacks
if ($pingbackurl)
{
#TODO: expand xml entities &lt; &gt; &amp; &quot; in $pingbackurl
#contruct the xml-rpc request
my $xmlpost->{"methodName"} = ["pingback.ping"];
push @{$xmlpost->{'params'}->{'param'} },
{
"value" =>
{
"string" => [$config->{"url_root"}."/video/".urlencode($title)."/$id/"]
}
};
push @{$xmlpost->{'params'}->{'param'} },
{
"value" =>
{
"string" => [$match]
}
};
#post a xml-rpc request
$request = HTTP::Request->new(POST => $pingbackurl);
$request->header('Content-Type' => "application/xml");
$request->content(XMLout(
$xmlpost,
XMLDecl => 1,
KeyAttr => {},
RootName => 'methodCall'
));
$ua = LWP::UserAgent->new;
$response = $ua->request($request);
print $response->content;
#TODO: maybe do something on success?
}
}
}
} }
} }

View file

@ -40,6 +40,9 @@
</xsl:attribute> </xsl:attribute>
</link> </link>
<!-- TODO: get server root from config file-->
<link rel="pingback" href="http://localhost/pingback.pl" />
<xsl:choose> <xsl:choose>
<xsl:when test="//frontpage"> <xsl:when test="//frontpage">