日記
PingProxy α版 (20:18)Edit

※注意書き

  • PingProxyを利用するいしだなおとさんによる「htmlによるTrackBackクライアント実装(http://www.ksky.ne.jp/~naoto/39_akiary/n3/200310.html#20031010_1065724154)」が公開されています。
  • urlsパラメータで送信するべき文字列は、TrackBack Ping URLではなく、記事URL(いわゆるPermalink)の方です。TrackBack Ping URLが送られてもそこへのPing送信は代行しませんのでご注意ください。
  • Perlのサンプルが間違っていたので修正しました。


日記やらblogやらwikiやらCMSやらの連携について議論するMLの、

あたりで書いたTrackBack送信代行サーバーPingProxyをテスト実装してみた。

概要

TrackBack、PingBackなどの送信を代行する専用サーバーを用意することによって、ユーザーの使い勝手を向上させる仕組み。TrackBack Ping URLの存在を気にすることなく、PingBackと同等の操作でTrackBackが気軽に送れるようになる。

重複チェック(同じTrackBackを複数回送ってしまう)、存在チェック(間違ったURLに送ってしまう=タイムアウトまで待つ?)、文字コードチェック(送り先の文字コードを確認して、その文字コードに変換した上で、charsetパラメータもつけて送る)などもサーバーサイドで代行する。

詳細

TrackBackを一般ユーザーとして利用する際の、私が思うところの弱点は、

  • 言及したい記事URLとTrackBack Ping URLを結びつけることを意識するのがうざい(bookmarkletを使ったところで)
  • できれば、PingBackみたいに含まれるURL一通りに対して自動的に(相手が対応していれば)Pingを送って欲しい
  • でも、PingBackはサーバー負荷&時間がかかるから、記事更新時のレスポンスが悪くなるのがうざい
  • ただのTrackBackの場合でも、相手先サーバーが重ければレスポンスが悪くてうざい

というあたりなんで、そのあたりを解消するために、

  • PingProxy I/F(http://pingproxy.ishinao.net/ping)がすべてのPing投稿をうけつける
  • PingProxyにはHTTP POSTで以下のパラメータを送信する。
    • url(必須)……送信元記事の固定URL
    • title……送信元記事のタイトル
    • blog_name……送信元記事を含むサイト名
    • excerpt……送信元記事の要約
    • charset……POSTしたパラメータの文字コード
    • urls(必須)……言及先URL文字列(複数)を含むテキスト。※ここでいう言及先URL文字列というのは、TrackBack Ping URLではなく、記事URL(いわゆるPermalink)のことです。TrackBack Ping URLを送信してもPingを送りません。
  • PingProxyは、上記のPing投稿を受け付けると、ただちに「OK」という文字列を返す。それ以外の文字列が返された場合はエラー。
  • PingProxyは、投稿されたurlsに含まれるURL文字列を抽出し、そのURL文字列に対応したPing I/Fが存在するかどうかを確認する
    • 埋め込みRDFを使ったTrackBack Ping I/Fを検索する
    • はてなダイアリーの記事URL文字列に合致する場合は、末尾にtrackbackをつけたものをPing URLと見なす
    • blogmapにそのURLに関する項目がないかを確認し、存在した場合はblogmapのTrackBack Ping URLを返す
    • PingBack I/Fを検索する(未実装)
  • Ping投稿を実際のPing処理コマンドに分解する
    • 投稿元記事URLと、その記事に含まれるターゲットURL、ターゲットURLが持つPing I/F、という組み合わせ分のPing処理コマンドを予約する
    • すでに処理が行われた組み合わせのコマンドは重複実行しない
  • 各URLに関する情報を収集する
    • そのURLは本当に存在するか
    • そのURLではどの文字コードを利用しているか
  • 実際にPing処理コマンドを実行する
    • すべての準備が整ったPing処理コマンドを順次実行していく
    • TrackBack Pingを送信する
      • 送信先のcharset(だと思われるもの)に合わせてパラメータの文字コードを変換した上で、charsetパラメータ付きで送信する
    • pingback.pingを送信する(未実装)
    • 各Ping処理コマンドの実行結果をログに記録していく

urlsには、言及先の記事URLを列挙してください。記事本文を丸ごとurlsとして投稿しても、その中に含まれるURLを自動的に抽出するので、通常は記事本文を丸ごと投稿してしまって構いません。

まだほとんどテストも行っていないので、ひとまずは概要説明ってことで。裏タスクは-[まだ自動化していません。もうちょっと試して問題なさそうならば、裏タスクを自動化しつつ、-自動化しました。表側のWebインターフェース(ログ表示とか)も用意します。

α版のURL

直接PingProxy I/Fを叩く場合は、

を。

HTMLフォームから手動で送信する場合は、

を使うと動作します。

PHPによるPingProxy送信サンプルコード

$pingproxy = 'http://pingproxy.ishinao.net/ping';
$charset = 'euc-jp';
$blog_name = 'サイト名';
$url = '記事のURL';
$title = '記事のタイトル';
$body = '記事本文';
$excerpt = '記事の要約';
$query = 'url='.urlencode($url);
$query .= '&title='.urlencode($title);
$query .= '&blog_name='.urlencode($blog_name);
$query .= '&charset='.urlencode($charset);
$query .= '&excerpt='.urlencode($excerpt);
$query .= '&urls='.urlencode($body);
$curl = curl_init($pingproxy);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $query);
ob_start();
curl_exec($curl);
ob_end_clean();
curl_close($curl);

Perl+LWPによるPingProxy送信サンプルコード

use URI::Escape;
use LWP::UserAgent;
use HTTP::Request;
my $pingproxy = 'http://pingproxy.ishinao.net/ping';
my $url = '記事URL';
my $title = '記事タイトル';
my $blog_name = 'サイト名';
my $excerpt = '記事要約';
my $body = '記事本文';
my $charset = 'euc-jp';
my $ua = new LWP::UserAgent;
my $headers = new HTTP::Headers;
$headers->header('Content-type','application/x-www-form-urlencoded');
my $query = 'url='.uri_escape($url);
$query .= '&title='.uri_escape($title);
$query .= '&blog_name='.uri_escape($blog_name);
$query .= '&charset='.uri_escape($charset);
$query .= '&excerpt='.uri_escape($excerpt);
$query .= '&urls='.uri_escape($body);
my $request = new HTTP::Request('POST', $pingproxy, $headers, $query);
my $response = $ua->request($request);

rubyによるPingProxy送信サンプルコード

require('cgi.rb');
url = '記事URL'
title = '記事タイトル'
blog_name = 'サイト名'
excerpt = '記事要約'
body = '記事本文'
charset = 'euc-jp'
query = 'url='+CGI::escape(url)
query += '&title='+CGI::escape(title);
query += '&blog_name='+CGI::escape(blog_name);
query += '&charset='+CGI::escape(charset);
query += '&excerpt='+CGI::escape(excerpt);
query += '&urls='+CGI::escape(body);
require 'net/http'
http = nil
response = nil
header = {}
header['Content-type' = 'application/x-www-form-urlencoded'
Net::HTTP.start('pingproxy.ishinao.net') {|http|
response ,= http.post('/ping', query, header)
}

※一応動いたけど、rubyはさっぱり分からないんで、そのまま使うのは危険かも

はてなダイアリーとの連携テスト用

はてなダイアリーでは、送信元URLに送信先URL文字列が含まれるかを確認するため、送る前にURLを記述しておかないといけない。

懸案事項

  • はてなダイアリーのように、送信元URLに送信先URLが含まれているかを確認した方がいいだろうか?
  • 内部EUC-JPなんで、日本語・英語以外の文字コードはサポートできないけれども、本気でやるならば内部UTF-8でやるべきなんだろうなー。
  • MovableTypeにPingProxy送信機能を組み込んでみたんだけど、MovableTypeって派生物の配布も許可していないってことは、改変コードの提示も許可されないのかな? それとも、MovableType自身のコードを含まなければいいのか? 微妙だ。
  • PingProxyって、MovableTypeでTrackBackをProxy経由で送るときの設定項目名と同じだな。ややこしくなるから変えた方がいいかな。

Published At2003-10-01 00:00Updated At2003-10-01 00:00