2006年12月アーカイブ

PUTとPOSTの違い

リクエストURIとリクエストボディの意味が違うのか。

リクエスト POST と PUT とでの根本的な違いは、 Request-URI の意味の違いをもたらす。
POST リクエストにおける URI は、同封されたエンティティを処理するであろうリソースを識別する。
(中略)
それに対して、PUT リクエストにおける URI は、リクエストとともに同封されたエンティティを識別する。
ハイパーテキスト転送プロトコル -- HTTP/1.1
The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI.
The URI in a POST request identifies the resource that will handle the enclosed entity.
(中略)
In contrast, the URI in a PUT request identifies the entity enclosed with the request.
9.6 PUT - [RFC2616]Hypertext Transfer Protocol -- HTTP/1.1

POSTはリクエストデータを処理するためのリソースにリクエスト。PUTはリソース自体にリクエスト。メソッドの結果(『リソースを作る(変更する)』)が同じでも、URIが表すリソースが違うんだね。

RESTのPOSTとPUTの話も、URIが意味する『リソース』に注目したときの違いが重要だよってことだったのかな?
Why PUT and DELETE?
↑は、きっと興味深い事が書いてあるんだろうけど、英語なのでいまいち分からない。

まだまだHTTPについて勉強不足です。

カテゴリアーカイブのサイズが無駄に大きくなりすぎたので、Paged Archivesプラグインでカテゴリアーカイブをページ分割してみた。
Alden Bates' Weblog: Paged Archives plugin

元々、Paged Categoriesとして提供されていたかなんだかっぽい。なので、以下の日本語情報がほぼそのまま使える。
HTMLでカテゴリーアーカイブのページ分割を行う『Paged Categories Plugin』 (Apres Un Reve: Movable Type Customize)
<MTPC***>を、<MTPA***>に読み替えればよし、かな。

カテゴリ数を考え無しに減らしたのはまずかった。。。

FirefoxのスマートキーワードとGoogleのsite:を利用して、アプリケーションのオンラインドキュメントを簡単に検索出来るようにしたらどうにかなるかも。

何をするにも『まずはGoogleで。。。』というのが癖なんだけど、これは『とりあえず"検索"して適当なページ出てこい』という気持ちでやってる気がしないでもない。なので、同じような手順でドキュメントを手に入れる(表示させる)ところまで出来るように準備。

準備と言っても、めぼしいドキュメントについてsite:で絞り込めれば、後はGoogle検索のURLをいじくって、それをブックマークしてキーワードを割り当てるだけ。

http://www.google.co.jp/search?hl=ja&q=site%3Asubversion.bluegate.org%2Fdoc%2F%20%s&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=

↑はSubversion Book。これに"svn?"を割り当てて利用中。とりあえず、bookmarkletによるプチコマンドと区別するためにサフィックスとして?を付けてみてます。コマンドは頭に:かな、と。

あとは、ApacheとかMySQLとか色々。del.icio.usへのpostもだし、あとで読むとかにも割り当て。

後は、しばらく使ってみて本当にドキュメントを読む癖がつくかどうか。


ちなみにFirefoxの検索窓は消してます。

mod_cacheの有効期限について勘違いしてた。
mod_cache - Apache HTTP サーバ

mod_cacheは基本的に、Last-Modifiedヘッダがないコンテンツ(レスポンス)はキャッシュしない。"CacheIgnoreNoLastMod On"とする事で、Last-Modifiedヘッダがなくてもキャッシュするようになる。

Last-Modifiedヘッダがあり、有効時間が設定されていないコンテンツ(レスポンス)の有効期限は、特別な式で計算される。

有効時間[s] = (現在日時[s] - コンテンツ最終更新日時[s]) * CacheLastModifiedFactor

Expiresヘッダに使われる有効期限は、"現在日時+有効時間"で決まる。このとき、有効時間は"CacheMaxExpire"を最大とする。

キャッシュ有効時間のデフォルトとして、"CacheDefaultExpire"ディレクティブが利用可能。ただし、これはLast-Modifiedヘッダがなく、有効時間も設定されていないコンテンツに限って有効となる。

ずっと、"CacheDefaultExpire"が無条件で使えるんだと考えてたので、大失敗。PHPでの動的コンテンツのキャッシュを考えていて、If-Modified-Sinceでの304応答が出来るようにと、Last-Modifiedヘッダを付けたのがまずかった(まずくないんだけど)。Last-Modifiedヘッダをつけたのに、"CacheLastModifiedFactor"を調整しなかったので微妙にキャッシュがきかなかったり。

問答無用で一定時間はサーバ側でキャッシュしたコンテンツを返したかったので、"CacheLastModifiedFactor"を"CacheMaxExpire"にそろえて、"Last-Modified == 現在日時"でない限りは"CacheMaxExpire"が使われるように調整。効果云々は抜きにして、期待通りの結果が得られて満足(とりあえずは)。

あと、mod_disk_cacheを使っているので、htcachecleanをデーモンで起動。
htcacheclean - Clean up the disk cache - Apache HTTP Server

さて、これから様子を見て調整してかないとね。

"URI Template"ってのが気になって、色々見てみたんだけど、英語なのでさっぱり理解出来ない。
URI Template(draft-gregorio-uritemplate-00.txt)

snellspace.com » Blog Archive » URI Templates in XML
XMLの名前空間を使ってごにょごにょするだなんだというのを見る限り、テンプレートの解決に名前空間で定義された参照先を利用するような印象。となると、クライアント側でURIを作成出来るようにするためのものなのかな。

