へぼい日記
javascriptからsocketが扱えるJSocketを作りました
- 2009/10/20 火曜日 0:18:49
- javascript
javascriptからsocketを扱いたいなぁという事象が発生したんですが(それについては別エントリで)、SocketJSというのがあるんですがDownloadするところがなぜかSSLになっていてCAがCAcertでfirefoxだとデフォルトでは見れないので、かっとなって自分で作ってみました。今も反省していません。
コードはgithubからどうぞ。
使い方はjs/jsocket.jsに軽く書いてあります。
/* * Jsocket - Socket on Javascript * Author: Masahiro Chiba <nihen@megabbs.com> * Depends: * - jQuery: http://jquery.com/ * - jQuery TOOLS - Flashembed: http://flowplayer.org/tools/flashembed.html * SYNOPSIS: * JSocket.init('/static/JSocket.swf', function () { * socket = new JSocket({ * connectHandler: connectHandler, * dataHandler: dataHandler, * closeHandler: closeHandler, * errorHandler: errorHandler * }); * socket.connect(location.hostname, location.port || 80); * }); * function connectHandler() { * socket.write("GET / HTTP/1.0\x0D\x0A\x0D\x0A"); * socket.flush(); * } * function dataHandler(data) { * alert(data); * socket.close(); * } * function closeHandler() { * alert('lost connection') * } * function errorHandler(errorstr) { * alert(errorstr); * } * * */
こんな感じですね。flashの力を借りているので、Flashのソケットポリシーファイルとかを参考にポリシーファイルを配布するサーバを立ち上げておいてから使ってください。まる。
mod_psgi試してみた
- 2009/10/16 金曜日 18:17:20
- perl
mod_psgi をインストールしてみたをみて速くなるなら試してみようということでmod_psgiを試してみますた。
まずはこんな感じの簡単なPSGIアプリで。
my $app = sub { return ['200', [Content-Length => '5'], ['hello']]; };
ab -n 10000 -c 100 mod_psgi Requests per second: 1403.51 [#/sec] (mean) mod_perl Requests per second: 668.33 [#/sec] (mean) Standalone Requests per second: 702.46 [#/sec] (mean) Standalone::Prefork Requests per second: 725.78 [#/sec] (mean)
おおおお。超絶早いですね!
(plackupの際に-E product(development以外ならなんでもおk)をつけないとだいぶ遅くてそれをそのまま載せてたのを修正しました)
で、お次は、Catalyst::Engine::PSGIを使ってCatalystのhello worldなアプリを。
catalyst.pl Hello
で作って、debugモードを切って、Root.pmのindexで
$c->response->content_type('text/plain'); $c->response->body( 'hello' );
こんな感じにしたもの。
ab -n 1000 -c 10 mod_psgi Requests per second: 207.87 [#/sec] (mean) mod_perl Requests per second: 144.94 [#/sec] (mean) cat-standalone Requests per second: 184.95 [#/sec] (mean)
おおおおお。早いですね!!これはこれだけでも乗り換える意味がありそうだ。と思ってたんですが現在実運用中のCatalystアプリでやってみたところ”child pid 32320 exit signal Segmentation fault (11)”とかいって死にました。うーむ。これは再現する最小構成を探ってid:spiritlooseさんにフィードバックしたいところですね。
casual-perlerな人たちは今持ってるCatalystアプリをmod_psgi+Catalyst::Engine::PSGIで動かしてどんどんフィードバックするといいんじゃないかな!
Archer and Git
- 3:17:31
- git
最近会社のレポジトリ管理も順次gitに移行しようとしてるのですが、今までArcher&svnでデプロイしていたものをgit用にarcher.ymlを書き換えしてみた。
汎用的にはこんな感じ。中央サーバのレポジトリにreleaseというブランチを作っておいて、作業者もそれの追跡ローカルブランチなreleaseを作っておくというのが前提。releaseに直接コミットは厳禁。
git stash saveがあるから作業ディレクトリを別に用意する必要ないかなぁとか思ってこんな形にしてみた。今のところ満足してるけど運用しているうちになんか不具合がでるかもしれない。
Acme::Coro::Sukeをリリースしました
- 2009/10/12 月曜日 15:44:51
- perl
多分、5人以上の人が思いついたけどあまりのくだらなさに作成を断念したといううわさのAcme::Coro::Sukeを先ほどCPANにリリースしました。(githubにもあげてあります)
これは、Coroのasyncと基本的には同じ動作をするbenzoというブロック定義ができるようになるもので、benzoブロックにCoroがスレッドを切り替えるたびに、「うわぁ…べんぞうさんの中…すごくあったかいナリぃ… 」とコロちゃんが囁やいてくれるモジュールです。
一番簡単な使い方は以下のようになります。
use Coro; use Acme::Coro::Suke; benzo { }; cede;
enjoy Acme::Coro::Suke!
CPANに上げる三つめのモジュールがAcmeモジュールというのはこれはひどい。
Re: PSGI Implのsendfileについて
- 2009/10/7 水曜日 15:29:06
- perl
PSGI Implのsendfileについてですが、自分の今のところのイメージを書いておくです。
on Plack::Server
- $res->[2]がGLOBだったら fileno($res->[2])して sendfile に fd を渡す
- $res->[2]->can(‘fileno’) が生えてたら、$res->[2]->filenoからfdを取って使う
- $res->[2]->can(‘path’) が生えてたら、$res->[2]->pathからファイルパスを取って使う
$env->{psgix.sendfile}を使わない以外は一緒
on app
realfileをserveしたい時は
- GLOBを返す
- ->pathを生やしたIO-Handle-likeなオブジェクトを返す
の二種類の方法があって、後者のほうがあらゆるサーバで最適化される可能性がある。かといって前者だからといってクライアントに届くresponseが変わることはないと期待される。後者において->filenoの実体のファイルと->pathが違うものだった場合の動作は未定義。
on middleware
- Plack::Middleware::XSendfile
responseから->pathが取れる場合にはそれをヘッダのX-Sendfileにセットするようなmiddleware。これのpsgix.sendfileサポートを無くしたやつのイメージ。
X-Sendfileヘッダをセットする場合というのはbackendがlightyの場合とかだと思うけど、それをセットしていいかどうかはPlackは知り得ない。かといってappでセットしていて必要のない時に外にファイルPATHが出ていくものいくない。というわけでappでは->path付きオブジェクトを返すだけにして、このmiddlewareをbackendにあわせて付けたり外したりする。Plack::Server::*のsendfile(2)サポートとかとはまったく関係無い。 - Plack::Middleware::GuessPath
GLOBからファイルPathを推測して->path付きのオブジェクトに変換しちゃうMiddleware。マルチプラットフォーム対応が課題。Plack::Middleware::XSendfileより先に実行する。Plack::Server::*のsendfile(2)サポートとも関係する。
追記(10/7 17:24): 大体ここに書いてある感じで追加されたみたいです。詳しくは本家specのchangesetをご覧ください。Plack::Middleware::XSendfileも追加されたみたいです。miyagawaさん仕事ハヤス、、、。
ファイルPATHを覚えているfhを作成できるIO::File::WithPathをリリース
- 1:49:30
- perl
Plackのsendfileサポート関連を追いかけてて、Plack::Server::Apache2でsendfileサポートされてない理由がfhからファイル名を取るベストな方法がないというわけで、gist: 200797みたいなパッチを書いて#http-engineとかに張り付けたけどそれlinuxでしか動かないよねみたいなことで日本の恥を晒してしまったりしてたわけですが、その中でIO::File::WithPathみたいなのがあればいいよねと話がでていたので作ってみました。
使い方はこんな感じ。
my $fh = IO::File::WithPath->new('/path/to/file'); print $fh->path; # /path/to/fileがとれるよ print $fh->getline; # IO::Handleとしても扱える print <$fh>; # もちろんGLOBとしても
Plackのappでは
return ['200', [], IO::File::WithPath->new('/path/to/file')];
みたいな使い方を想定していますが、Plack::Server側はこのモジュールを使うことが前提というわけではなくて、duck typingで->pathがあるオブジェクトであればそのpathを(使える条件であれば)使うようになる予定だと思います。
あと、純粋なfhからpathを取るマルチプラットフォーム対応なモジュールもできれば欲しいよねというところ。windowsはかなり無理っぽい。
Plack::Requestからのhostのとりかた
- 2009/9/30 水曜日 21:42:21
- perl
Plack::Requestにhost無いなぁ。と思って勢い余ってforkしてコミットまでしてしまったのですが、#perl-casual@freenodeで呟いたところyappoさんから
$req->uri->host
もしくはURIオブジェクトの作成コストが気になるなら($req->uriは遅延作成なので)
$req->env->{HTTP_HOST}
でいいじゃんと言われました。確かにその通りですね。
Wassrのyapcasia2009チャンネルの発言をIRCに投稿するボットをYAPC::Asiaの二日目向けに作った
- 2009/9/10 木曜日 23:47:54
- perl
twitterの#yapcasia2009ハッシュタグがスクリーンに晒されるのが個人的に非常にツボだったので、wassrのyapcasia2009チャンネルに発言するとirc.freenode.orgの#yapc.asia-jaに投稿するボットも作ってみました。
wassrにはstreaming APIはないようなので5秒ごとにpollingしちゃってます。いいんでしょうか。
参考文献(つうかほぼパクリ):
Twitterのハッシュタグ付き発言をIRCに投稿するボットをYAPC::Asia向けに作った
以下コード
#!/usr/bin/perl use strict; use warnings; use AnyEvent::IRC::Client; use Net::Wassr; use Encode (); use Storable; my $channel = '#yapc.asia-ja'; my $interval = 5; my $wassr_channel = 'yapcasia2009'; my $wassr = Net::Wassr->new( user => 'nihen', passwd => '*****', ); my $cv = AnyEvent->condvar; my $pc = AnyEvent::IRC::Client->new; my $send_message = -e 'send_message' ? retrieve('send_message') : {}; $SIG{INT} = $SIG{TERM} = sub { $pc->disconnect('bye'); store $send_message, 'send_message'; exit; }; $pc->reg_cb( connect => sub { my ( $pc, $err ) = @_; if ( defined $err ) { warn $err; return; } }, registered => sub { my ( $self ) = @_; print "registerd!\n"; $pc->enable_ping(60); }, disconnect => sub { print "disconnected: $_[1]!\n"; } ); $pc->send_srv('JOIN', $channel); $pc->send_chan($channel, 'NOTICE', $channel, 'hi'); $pc->connect('irc.freenode.org', 6667, { nick => 'wassr_bot', user => 'wassr_bot', real => 'wassr_bot', }); my $w = AnyEvent->timer(after => $interval, interval => $interval, cb => sub { my $time_line = $wassr->channel_timeline('name_en=' . $wassr_channel); if ( !$time_line || ref $time_line ne 'ARRAY' ) { return; } foreach my $message ( @{$time_line} ) { next if $send_message->{$message->{rid}}; $send_message->{$message->{rid}} = 1; $pc->send_chan($channel, 'NOTICE', $channel, Encode::encode('utf-8', $message->{user}->{login_id} . ': ' . $message->{body})); } }); $cv->wait;
YAPC::Asia2009の参加トークをわかりやすくするグリモン作ったよ
- 2009/9/9 水曜日 14:40:35
- perl
さて、明日からついにYAPC::Asiaが始まりますね。皆さんは参加されるトークをすでに決められたでしょうか?
参加するトークの詳細ページ(ex.Welcome)でadd to personal scheduleを行うと参加トークの管理ができるようになっているみたいです。ただこれがスケジュール上では確認できなくてちょっと不便だなーと思ったのでわかりやすくするぐりもんを作ってみました。
yapcasia2009myschedule.user.js
です。いれるとスケジュールの表示がこうなります。あ、ログインした状態じゃないと表示されないです。
らくだのマークがわかりやすくて印刷用にも最適ですね!
では、YAPC::Asia会場でお会いしましょうです。
mysqlでskip-character-set-client-handshakeはもう使わないほうがいいと思われ
skip-character-set-client-handshake を [mysqld] セクションに追記すると、クライアントがどんな文字コード設定をもっていようが問答無用で character_set_* を (_system をのぞいて) すべて同じ値に統一してくれる
http://d.hatena.ne.jp/a666666/20090826/1251270979
ふーむ。
skip-character-set-client-handshakeを薦める文書がネット上にはやたら転がってるんだけど、これには大きな落とし穴がある。
たしかに表示されるcharacter_set_*は統一されるかもしれないがこれはあくまでもサーバー側の認識であってクライアント(libmysqlclient)がcharsetをどう認識しているかというのとは関係ないのだ。で、実はlibmysqlclientが認識しているcharsetはcharacter_set_clientとは必ずしも一致しているわけではなくて、これを絶対的に一致させるには以前のエントリでも紹介したがhttp://www.klab.jp/media/mysql/index6.htmlの図3:クライアント側文字コードの指定チャートが参考になる。
skip-character-set-client-handshakeをしただけだと結局libmysqlclientが認識しているcharsetはクライアント側のコンパイル時のcharset(デフォルトではlatin-1)になる。ここで実際に送信するcharsetと乖離が起これば当然組み合わせによってはSQLインジェクションの脆弱性が発生する。id:a666666氏のmysqlはutf8でコンパイルしてujisを送信ということなので脆弱性はなさそうだが(あったら誰か教えてください)、例えばcp932を送信するのであれば以前のエントリと同様に(反対方向だけど)”\xe3\x81\x95\x5c”等が危険な文字列になる。これをlibmysqlclientはUTF-8として認識してエスケープするので”\xe3\x81\x95\x5c\x5c”になるが、サーバー側ではcp932と認識するので”\xe3\x81″ “\x95\x5c” “\x5c”と分割されてしまうという感じだ。
そもそもskip-character-set-client-handshakeなんてのはmysql4.0からの移行組用の臨時救済措置で作られたものだろうし、こんなものを使うことを前提に運用するのはやめたほうがいい。よくいわれている文字コードの変換処理をさせたくない、ということであればフィールドの文字コードと通信の文字コードを統一しておけばいいだけでしょう。
- 検索
- フィード
- メタ情報