Movable Type の XML-RPC API による記事投稿メモ

Movable Type の XML-RPC API を調べていて、metaWeblog.newPostmetaWeblog.editPost に渡すパラメータについて気になったのでメモ。

記事の投稿内容を content 構造体パラメーターで指定するのだが、このパラメーターには Movable Type の独自実装として、たとえば「コメントを許可するかどうか」などを含めることができる。

しかし、これらのうち、いわゆるフラグ系(真偽値)の指定の仕方がちょっと変わっている。

  • mt_allow_comments (int) 0 なら false、1 なら true
  • mt_allow_pings (int) 0 なら false、1 なら true
  • mt_convert_breaks (string) "0" または "none" で false、"1" または "convert_breaks" で true

mt_convert_breaksstring なのは、mt.supportedTextFilters で返ってきた値を使えるようにするためなんだろうな。たぶん。

Redstone XML-RPC Library への不満

どうやら Java の XML-RPC ライブラリとは、あまり縁がないらしい。またもや、XML-RPC ライブラリへの愚痴エントリである

Apache XML-RPC ライブラリの複雑さとドキュメントのすくなさ(いつまでホームページのロゴ画像がリンク切れなのだろう?)に辟易して、今度は Redstone というライブラリを試してみた。

Redstone の前身である Marquee というライブラリは developerWorks に紹介記事だって載っている由緒正しい(?)XML-RPC ライブラリだ。

最初は何も問題ないかのように思えた。すべてが順調で平和だった。API はシンプルで、ホームページの簡潔なチュートリアルも必要十分に思えた。

だが、決して小さくはない欠陥がいくつもあることがわかってきた(バージョンは 1.0.1)。

  1. contentType の指定が無視される
  2. エラー処理がいいかげん
  • <methodResponse> の faultCode がハードコーディングされている。
  • そのエンコーディングも ISO-8859-1 でハードコーディング。日本語書けない。せめて UTF-8 にしてよ...
  1. Base64 のコードがバグっていて、複数行にエンコードされていると対応できない。
  2. カスタマイズが困難。
  • API がシンプルで一見、拡張しやすく見えるが、実際には重要なポイントが private だったりしてサブクラス化しづらい。
  • たとえば、XmlRpcDispatcher を拡張しても、それを使っている XmlRpcServer に独自の XmlRpcDispatcher を設定する API がない(ので、結局、こいつもサブクラス化して、さらに、サブクラス化した XmlRpcServer を使う XmlRpcServlet を書いて ...)。
  • XmlRpcParser は XML-RPC の xml を解析できるが、肝心の結果は private になっているため、これ単体で使えない。

実は 3. までの問題を修正するためのラッパーライブラリを、テストコード含めて 800 行ほど書いていた。しかし、それも 4. の理由により挫折しかけている。まあ、ad-hoc な修正の塊なので、コード自体はもったいなくないのだが。

誰も XML-RPC なんて使ってないのかな...。

XML-RPC で "Premature end of file."

Java で XML-RPC の開発をしている。

動作確認は UNIX コマンドの curl で手軽にすませているのだが、突然、すべての curl コマンドで Premature end of file. というエラーが出るようになった。

[Fatal Error] :-1:-1: Premature end of file.

このエラーには見覚えがある。たしか、XML の絡んだ通信で接続状態が悪くなり、通信が途絶えた場合などに ぼろぼろ出ていたやつだ。つまり、XML が不完全なのだろう。

しかし、curl の POST で送っているデータをいくら調べてもおかしい部分が見つからない。 問題になりがちな改行を取り除いても、コンソールのエンコーディングを変更しても同じ。

しかたがないので、デバッガでブレークポイントを設定し、動作を追ってみた。

その結果、リクエストオブジェクトの入力ストリームから読み出す時点でデータが空なことが判明。つまり、curl で POST したデータを読みだせていないわけだ。

では、何が原因でデータを読みだせていないんだろう? curl の -v オプションの出力を眺めているうちに気がついた。


POST /api/xmlrpc HTTP/1.1
User-Agent: curl/7.13.1 (powerpc-apple-darwin8.0) libcurl/7.13.1 OpenSSL/0.9.7l zlib/1.2.3
Host: example.com
Pragma: no-cache
Accept: */*
Content-Length: 123
Content-Type: application/x-www-form-urlencoded

application/x-www-form-urlencoded で POST しているせいだ。

Content-Typeapplication/x-www-form-urlencoded だと、HttpServletRequest がパラメータとして解析するために先に入力を読みだしてしまうので、HttpServletRequest#getInputStream() から読みだすときは空なわけだ。

次のように POST すれば、正常に動作した(--data-ascii の XML は省略)。


% curl -v -H "Content-Type: text/xml" --data-ascii "..." "http://example.com/api/xmlrpc"

どうやら、昨日まではちゃんと -H オプションで Content-Type を指定していたのだが、一日寝ると忘れてしまったようだ

だから、ブログに書いている。

Apache XML-RPC への不満

Apache Web Services Project の一環として開発されている Apache XML-RPC は Web に紹介記事も多く、もっとも利用されている印象を受ける。

実際、これまで仕事でも XML-RPC クライアントとして Apache XML-RPC を使用していた。他の選択肢を知らなかった、というのもあるが、Apache というブランドの影響も大きいと思う。

しかし、不満がないわけではない。

特に、クラス階層が複雑なのには手こずった。動作をカスタマイズしたいときなど、あるクラスがどのインターフェースを実装し、どのファクトリで生成されるかを調べるだけでも大変だ(RequestProcessorFactoryFactory インターフェースまでくると、もう冗談のように思えてくる)。

実例をあげよう。

RPC の結果として不正な XML が返ってきた場合のエラー処理。 たとえば、XML 宣言の前に PHP のエラーが出力されている、なんてことはざらにある(現実とはそういう世界なのだ)。こういうときでも、XML 宣言以降は正当な XML なので、できるだけ XML をパースして処理の結果を拾いたい。

そして、このリカバリ処理自体は難しくない。例外をキャッチして、結果の文字列を XML 宣言までスキップして、再度パースしてみるだけだ。

だが、結局、その処理をするためには、ダウンロードした Apache XML-RPC のソースコードから既存のクラスをコピーして別のクラスを作成する必要があった。どうしてだろう? もしかすると、他にエレガントな解決方法があったのかもしれない。だが、発見できなかった。

そして、いま、サーバサイドの XML-RPC サービスを実装しているのだが、今度は出力エンコーディングを設定する方法が分からない。きっとどこかで、エレガントな解決方法が、発見されるのを待っているのだろう。

ブログの XML-RPC サポート

個人的メモとして、各ブログの XML-RPC サポート状況をまとめてみた。

Movable TypeBlogger の API と、米 UserLand Software 社の MetaWeblog API に準拠しているようだ。また、WordPressMovable Type に準ずるかたちになっている

面白いのは Blogger。 現在は XML-RPC ではなく、 Google Data APIs (GData) による Blogger Data API を使用している。

Web ページのサイドバーには他にも "Calendar Data API""Spreadsheets Data API" など、Google の他サービスの名前が並んでいるので、GData はこれらのサービスでも実装されているのだろう。GData によるサービス同士の連携もあるのかもしれない。

Want fries with that?

Open Source Projects