RESTfulなアプリケーションのURIを連鎖的に叩く場合で、それぞれのURIの作成をクライアント側で制御したい場合に使うもの?レスポンスに埋め込まれた"URI Template"とクライアントが持つ情報(ユーザ名だとか)を使って、叩くべきURIを決定する、とか。

  1. URIのベースをサーバが返す
  2. xmlnsとかでテンプレート規則を参照させる
  3. クライアントはテンプレートを利用してURIを組み立ててリクエスト

よくわかりません。

PEARのXML_RPCを使って、RESTサーバに送信した場合どうなるか見てみた。

<?php
 
require_once "XML/RPC.php";
 
$title  = "KoshigoeBLOG";
$url    = "http://blog.koshigoe.jp/";
$rss    = "http://blog.koshigoe.jp/index.xml";
 
$params = array(
                new XML_RPC_Value("", "string"),
                new XML_RPC_Value("", "string"),
                );
$message = new XML_RPC_Message("weblogUpdates.ping", $params);
 
$clients = array();
 
$server    = "blogsearch.google.co.jp";
$endpoint  = "http://blogsearch.google.co.jp/ping?name=" . urlencode($title) .
    "&url=" . urlencode($url) . "&changeURL=" . urlencode($rss);
$cli       = new XML_RPC_Client($endpoint, $server);
$cli->setDebug(1);
$clients[] = $cli;
 
$server    = "api.my.yahoo.co.jp";
$endpoint  = "http://api.my.yahoo.co.jp/rss/ping?u=" . urlencode($rss);
$cli       = new XML_RPC_Client($endpoint, $server);
$cli->setDebug(1);
$clients[] = $cli;
 
foreach ($clients as $cli) {
    $resp = $cli->send($message);
    if (!$resp) {
        echo 'Communication error: ' . $cli->errstr;
        exit;
    }
    if (!$resp->faultCode()) {
        $val = $resp->value();
        $data = XML_RPC_decode($val);
        echo $data[0]['name'] . ' is at version ' . $data[0]['version'];
    } else {
        echo 'Fault Code: ' . $resp->faultCode() . "\n";
        echo 'Fault Reason: ' . $resp->faultString() . "\n";
    }
}
 
/** results
 
<pre>---GOT---
HTTP/1.0 200 OK
Content-Type: text/plain; charset=Shift_JIS
Set-Cookie: PREF=ID=43cfaf2c8e225666:TM=1166889903:LM=1166889903:S=_ShDAUWKrIV9dhMG; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.co.jp
Server: psfe
Content-Length: 20
Date: Sat, 23 Dec 2006 16:05:03 GMT
Connection: Keep-Alive
 
Thanks for the ping.
---END---</pre>
XML error at line 1, check URL
Fault Code: 2
Fault Reason: Invalid return payload: enable debugging to examine incoming payload
 
<pre>---GOT---
HTTP/1.1 200 OK
Date: Sat, 23 Dec 2006 16:05:04 GMT
P3P: policyref="http://p3p.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"
Content-Length: 320
Connection: close
Content-Type: text/plain
 
Refresh requested: http://blog.koshigoe.jp/index.xml
 
Blog Search: Successfully refresh requested
My Yahoo! RSS reade: Feed not found. To request refresh, add feed to My Yahoo!
About "Blog Search", see "http://blog-search.yahoo.co.jp/"
About "My Yahoo! RSS reader", "http://my.yahoo.co.jp/promo_jp/rss_reader/index.html"
---END---</pre>
XML error at line 1, check URL
Fault Code: 2
Fault Reason: Invalid return payload: enable debugging to examine incoming payload
 
**/
 
?>

プログラムを正常終了出来て、pingサーバからのHTTPレスポンスもping受信完了のもの。ただ、RESTサーバからのレスポンスはtest/plainなので、XML-RPCのレスポンス処理で問題が起きる。といっても、HTTPステータスを確認して問題なかった後のXMLパーズでの問題。

どうやら、RESTのpingサーバにXML-RPCクライアントからweblogUpdates.pingで送っても大丈夫っぽい。

XML-RPCにしろ、RESTにしろ、HTTPでリクエストして受け取ってもらえればいいわけだ。

普段pingを送らないのでよく知らなかったんだけど、試してみれば問題無さげ。既存のweblogUpdates.pingを送るXML-RPCクライアントをそのまま使っても、RSSのURLを明示的に指示する事は出来るんだね。まあ、レスポンスの処理をどうするかってのが問題になるだろうけど。あくまで、運用(利用者)側の『動くよ的回避策』かな。

更新通知pingのRESTサーバって、『weblogUpdates.extendedPing的な事をしたいけど、クライアントはweblogUpdates.pingしか使えない』って場合に使うために用意されたもの?簡単に(手順を少なくして)使えるようにするため?


XML-RPCクライアントをシミュレート(?)したつもりでいるんだけど、間違ってるかな?

~% telnet blogsearch.google.co.jp 80

Trying 216.239.53.99...
Connected to blogsearch.google.com.
Escape character is '^]'.
POST /ping?name=KoshigoeBLOG&url=http%3A%2F%2Fblog.koshigoe.jp%2F&changesURL=http%3A%2F%2Fblog.koshigoe.jp%2Findex.xml HTTP/1.0
User-Agent: request
Host: blogsearch.google.co.jp
Content-Type: text/xml
Content-Length: 247

<?xml version="1.0"?>
<methodCall>
  <methodName>weblogUpdates.ping</methodName>
  <params>
    <param>
      <value>KoshigoeBLOG</value>
    </param>
    <param>
      <value>http://blog.koshigoe.jp/</value>
    </param>
  </params>
