#!/usr/bin/perl -wT
# -*- Mode: perl; tab-width: 4; indent-tabs-mode: nil; -*-
#
# Pingback Client: HTML to Pingback
#
# Copyright (c) 2002 by Ian Hickson
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
use strict;
use diagnostics;
use lib '/home/ianh/lib/perl';
use CGI;
use LWP::UserAgent;
use RPC::XML::Client;
use HTML::Entities;
print STDERR "\npingback client invoked\n";
# set up HTTP client
my $query = CGI->new();
my $ua = LWP::UserAgent->new();
$ua->agent($ua->agent . ' (Hixie\'s pingback client)');
$ua->timeout(5);
$ua->env_proxy();
$ua->protocols_allowed(['http', 'http']);
# get permalink
my $permalink = $query->param('permalink');
if (not defined($permalink)) {
result('400 Bad Request', 'Client Error',
'You must provide a permalink.');
}
print STDERR "permalink: $permalink\n";
# get source content
my $content = $query->param('content');
if (not defined($content) or $content eq '') {
my $request = HTTP::Request->new('GET', $permalink);
$request->referer('http://software.hixie.ch/utilities/cgi/pingback-proxy/client');
$content = $ua->request($request)->content;
}
#print STDERR "content:\n$content\n";
# scan $content for links
my $links = {};
while ($content =~ s/href=\"([^\"]+)\"//os) {
$links->{decode_entities($1)}++;
# using a hash instead of an array avoids duplicates
}
# send pingbacks
my $result = '';
foreach my $link (keys(%$links)) {
# fetch the page
my $request = HTTP::Request->new('GET', $link);
$request->referer($permalink);
my $headers = $ua->request($request);
my $page = $headers->content;
# scan for a pingback link
my $pingbackServer;
if (my @pingbackServers = $headers->header('X-Pingback')) {
# XXX check that there is only one?
$pingbackServer = $pingbackServers[0];
} elsif ($page =~ m//os) {
$pingbackServer = decode_entities($1);
} else {
$result .= "No pingback server at $link\n";
next;
}
# send pingback
my $client = RPC::XML::Client->new($pingbackServer);
my $response = $client->send_request('pingback.ping', $permalink, $link);
if (not ref $response) {
$result .= "Failed to ping back '$pingbackServer': $response\n";
} else {
$result .= "Got a response from '$pingbackServer': \n" . $response->as_string . "\n";
}
}
result('200 Done', 'Done', $result);
sub result {
my($status, $line1, $data) = @_;
my $length = length("$line1\n$data");
print <