2GBのSDカード買って意気揚々と歓迎会に突撃したらカメラごと持って帰るのを忘れて生きていくのがつらくなったjokagiです. ガジェットには名前と連絡先をお忘れなく.
さてウェブアプリケーションの開発をしていると当然ですがブラウザーで画面の確認をしたりしますが,ブラウザーで確認をしているとキャッシュに悩んだり面倒くさいことが少なくありません. 普通そういう時はtelnetなどで直接HTTPプロトコルでウェブサーバーと会話するわけですが面倒くさいですよね.
$ telnet www.yahoo.co.jp 80 Trying 203.216.231.160... Connected to www.yahoo.co.jp. Escape character is '^]'. GET / HTTP/1.1 Host: www.yahoo.co.jp HTTP/1.1 200 OK Date: Tue, 13 Feb 2007 10:10:41 GMT P3P: policyref="http://privacy.yahoo.co.jp/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" Expires: -1 Pragma: no-cache Cache-Control: no-cache Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=euc-jp 10fff <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=euc-jp"> <!----> (略)
jokagiは何年か前に偶然見つけたGETというコマンド(HEADもよく使う)を使用していますので,このコマンドの紹介と超簡単なハックをひとつ紹介したいと思います.
GETコマンドの使い方
GETコマンドの使い方は--helpしてみましょう.
$ GET --help Unknown option: help Usage: GET [-options] <url>... -m <method> use method for the request (default is 'GET') -f make request even if GET believes method is illegal -b <base> Use the specified URL as base -t <timeout> Set timeout value -i <time> Set the If-Modified-Since header on the request -c <conttype> use this content-type for POST, PUT, CHECKIN -a Use text mode for content I/O -p <proxyurl> use this as a proxy -P don't load proxy settings from environment -H <header> send this HTTP header (you can specify several) -u Display method and URL before any response -U Display request headers (implies -u) -s Display response status code -S Display response status chain -e Display response headers -d Do not display content -o <format> Process HTML content in various ways -v Show program version -h Print this message -x Extra debugging output
大体で言うと-m,-c,-p,-Hを覚えておくとよいです.後はDisplay~となっている系のオプション. 例えばhttp://www.yahoo.co.jp/のコンテンツを取得するのはこんな感じで行います.
$ GET 'http://yahoo.co.jp/' | head <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=euc-jp"> <!----> <title>Yahoo! JAPAN</title> <meta name="description" content="80??"> <style type="text/css" media="all"> <!-- .spacer { line-height: 110%; } .spacer1 {line-height: 115%; }
GETを使うと簡単にコマンドラインでいろんなウェブ関連の処理ができます. 下記はgo-pear.org(pear.php.net)からPEARのインストーラーをダウンロードしてインストール作業を行う例です.
$ GET 'http://go-pear.org/' | php -q Welcome to go-pear! Go-pear will install the 'pear' command and all the files needed by it. This command is your tool for PEAR installation and maintenance. Go-pear also lets you download and install the PEAR packages bundled with PHP: MDB2. If you wish to abort, press Control-C now, or press Enter to continue:
ウェブサービスへのアクセスも簡単です. 下記はフォト蔵からキーワードmasatoで検索をする例です.
$ GET 'http://api.photozou.jp/rest/search_public?type=photo&order=date&keyword=masato' | head <?xml version="1.0" encoding="UTF-8" ?> <rsp stat="ok" ><info ><photo ><photo_id>2166156</photo_id ><user_id>137</user_id ><album_id>220281</album_id ><photo_title>P1140118</photo_title ><favorite_num>0</favorite_num ><comment_num>0</comment_num
-m覚えようぜ!!といいつつ,実は-mに相当するコマンドがそれぞれHEAD,POSTとして用意されています.
$ rpm -qlf /usr/bin/GET | grep bin /usr/bin/GET /usr/bin/HEAD /usr/bin/POST /usr/bin/lwp-download /usr/bin/lwp-mirror /usr/bin/lwp-request /usr/bin/lwp-rget
ようするにコマンド名イコールHTTPリクエスト方法(-mオプション)になります. ウェブアプリケーションでは通常GET,POST,HEADしか使わないので(HEADも開発中でもなければ使う機会は少ないかも),これだけで十分作業ができます(以後これらのコマンド群はまとめてGETコマンドとします).
GETコマンドはBasic認証に対応しているので,いちいちBasic認証情報をBase64エンコードしたりしなくてもいいことも特徴のひとつでしょう(ただし毎回認証情報を質問されるので,うっとおしければ-Hで自分で指定する必要があるかもしれません).また,基本的にキャッシュなどの機構はないので,ブラウザーで確認するほどキャッシュに振り回されることがありません.
また,HEADコマンドを使えば(HEADじゃなくてもできるけど)簡単にサーバー側からの送られてくるHTTPレスポンスヘッダーを確認することができます.
$ HEAD 'http://www.yahoo.co.jp/' 200 OK Cache-Control: no-cache Connection: close Date: Tue, 13 Feb 2007 09:24:38 GMT Pragma: no-cache Content-Type: text/html; charset=euc-jp Expires: -1 Client-Date: Tue, 13 Feb 2007 09:24:38 GMT Client-Peer: 203.216.247.225:80 Client-Response-Num: 1 P3P: policyref="http://privacy.yahoo.co.jp/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"
残念ながらGETコマンドも注意点があります.
- 動作環境にインストールされているCPANパッケージの具合によってはhttpsが使えない(ぽい)
- Locationなどで別ページに飛ばせる処理はリダイレクト先の情報(コンテンツ)が出力される
この辺をうまく使うことでウェブサーバーを経由したユニットテストも可能になるかもしれません. またちょっとしたハックでWebDAVなどで必要なPROPFINDなどの対応もできるようになります. やり方はいくつかあると思いますが,jokagiは下記の手順でやってみました.
-
/usr/bin/GETを適当なパスにコピーする
$ mkdir -p ~/bin/ $ cp -pr /usr/bin/GET ~/bin/PROPFIND
- viなどでファイルを開き(ただのperlのスクリプトです)検索で「GET」を探し,それっぽくPROPFINDを追加する
%allowed_methods = ( GET => "", HEAD => "", POST => "C", PUT => "C", DELETE => "", TRACE => "", OPTIONS => "", PROPFIND => "", ←これを追加する );
これでPROPFINDとして使用できるようになります. 下記はその実行例です.
$ PROPFIND http://192.168.0.1/webdav/foo.txt Enter username for Authorization at 192.168.0.1:80: user Password: <?xml version="1.0" encoding="utf-8"?> <D:multistatus xmlns:D="DAV:"> <D:response xmlns:ns0="DAV:" xmlns:ns1="urn:schemas-microsoft-com:" xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/"> <D:href>/webdav/foo.txt</D:href> <D:propstat> <D:prop> <ns1:Win32CreationTime>Wed, 13 Dec 2006 07:06:38 GMT</ns1:Win32CreationTime> <ns1:Win32LastAccessTime>Wed, 13 Dec 2006 07:06:38 GMT</ns1:Win32LastAccessTime> <ns1:Win32LastModifiedTime>Wed, 13 Dec 2006 07:06:38 GMT</ns1:Win32LastModifiedTime> <ns1:Win32FileAttributes>00000000</ns1:Win32FileAttributes> <lp1:resourcetype/> <lp1:creationdate>2006-12-13T07:07:42Z</lp1:creationdate> <lp1:getcontentlength>0</lp1:getcontentlength> <lp1:getlastmodified>Wed, 13 Dec 2006 07:07:42 GMT</lp1:getlastmodified> <lp1:getetag>"1ed52e-0-e08ab80"</lp1:getetag> <lp2:executable>F</lp2:executable> <D:supportedlock> <D:lockentry> <D:lockscope><D:exclusive/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> <D:lockentry> <D:lockscope><D:shared/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock> <D:lockdiscovery/> <D:getcontenttype>text/plain</D:getcontenttype> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> </D:multistatus>
コピーでなくシンボリックリンクでもいいのですが,パッケージのアップデートの影響をもろ受けること,/usr/bin/直下を直接いじりたくないと思ったからです. perlがわかる人はそんなことしなくてもさくさくうまいやりかたでやると思います(コメントとかトラックバックとかで情報ください).
通常はwgetやcurlでも問題ないかもしれませんが,GETコマンドはできることがシンプルなのですぐに使いこなせると思います. また,WebDAVを使う人は今回のハックはちょっと開発効率アップに貢献するかもしれません. 一度使うと常用するようになってしまうのでぜひお試しください. それではあでゅー.