</methodCall>
HTTP/1.0 200 OK
Content-Type: text/plain; charset=Shift_JIS
Set-Cookie: PREF=ID=3140ff3e20e5948a:TM=1166793472:LM=1166793472:S=zHurbS1h7XqPZ6_i; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.co.jp
Server: psfe
Content-Length: 20
Date: Fri, 22 Dec 2006 13:17:52 GMT
Connection: Keep-Alive

Thanks for the ping.Connection closed by foreign host.

~% telnet api.my.yahoo.co.jp 80
Trying 203.216.243.185...
Connected to api.my.yahoo.co.jp.
Escape character is '^]'.
POST /rss/ping?u=http%3A%2F%2Fblog.koshigoe.jp%2Findex.xml HTTP/1.0
User-Agent: request
Host: blogsearch.google.co.jp
Content-Type: text/xml
Content-Length: 247

<?xml version="1.0"?>
<methodCall>
  <methodName>weblogUpdates.ping</methodName>
  <params>
    <param>
      <value>KoshigoeBLOG</value>
    </param>
    <param>
      <value>http://blog.koshigoe.jp/</value>
    </param>
  </params>
</methodCall>
HTTP/1.1 200 OK
Date: Fri, 22 Dec 2006 13:19:48 GMT
P3P: policyref="http://p3p.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"
Content-Length: 320
Connection: close
Content-Type: text/plain

Refresh requested: http://blog.koshigoe.jp/index.xml

Blog Search: Successfully refresh requested
My Yahoo! RSS reade: Feed not found. To request refresh, add feed to My Yahoo!
About "Blog Search", see "http://blog-search.yahoo.co.jp/"
About "My Yahoo! RSS reader", "http://my.yahoo.co.jp/promo_jp/rss_reader/index.html"Connection closed by foreign host.

色々触ってみると、なかなか反映されずに戸惑う。

リクエストだけ投げて、後は裏でバッチ処理してるのかな?postのeditとかもガワだけ変えて実際のデータは変わってない?

イラっとくるときもあったけど、まあ妥当だよね。

fragmentを付けてGETした場合とか、サーバは環境変数のQUERY_STRINGとかをどう扱うべきなんだろう。

http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
...
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
...
Request-URI = "*" | absoluteURI | abs_path | authority
Hypertext Transfer Protocol -- HTTP/1.1

↑を見た感じ、fragment付きでリクエストされる事を想定してないように思えるんだけど、どうなんだろう。

とりあえず、実装(挙動)を見ようと言う事でテスト。Apache2で動くPHPプログラムで環境変数をダンプしてみたのが↓(プログラムとテスト結果)。

<?php
 
/** /test/dump.php **/
 
echo "from \$_SERVER:\n";
echo "\tREQUEST_URI  = " . $_SERVER["REQUEST_URI"]  . "\n";
echo "\tQUERY_STRING = " . $_SERVER["QUERY_STRING"] . "\n";
 
echo "from \$_GET:\n";
var_dump($_GET);
 
echo "use apache_getenv():\n";
echo "\tREQUEST_URI  =  " . apache_getenv("REQUEST_URI")  . "\n";
echo "\tQUERY_STRING = "  . apache_getenv("QUERY_STRING") . "\n";
 
/*
~% telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET /test/dump.php?key=value&foo=bar#fragment HTTP/1.1
Host: locahost
 
HTTP/1.1 200 OK
Date: Thu, 21 Dec 2006 13:16:56 GMT
Server: Apache/2.2.3 (Unix) mod_ssl/2.2.3 OpenSSL/0.9.8d DAV/2 PHP/5.2.0
X-Powered-By: PHP/5.2.0
Content-Length: 308
Content-Type: text/html
 
from $_SERVER:
        REQUEST_URI  = /test/dump.php?key=value&foo=bar#fragment
        QUERY_STRING = key=value&foo=bar
from $_GET:
array(2) {
  ["key"]=>
  string(5) "value"
  ["foo"]=>
  string(3) "bar"
}
use apache_getenv():
        REQUEST_URI  =  /test/dump.php?key=value&foo=bar#fragment
        QUERY_STRING = key=value&foo=bar
*/
 
?>
 

fragmentはQUERY_STRINGには含まれず、GETパラメータ(引数)にもくっつかない。foo="bar#fragment"として解釈されるケースってあるのかな?あったとして、それはRFC準拠ってこと?生#はコンポーネントのデリミタだからおかしい?

The generic syntax uses the slash ("/"), question mark ("?"), and number sign ("#") characters to delimit components that are significant to the generic parser's hierarchical interpretation of an identifier.
Uniform Resource Identifier (URI): Generic Syntax

IE6ではLocationで得たURLについては、fragmentが付いていてもそのままリクエストするらしい。世にあるプログラム(アプリケーション)では、これを踏まえた上で、それでも(fragment付きでリクエストされても)動く様に作られているのかな?それとも、『リクエストが悪い』ってことで、エラー扱い?

いろんなウェブサーバの挙動を見てみたいけど、Apache以外よく分かんないんだよなぁ。。。

『第九回XML開発者の日』で、「ネタがあったら"for:username"でタグつけて教えてね。」なんていうヒトコマから知ったんだけど、使ってみたら何か楽しい。

どうやら、private扱いらしい。RSSは"/rss/for/username?private=****"で取得出来る。

そういえば、del.icio.usユーザーなら誰でも誰にでも"links for you"出来るんだよね?だとすると、嫌がらせ(SPAM)とかあった場合に何か対応策ってあるのかな?『狙い撃ち』感が強いし、よほどの事がなければないかな。

まあ、「だから何?」とか「それ○○で」かも知れないんだけどね。個人的に楽しいです(今のところ)。


