というわけで、今回もラジオねたではなく、前回の PerlのCGIからWebサービスにアクセスする の続きで「素のPerlでWebサーバーにアクセスするにはどうするのか?」です。コードはめんどいので正常系のみでいきます。もし実装するときはちゃんとエラー処理もいれてください。
まずは、最初に注意事項として申し上げますが、CGIから他のサーバーにアクセスするようにしていると、そのCGIが大量に呼び出された場合でも、呼び出すサーバーに負荷がかからないようにすべきでしょう。さて、サンプルコードですが、connect()までは、世に存在するこの手のコードと一緒なので、詳細な説明は省きます。基本的にこういうものだと思ってもらって問題ないと思いますが…。
ここで、$host、$portはアクセスするサーバーのホスト名(ドメイン表記でも可)とポート番号です。httpの場合は、普通$portは80になるでしょう。次はサーバーへリクエストを送ります。要するにHTTPプロトコルのGETメソッドを使ってコンテンツを持ってくる方法ということになります。
binmode()はUNIX上では意味はないですが念のため。「$| = 1;」はこれを指定しておかないとバッファに溜まったままで、サーバーに送り出してくれません。最後の「select(STDOUT);」は、デフォルト出力先を元に戻しています。
ここでは、$urlと$hostを指定しなければならないのですが、$hostは前のコードの$hostと同じで基本的にはOKです。$uriは、ここではサーバー内のパス(すなわちURLでhttp://hostname以降に書いてあるもの)を指定します(例えば、「/cgi-bin/test.cgi?param=value」)。
ヘッダーの「Host:」はHTTP/1.1では必須なので省略不可で、あとお好みでヘッダーを追加してください。
$header .= "\r\nUser-Agent: hogehoge";
と、書いてみたりとか。
これで、リクエストは送られましたので、あとは結果を読み込むわけですが、失敗しなければ、「ステータス」と「ヘッダー」と「リクエストの結果(コンテンツ)」が返ってきます。とりあえず、ヘッダーの解析までです。
というような、ちょっと強引なコードですが…。まずステータスコード「200」以外はエラーとみなしていますが、このあとヘッダー、場合によってはコンテンツも送られてきますので、ここはそのまま突っ走ります。たぶん、コードを保存しておいて、最後に処理するのが正しい方法かと思われます。
ヘッダーの内容は後から使うので、連想配列の中に入れておきます。
次にリクエストの結果を取得するのですが、サイズの指定され方によって基本的に3つの方法があります。まずはコード。
このコードもエラーチェックなしなので、このままではどうかと思います。<S>やreadはエラーが起きるとundefを返すので、それをチェックしたほうがよいと思います。最後は、ソケットを閉じます。
できる限り、close(),shutdown()は、connect()成功後、いかなる場合においても実行しておくべきです。
と、いうわけでこれで終わりです。ただし、1つ気になることがあって、それはタイムアウトをどうするのかということです。
思いついた対処の方法としては…。
ブログのトップフリーとラジオ周波数一覧… 2007/08/19 コメント(1)
楽天WEBサービスを使ってCGIを作ろうと思う 2007/01/28
リニューアルなのか?「ブログでスタイル… 2006/11/03