『これ見て勉強しろ、"for:koshigoe"』歓迎します。

注)激しく的外れな事を書いている気がします。

知らなかった。。。というか、fragmentって言葉を知らなかった(ハッシュとかページ内アンカーとか、適当に呼んでた)。

「Locationヘッダにfragmentを含めていいのかどうか」という疑問にぶつかって、Locationヘッダはabsolute-URIを利用可能という事で、じゃあOKだね、と。

Location = "Location" ":" absoluteURI
[RFC2616]Hypertext Transfer Protocol -- HTTP/1.1
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
[RFC3986]Uniform Resource Identifier (URI): Generic Syntax

URI?まあ、いいか。

absolute-URI = scheme ":" hier-part [ "?" query ]
[RFC3986]Uniform Resource Identifier (URI): Generic Syntax

駄目じゃん。。。URIで安心してabsolute-URIを見逃してた(嘘付きました、ごめんなさい)。

この疑問の切っ掛けは、「IE6でfragmentを含むURLのリダイレクトに失敗してるよ」と言われたから。

ヘッダを見てみると、↓。

Location: http://www.example.com/item?id=1234#price
...
GET http://www.example.com/item?id=1234#price HTTP/1.1

このときのレスポンスはプログラムが吐いているエラーページ。で、Firefoxだと、↓。

Location: http://www.example.com/item?id=1234#price
...
GET http://www.example.com/item?id=1234 HTTP/1.1

どうやら、Locationで受け取ったURLをGETする間で何かがあるらしい。で、エラーページが出てきたのは、クエリの解釈を期待通りに出来てない事が原因らしい。id="1234"を期待してるけど、id="1234#price"で渡ってる、と。

で、IE7で試すと問題がないらしい。ん?RFC2396->RFC3986で何か変わった?

URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
absoluteURI = scheme ":" ( hier_part | opaque_part )
[RFC2396]Uniform Resource Identifiers (URI): Generic Syntax

変わってない。じゃあ、HTTP/1.0かと思ってみても、Locationの記述は変化無し。

Location = "Location" ":" absoluteURI
[RFC1945]Hypertext Transfer Protocol -- HTTP/1.0

fragment付きURIにリダイレクトする場合、HTTPヘッダだけでは無理?

「動くから」を理由にしてLocationヘッダにfragment付きURIを利用して問題はないでしょうか?IE6については、「key=value&#fragmentにしてしまえ」で。。。

「fragment込みのURIはユニークなリソースIDだ」と考える事は無茶なのかな。「RFC準拠ですから」でWeb利用者は納得出来るもの?

「RFCに従いつつ、fragment込みのURIにリダイレクトする方法」を考えないと、かなぁ。


。。。Web系開発に携わってるくせに、根っこを押さえられてない自分が憎い。。。


Locationヘッダに関する正誤表?

Location = "Location" ":" absoluteURI [ "#" fragment ]
HTTP/1.1 Specification Errata

設定をミスったと思ったら、importしたブックマークはprivateになるって書いてあった。

はてなブックマークをHTMLでエクスポートして、del.icio.usにimportしてみたんだけど、みごとに"not shared"。これを全部公開するには、こつこつAPIを叩く何かを使うしかないのかな。

/v1/posts/allで全件取得して、/v1/posts/addでshared=yesにして。。。

10件くらいならともかく、1000件以上のブックマークをWebのUIから公開するのは無理だなぁ。まあ、ブラウザのブックマークをimportするってのが主な用途みたいだし、仕方ないのか。

間違えて公開にしないようにする安全策なんだろうけど、選択出来てもいいんじゃないかな。

mod_cacheを使ってみた

mod_disk_cacheと組み合わせて使ってみた。

(Client)---((Load Balancer)---(Web server))

  • ロードバランサはApache2.2(mod_proxy_balancerだと思う)
  • ウェブサーバはApache2.0
  • コンテンツの生成はウェブサーバ
  • mod_cacheはロードバランサで動作

よく分からなかったのでとりあえず動かしてみようと、上記構成でテストしたわけだけど、普通に裏で生成されたコンテンツをロードバランサでキャッシュ出来るんだね。コンテンツの生成はPHPプログラムなんだけど、(PHPスクリプトで)Last-Modified吐くようにしたら普通に304応答もしてくれた(裏にリクエストは飛んでないと思う; ログを見る限り)。

お手軽(『実験的』というのは怖い気がするけど)。

メタデータ技術とセマンティックウェブ』を読んで存在を知ったんだけど、今どんな感じなんだろう。
newsml.jp

NewsMLが足踏みしている間に,同じXMLのサブセットとも言えるRSSが,ブログから始まり新聞社のニュースサイトまで草の根的に一気に普及したのは,興味深い。
メディア・パブ: 新聞業界のNewsMLプロジェクトが足踏み
XMLベースのニュース配信用フォーマット「NewsML (News Markup Language)」も、RSSをサポートする予定で検討を進めているそうだ
サービス & 製品 > XML > ニュース解説 > 2004年1月21日 - FUJITSU Japan

新聞社のRSSってNewsMLから変換してたりするのかな(NewsMLの前のDBから直接出してる?)。"NewsMLによるRSSサポート"ってどういう意味なんだろう。xmlnsとか?

業務面で意味があるものなのかな?別フォーマットでの公開に向けたデータソースとして利用出来るものなんだろうか?

CarbonEmacsと違って、kill-ring=クリップボードでは無いらしい事を初めて知った。

↓のelispで多少改善されるらしい。
macosxhints.com - A script to enable XEmacs to OS X clipboard sharing
まあ、Terminalのcmd+cとかcmd+v使えばいいのかもだけど、region指定してC-wしちゃうよね。上記elispをそのまま使ってもkill-ringには入らないのは気になる。

そもそも、CarbonEmacsとかW32Emacsとか、Window System(?)で動くemacsしか使って来てないから、コンソール(?)で動くemacsが微妙な感じ。

zshの日本語環境の設定に失敗しているせいか、emacs上での表示が崩れる(C-x hして直してる)。

Terminal内でemacsを使わなきゃいけない理由が無いので、おとなしくCarbonEmacs使うかな。screenで画面を2分割して、その上下でほげほげってのはちょっとしたいかも。

ローカルファイルしか触らないし、まだしばらくはCarbonEmacsでいいや。

結構前に問題は把握してたんだけど、なぜか実行してなかったのでこの機会に入れ直してみた。
SPARK?: osx - ssh接続がタイムアウトで切れてしまう

MacPortsの影響か分からないけど、OpenSSLのライブラリがmissmatchらしいので、/usr/local/sslに0.9.7lを入れる(デフォルト)。

% wget wget http://www.openssl.org/source/openssl-0.9.7l.tar.gz
% tar xvzf openssl-0.9.7l.tar.gz
% cd openssl-0.9.7l
% ./config
% make
% sudo make install

heartbeatパッチのバージョン番号は4.4p1になってるけど、無視してOpenSSH4.5p1に当てる。で、OpenSSLを入れたディレクトリを指定してconfigureしてmake。

% wget ftp://ftp.iij.ad.jp/pub/OpenBSD/OpenSSH/portable/openssh-4.5p1.tar.gz
% tar xvzf openssh-4.5p1.tar.gz
% wget http://www.sc.isc.tohoku.ac.jp/~hgot/sources/openssh-4.4p1-watchdog.patch.tgz
% tar xvzf openssh-4.4p1-watchdog.patch.tgz
% cd openssh-4.5p1
% patch -p0 < ../openssh-4.4p1-watchdog.patch
% ./configure --with-ssl-dir=/usr/local/ssl
% make
% sudo make install

後は、~/.ssh/configに"Heartbeat 120"を追記。

MacPortsだけで何とかならないかと、"port search ssh"したら、autosshというのを見つけたんだけど、どう使っていいのかよく分からず。とりあえずheartbeatパッチで何とかなったのでよし。


OSX Update SSH Keepalive Patch | Outlandish Josh
↑が気になりつつ作業してたんだけど、よく分からない。

color*を入れてみた

残念ながらMacPortsではcolordiffしか見当たらない。"port search color"じゃ駄目?

colordiffをMacPortsでインストールして、colorsvnをソースからコンパイル。/etc/colorsvnrcでIと?がblackになっていたので、~/.colorsvnrcで両方ともwhiteに変更(コンソールが黒字なので)。

(PEAR::DBの)SQLエラーでクエリの長さによってはbacktraceのデータでmemory_limitを超えてFatalエラー。

PEAR_Errorのskiptraceプロパティを利用してdebug_backtraceを省略可能。
PEAR::getStaticProperty()

require_once 'PEAR.php';
$isSkiptrace = &PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
$isSkiptrace = true;

第1引数でクラス名、第2引数でプロパティ名を指定してプロパティへのリファレンスを得る。後はリファレンスを利用して値を設定。

『長過ぎるSQL』の時点で設計ミス?実行環境によって適切なデバッグ設定をするのがマナー?PHPのコンパイルオプション間違ってる?

間違ってるかもだけど、try&errorの結果。

  • PHPUnit3
  • Testing_Selenium-0.2.1(alpha)
  • SeleniumRC0.9.0

上記パッケージ群で動作を確認。

PHPUnit3とTesting_Seleniumを準備。

~/% sudo pear uninstall PHPUnit
~/% sudo pear uninstall PHPUnit2
~/% sudo pear channel-discover pear.phpunit.de
~/% sudo pear install -a phpunit/PHPUnit
~/% sudo pear install -a Testing_Selenium-alpha

SeleniumRC0.9.0をダウンロードして展開。selenium-server.jarを実行(オプションなどは任意)。selenium-server.jarはjetty(httpサーバ?)で動作する模様(org.mortbay.jetty.Server)。

 ~/% java -jar /path/to/selenium-server.jar

OSXでsafariを使ったテストには失敗するも、firefoxにしたら問題なくなったのはなんだろう?

PHPUnit3をインストールして、SeleniumRCとSeleniumCoreを用意したけど上手く動かない。

-interactiveでサーバを動かしてコマンドを実行する分には問題は無い感じ。

で、PHPUnit3(+ Testing_Selenium-0.2.1)でテストケースを書いて試してる最中なんだけど、どうも上手く行かない。

setUpは上手く行っているようで、setBrowserとsetBrowserUrlに従ってブラウザは立ち上がる。最初、SeleniumCoreを用意していなくて、『"/selenium-server/core/RemoteRunner.html"がない』なメッセージが出て来たけど、SeleniumCoreを該当箇所に置いて解決。

しかし、書いてあることは少し違うんだけどね。つーか、PEARにあがっているのは、Selenium RC 0.8.1版で、OpenQAにあがっているのは、0.9.1版。早くPEAR用のをアップロードしなきゃ。
ようやく、Testing_SeleniumがSelenium RCに組み込まれたようだ。(いや、もう少し。。訂正) at GANCHIKU.com

Testing_Seleniumは"pear install Testing_Selenium-alpha"で入れたので、SeleniumRC0.8.1を使って再チャレンジ。"/selenium-server/core/SeleneseRunner.html"を使うようになってる。。。SeleniumCore0.8.0に入れ替えて再チャレンジ。駄目。

サーバの立ち上げ方とか、実行環境に問題があるのかな?PHPUnitを実行しても停止しちゃうからすぐに終了してたんだけど、どうもずっと接続待ちかなんかしてるっぽい。ほったらかしてたら、実行時間が06:11でレポートされてた。ページ開いてタイトルのアサーションするだけのテストが1つあるだけなのに。

まあ、のんびりtry&errorで進めましょう。使いどころがあるわけでもないし。


、、、setBrowsserで*safariから*firefoxに変えたらすんなり動いた。

*firefoxにしたらSeleniumCoreを置かなくても大丈夫だった。Safariの時に何かが起きてる?

setUp内でsetHostを指定して、LANの別マシンからPHPUnitを実行しても動く事を確認。

SeleniumRC楽しそう

いまいち何をするものか分からず避けて来たんだけど、何となく楽しそう。

Seleniumサーバが立ち上がっているマシン上でブラウザを立ち上げてSeleniumテストを実行可能らしい。ここで実行するSeleniumテストは各種プログラミング言語用ドライバを利用したものでもいいし、通常のHTMLファイルでも可能らしい。

PHPUnitでSeleniumテストを書けるようなので、全てのテストをPHPで書けるわけだ。実行もCUIで完結。

テスト構成が原因な気がするんだけど、通しテストを実行するとFirefoxが数百MBのメモリを消費するので、テスト実行中は他の作業をしにくい。なので、リモートデスクトップとかVNCとか必要とせずに別マシンでSeleniumテストを実行出来るのは嬉しい気がする(SeleniumRCでなくてもリモートマシン上のスクリプトを実行する仕組みを使えばいいのかな?)。

まだいまいちわからないんだけど、使いこなせたらCI(継続的インテグレーション)とか楽になりそうな気がしないでもない。

現段階で調べた事を整理したのが以下。
koshigoe hiki - [Selenium]SeleniumRC
まだHTTPS周りとかHTAがどうとかといった情報は未確認。色々と嘘を書いてある危険性があるので注意。

Firefoxで、RSSアイコンがアドレス欄に表示される時に、合わせてアドレス欄自体の背景色も変えたい。

『RSSを提供してます』とか書いてあっても気づけないんです。。。

自宅macではブラウザの横幅を1920位にしてるし、サイドバーを右に置いてるしで、アドレス欄の右端とか結構目に付かない。

テーマが悪いのかな?設定でかえられたりするんだっけ?userChrome?

アドレス欄じゃなくても気づき易いところに変化があればいい。ページを開くたびに右端を確認する習慣は身につけられそうも無い。タブの色を変えたらいいのかな?

どうしたもんか。

復習というか、ちょっと考えてみて思い出してみる。

  • メディアファイルのアーカイブAPIとしてFeedを使おう
  • iPodと連携してメディアファイルを持ち運ぼう
  • 例えばラジオ
  • 定期的に音声ファイルが作られるから、そのリストをFeedで作ろう
  • Feedをsubscribeしたら定期的にコンテンツをダウンロードできるね
  • iTunesに登録出来るからiPodで持ち運べるね(オフラインのプレイヤーに忍び込む?)

text-feedならdescription流し読みで捌けるけど、media-feedってその辺どうよ?

  • descriptionにダイジェストをテキストで書かせる?
  • 割り切ってだらだら聞いたら?
  • リアルタイム性を諦めて、誰がつけるか分からないけど人気度とか評判で判断したら?
  • 割と趣味が合うfeed見つけたら、その時に登録したら?

メディアファイルのプレイリストをFeedで提供したらPodcasting?

  • OpenSearchとか
  • プレイヤー次第で認証できないね(課金は諦め?)
  • 広告を挟むとか
  • プレイリストの生成条件次第でコンテンツマッチ?
  • あれ、Googleとかのメディアファイル検索結果をmedia-feedで取得出来たっけ?

放送局に縛られる事無くコンテンツを配信出来るなら、media-feedを取得出来る検索エンジンに拾われるようにコンテンツを配置する事はありだよね。まあ、それが信憑性とか信頼性があるコンテンツかどうかは微妙だけどさ。

メディアファイルの権利関係がよく分からないので、「Feedで情報出しといたら色々と流入経路とか露出とか増えるみたいよ」と言えるのか分からない。

というわけで、Podcastingは個人的に鬼門な感じなので、このくらいで挫折。

Podcastingで過去に配信されたバックナンバーってどうやって管理してるんだ?

OpenSearchとか使ってpagination?MTベースならPaginatedFeedプラグイン使えばいけるかな。

広告を挟むとかするなら、媒体が多い方がいい気がする(言い方変かな)。検索結果っぽくしたら、いろんな切り口のmedia-feedが出来るし、コンテンツマッチっぽく出来るかも。勿論、いつからいつまでに配信されたものとかって切り出し方もありだろうし。

Podcastingは使ってないんだけど、提供場所次第でいろんな手段を講じてるのかな?

久しぶりに『Podcasting』っていう言葉を聞いてふと疑問に思いました。


ポッドキャスティング - Wikipediaに色々リンクがあるね。

SPLのドキュメントを読んでみたついでに、Splを冠すクラスをもう1つ触ってみた。
SPL-StandardPHPLibrary: SplFileObject Class Reference

<?php
 
$file = new SplFileObject("splfileobject.csv");
//$file->setCsvControl("\t", "");
 
while ($file->valid()) {
    echo var_dump($file->fgetcsv("\t", '"'));
    $file->next();
}
 
/** input(TSV; タブ文字+スペース文字で区切ってます)
a	 b	 c	 d	 e	 f	 g
1	 2	 3	 4	 5	 6	 7
 */
/** output
array(7) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
  [4]=>
  string(1) "e"
  [5]=>
  string(1) "f"
  [6]=>
  string(1) "g"
}
array(7) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
  [3]=>
  string(1) "4"
  [4]=>
  string(1) "5"
  [5]=>
  string(1) "6"
  [6]=>
  string(1) "7"
}
 */
 
?>

ファイル操作のための自作クラスを作った記憶があるんだけど、これ使った方が楽かな?

CSV処理関数を使った事が無かったんだけど、デリミタとエンクロージャを指定して、行を配列に展開出来るんだね。SplFileObject#fgetcsvの特徴なのか、組み込み関数のfgetcsvでも同じなのか分からないけど、エンクロージャに空文字('')は指定出来なくて、エンクロージャ無しの場合はデフォルト('"')で大丈夫らしい。あと、多分フィールドはtrimされてるね。

SplFileObject#setCsvControlが使えなかったんだけど、typoしてたかな?

久々にSPLのドキュメントを見てみた。

This container allows to store objects uniquly without the need to compare them one by one. This is only possible internally. The code represenation here therefore has a complexity of O(n) while the actual implementation has complexity O(1).
SPL-StandardPHPLibrary: SplObjectStorage Class Reference

SplObjectStorageは前からあるんだっけ?"Since PHP6.0"って書いてあるけど、5.1.6でも使えた。オブジェクトをユニークに保持して、イテレータとして使える、と。

$storage = new SplObjectStorage();
$a = new Hoge("a");
$b = new Hoge("b");
$c = new Hoge("c");
echo "check attach:\n";
var_dump($storage->attach($a));
var_dump($storage->attach($a));
var_dump($storage->attach($b));
echo "check count:\n";
echo $storage->count() . "\n";
echo "check contains:\n";
var_dump($storage->contains($a));
var_dump($storage->contains($b));
var_dump($storage->contains($c));
echo "check iteration:\n";
$storage->rewind();
while($storage->valid()) {
  echo $storage->current()->id;
  $storage->next();
}
echo "\n";
echo "check detach:\n";
var_dump($storage->detach($a));
var_dump($storage->detach($b));
var_dump($storage->detach($c));
class Hoge{
  public $id;
  public function __construct($id) {
    $this->id = $id;
  }
}
/** output
check attach:
NULL
NULL
NULL
check count:
2
check contains:
bool(true)
bool(true)
bool(false)
check iteration:
ab
check detach:
NULL
NULL
NULL
**/

ドキュメントのdescriptionは、『O(1)で実現すべきだけど、今のところO(n)ですよ』って事かな?ZFにもオブジェクトのユニークな管理機構があったと思うけど、あれはSplObjectStorageを使ってなかった気がする。

これも使いどころが分からず。

ChangeLogを見てたら気になる箇所が。

Added DomDocument::$recover property for parsing not well-formed XML Documents. (Christian)
PHP: PHP 5 ChangeLog

DomDocumentとあるけどDOMDocumentのtypo(?)だろうという事で、DOMDocumentでテスト。

<?php
 
$input  = basename(__FILE__, ".php") . ".xml";
$output = basename(__FILE__, ".php") . "_output.xml";
 
$doc = new DOMDocument();
 
echo "==> DOMDocument::recover = false(default).\n";
$doc->loadXML("<parent>hoge<child></parent>foo</child>");
echo $doc->saveXML() . "\n";
 
echo "==> DOMDocument::recover = true.\n";
$doc->recover = true;
$doc->loadXML("<parent>hoge<child></parent>foo</child>");
echo $doc->saveXML() . "\n";
 
?>
==> DOMDocument::recover is false.

Warning: DOMDocument::loadXML(): Opening and ending tag mismatch: child line 1 and parent in Entity, line: 1 in not_well_formed_xml_parser.php on line 8

Warning: DOMDocument::loadXML(): Opening and ending tag mismatch: parent line 1 and child in Entity, line: 1 in not_well_formed_xml_parser.php on line 8

<?xml version="1.0"?>

==> DOMDocument::recover is true.

Warning: DOMDocument::loadXML(): Opening and ending tag mismatch: child line 1 and parent in Entity, line: 1 in not_well_formed_xml_parser.php on line 12

Warning: DOMDocument::loadXML(): Opening and ending tag mismatch: parent line 1 and child in Entity, line: 1 in not_well_formed_xml_parser.php on line 12

<?xml version="1.0"?>
<parent>hoge<child/>foo</parent>

出来てるのか?一応、recoverプロパティをfalse/trueで切り替えてloadXMLし直してるんだけど、微妙。どういう修復ルールが正しいんだ?そもそも、検証方法(上記の確認スクリプト)が正しいのかよく分かりません。

さて、これの出番はあるだろうか?

何事?

以下、LDRで購読しているCNET Japanのフィードより抜粋。キャプチャはめんどいのでコピペ。

 BCNテストさせて yana
元記事 | 1時間前
ほげほげ24時間いないでしょお
投稿: 2006/12/02 10:35:48
記事テス
元記事 | 1時間前
てすと
投稿: 2006/12/02 10:35:48
フィードテスト用海外記事2
元記事 | 1時間前
テスト投稿にそろそろ飽きてきてしまいました。
投稿: 2006/12/02 10:35:48
フィードテスト用国内記事2
元記事 | 1時間前
あれっ??今日って28日だっけ?ってことは今週末は!!やつがくるんですねぇ!がgだshdじゃsdhfはsdf
投稿: 2006/12/02 10:35:48
フィードテスト用海外記事1
元記事 | 1時間前
よーしいってみよーーー、海外記事だこらーーもんくあっかーーー
投稿: 2006/12/02 10:35:48
フィードテスト用国内記事1
元記事 | 1時間前
フィードテスト用国内記事1:CMSv3移行も佳境に入って参りました。移行は無事完了するのか?それとも・・・
投稿: 2006/12/02 10:35:48
インテルのCore 2 Duoがクリスマスツリーに--アキバにCPU2000個を使ったツリー登場 (com-test)
元記事 | 1時間前
インテルとつくばエクスプレス(TX)のコラボレーションにより、約2000個の実物CPUで装飾したクリスマスツリーが秋葉原に登場した。
投稿: 2006/12/02 10:35:48
インテルのCore 2 Duoがクリスマスツリーに--アキバにCPU2000個を使ったツリー登場 (biz-test)
元記事 | 1時間前
インテルとつくばエクスプレス(TX)のコラボレーションにより、約2000個の実物CPUで装飾したクリスマスツリーが秋葉原に登場した。
投稿: 2006/12/02 10:35:48
ふぃーど:そーすCNET Japan
元記事 | 1時間前
ふぃーど:そーすCNET Japan(異常系試験)。そういうわけで、猫を飼いたい。
投稿: 2006/12/02 10:35:48
ふぃーど:そーすNews.comだけど、コラムなの
元記事 | 1時間前
ふぃーど:そーすNews.comだけど、コラムなの(異常試験)。これは、ニュースじゃないから、フィードされないで欲しい。猫の戦いの続き。
投稿: 2006/12/02 10:35:48
ふぃーど:そーすZDNet Australia
元記事 | 1時間前
ふぃーど:そーすZDNet Australiaの正常系試験。近所の猫の話の続きです。
投稿: 2006/12/02 10:35:48
ふぃーど:そーすZDNetUK
元記事 | 1時間前
ふぃーど:そーすZDNetUKのニュース(正常試験)
投稿: 2006/12/02 10:35:48
ふぃーど:そーすNews.com
元記事 | 1時間前
ふぃーど:そーすNews.comの正常試験。
投稿: 2006/12/02 10:35:48
インタビューcom yana
元記事 | 1時間前
サマリを変更
投稿: 2006/12/02 10:35:48
画像テスト - 20061120
元記事 | 1時間前
Short Summary:テスト
投稿: 2006/12/02 10:35:48
てすと
元記事 | 1時間前
ててすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとてすとすと
投稿: 2006/12/02 10:35:48
インタビューテスト
元記事 | 1時間前
インタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテストインタビューテスト
投稿: 2006/12/02 10:35:48
C+Z 2
元記事 | 1時間前
適当で作ってみる適当で作ってみる適当で作ってみる適当で作ってみる適当で作ってみる適当で作ってみる適当で作ってみる適当で作ってみる適当で作ってみる
投稿: 2006/12/02 10:35:48
番号ポータビリティ開始で見えたケータイ需要の変化
元記事 | 1時間前
ソフトバンクモバイルの顧客管理システムダウンという、まさしく「予想外」でスタートを切った番号ポータビリティ(MNP)商戦。少しずつ傾向が出てきており、ケータイに対する需要の変化が起きていることがうかがえる。
投稿: 2006/12/02 10:35:48
がんばれ藤本くん(test)
元記事 | 1時間前
がんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれーがんばれがんばれー
投稿: 2006/12/02 10:35:48
あっぷるてすと
元記事 | 1時間前
てすとっす
投稿: 2006/12/02 10:35:48
【12】C(ニュース)+C(イベント)+Z(ニュース)+CVV(ニュース)
元記事 | 1時間前
【12】C(ニュース)+C(イベント)+Z(ニュース)+CVV(ニュース)
投稿: 2006/12/02 10:35:48
【11】Z+C(インタビュー)
元記事 | 1時間前
【11】Z+C(インタビュー)
投稿: 2006/12/02 10:35:48
【10】C+Z(インタビュー)
元記事 | 1時間前
【10】C+Z(インタビュー)
投稿: 2006/12/02 10:35:48
【3】C、Z
元記事 | 1時間前
【3】C、Z
投稿: 2006/12/02 10:35:48
(9)CVV,C,Z
元記事 | 1時間前
(9)CVV,C,Z
投稿: 2006/12/02 10:35:48
(7)CVV,C
元記事 | 1時間前
(7)CVV,C
投稿: 2006/12/02 10:35:48
【6】Z、C、CVV
元記事 | 1時間前
【6】Z、C、CVV
投稿: 2006/12/02 10:35:48
【5】Z、C
元記事 | 1時間前
【5】Z、C
投稿: 2006/12/02 10:35:48
【4】C、Z、CVV(2)
元記事 | 1時間前
【4】C、Z、CVV(2)
投稿: 2006/12/02 10:35:48
【1】C、CVV
元記事 | 1時間前
【1】C、CVV
投稿: 2006/12/02 10:35:48
yana test
元記事 | 1時間前
aaa
投稿: 2006/12/02 10:35:48
新着記事チェック15
元記事 | 1時間前
新着記事チェック15
投稿: 2006/12/02 10:35:48
新着記事チェック14
元記事 | 1時間前
新着記事チェック14
投稿: 2006/12/02 10:35:48
新着記事チェック13
元記事 | 1時間前
新着記事チェック13
投稿: 2006/12/02 10:35:48

これが本当に中の人のテストなら神経疑う。


注)netaカテゴリーに入れてあるけど、捏造ではありません。

プロフィール

このアーカイブについて

このページには、2006年12月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2006年11月です。

次のアーカイブは2007年1月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。