ラベル WEBrick の投稿を表示しています。 すべての投稿を表示
ラベル WEBrick の投稿を表示しています。 すべての投稿を表示

2009年3月18日水曜日

WEBrick/Windowsでのエラーについて

こんにちは、モリモルです。


windowsでwebrickを動かす際に、「cgi_runner.rb:47:in `exec':Exec format error」が出る際のメモ。
こちらを参考にしたら動きました。

:CGIInterpreterを追加すると解消されました。


server = HTTPServer.new(
:Port => "8088",
:BindAddress => "localhost",
:DocumentRoot => DOCROOT,
:CGIInterpreter => %("C:/Ruby/bin/ruby.exe")
)

2009年1月3日土曜日

WEBrick::HTTPServlet::CGIHandlerを使ってみました。

こんにちは、モリモルです。

WEBrickでCGIを動かしてみます。
使い方は、以前の自作サーブレットと同じような感じで、

HTTPServer#mount("URL", HTTPServlet::CGIHandler, "Rubyスクリプトへのパス")

第一引数のURLにアクセスがあるたびに、
第二引数のインスタンスを生成して、HTTPServlet::AbstractServlet#serviceを呼び出すようです。
第三引数のRubyスクリプトはHTTPServlet::CGIHandlerのコンストラクタに引数として渡されます。


では、簡単なCGIを作ってアクセスしてみます。
/var2/www/cgi/foo.rb

1 #!/usr/local/bin/ruby
2
3 require 'cgi'
4
5 cgi = CGI.new
6 print cgi.header({"type" => "text/html", "status" => "OK"})
7 print DATA.read
8
9 __END__
10 <html>
11 <body>
12 <h1>foo.rb</h1>
13 </body>
14 </html>


server.rb

1 #! /usr/local/bin/ruby
2 require 'webrick'
3 include WEBrick
4
5 server = HTTPServer.new(
6 :DocumentRoot => "/var2/www/html",
7 :Port => 20080,
8 :BindAddress => "myhost")
9
10
11 server.mount("/cgi", HTTPServlet::CGIHandler, "/var2/www/cgi/foo.rb")
12
13 trap("INT"){server.stop}
14
15 server.start


ブラウザから“http://192.168.91.128:20080/cgi”にアクセスしてみます。


表示されましたね。

2009年1月2日金曜日

WEBrickで“Cannot assign requested address”

明けましておめでとうございます。モリモルです。

正月休みを利用して、CentOSからUbuntuに乗り換えました。
乗り換えた後のWEBrickサーバーを起動で、“Cannot assign requested address”とエラーが出た際のメモです。

今までは、直接IPアドレスを入れていたのですが、
/etc/hostsに記述してあるホスト名に変更したら問題なく動きました。

server = HTTPServer.new(
:DocumentRoot => "/var2/www/html",
:Port => 20080,
:BindAddress => "myhost")
# :BindAddress => "192.168.91.128")

2008年12月23日火曜日

WEBrick::HTTPServlet::AbstractServletでサーブレットを作ってみました。

こんにちは。モリモルです。
2008年もあと1週間ほど。1年が早く感じます。

前回使ったHTTPFileHandlerが継承している、AbstractServletで簡単なサーブレットを作ってみようと思います。
※実行環境は1.8ですが、今後は参照するリファレンスはRuby1.9にしました(見やすいので。。)



まず、頭の中を整理。。



さて、今回作成するサーブレットにはPOSTメソッドのみ実装します。
(実装されていないHTTPメソッドが送られてくると例外を発生するようです)
サーブレットに送られるHTTPリクエストのBodyには、JPEGファイルが1つだけ添付されます。
サーブレットは、リクエストBodyからJPEGデータを抽出し、HTTPレスポンスのBodyに付けて返します。

まとめると、「フォームからPOSTで画像ファイルを送ると、サーブレットがその画像を返す」という単純なものです。



index.html(フォームページ)

<html>
<body>
<form action="/my_servlet" method="post" enctype="multipart/form-data">
<input type="file" name="img1">
<input type="submit">
</form>
</body>
</html>



server.rb(サーバー用スクリプト)

1 #!/usr/local/bin/ruby
2
3 require 'webrick'
4 include WEBrick
5
6 class MyServlet < HTTPServlet::AbstractServlet
7
8 def do_POST(req, res)
9 p req.query["img1"]
10 res.content_type = "image/jpeg"
11 res.body = req.query["img1"]
12 end

13
14 end
15
16 server = HTTPServer.new(
17 :DocumentRoot => "/var2/www/html",
18 :Port => 20080,
19 :BindAddress => "192.168.207.128")
20
21 server.mount("/my_servlet", MyServlet)
22
23 trap("INT"){server.stop}
24
25 server.start



9行目:HTTPリクエストBodyから画像を抽出して標準出力してます。やる意味はありませんが試しにいれました。
10行目:HTTPレスポンスヘッダのContent-Typeを指定。
11行目:HTTPレスポンスのBodyに画像データを代入。

では、ブラウザから"/my_servlet"へJPEGファイルをPOSTしてみます。





画像が表示されました。

9行目の標準出力の結果です。
文字列に変換するとつぎのようになります。
10行目のContent-Typeを適切に指定しないと、ブラウザ側はJPEGとして認識してくれません。

このデータをFile.open("foo.jpg", "w"){|file| file.write(req.query["img1"])}とかでサーバーに保存できるようです。

2008年12月22日月曜日

WEBrick::HTTPServlet::FileHandlerでエイリアス?を加えてみました。

こんにちは。モリモルです。

前回はWEBrick::Logでログをファイルに出力しました。
今回は、WEBrick::HTTPServlet::FileHandlerクラスで、Apacheでのエイリアスっぽいものを加えてみようと思います。

FileHandlerは、「通常のファイルサーバとしての機能を提供するためのサーブレット。 」とのことですので、こんな使い方はしないのかもしれませんが、、とりあえずやってみます。

前回からディレクトリ構成を変更しました。
------------------------------------------------------------

var2
`-- www
|-- html
| `-- index.html <----DocumentRoot
|-- image
| `-- foo.jpg
`-- logs
`-- log

------------------------------------------------------------
DocumentRootをwww/htmlにして、画像フォルダwww/imageを/imageでエイリアスしてみたいと思います。



www/html/index.html
------------------------------------------------------------

1 <html>
2 <body>
3 <img src="/image/foo.jpg"> <----/imageでアクセス
4 </body>
5 </html>

------------------------------------------------------------

server.rb
------------------------------------------------------------

1 #!/usr/local/bin/ruby
2
3 require 'webrick'
4 include WEBrick
5
6 logger = Log.new("/var2/www/logs/log", BasicLog::DEBUG)
7
8 server = HTTPServer.new(
9 :DocumentRoot => "/var2/www/html",
10 :Port => 20080,
11 :BindAddress => "192.168.207.128",
12 :Logger => logger )
13
14 server.mount("/image", HTTPServlet::FileHandler, "/var2/www/image")
15
16 trap("INT"){server.stop}
17
18 server.start

------------------------------------------------------------
青色の部分が今回追記した箇所です。
その他ログなどのパスは、適宜変更してあります。
HTTPServer#mountの第一引数で指定したディレクトリで、FileHandlerオブジェクトをマウントしています。
このFileHandlerオブジェクトですが、
/imageにアクセスがあるたびに、HTTPServerオブジェクトがFileHandler.newを呼び出し生成するようです。
その際に、FileHandler.newには、引数としてHTTPServer#mountの第三引数"/var2/www/image"が渡されます。

では、ブラウザからアクセスしてみます。


エイリアスのパスで、画像が表示できました。

WEBrick::HTTPServletには、ほかにも、CGIHandler、ERBHandlerなどがあるようですので、
次回はそちらを試してみようと思います。
ではでは。

2008年12月21日日曜日

WEBrick::Logでロギングしてみました。

こんにちは、モリモルです。

前回はWEBrickでHTTPサーバーを書きました。
今日は、WEBrick::Logクラスを使って、ロギング機能を追加したいと思います。

ディレクトリ構成
------------------------------------------------------------
/var2
|-- logs
 |-- log <----ログを記録するファイル
|-- www
 |-- index.html
------------------------------------------------------------
logsディレクトリ以下は、server.rbを実行するユーザーが書き込める権限が必要です。

前回書いたスクリプトにロギング機能を追記します。

server.rb
------------------------------------------------------------

1 #!/usr/local/bin/ruby
2
3 require 'webrick'
4 include WEBrick
5
6 begin
7 log = File.open("/var2/logs/log", "a")
8 rescue
9 puts "ERROR #{$!.message}"
10 log.close unless log.closed?
11 end
12
13 logger = Log.new(log, BasicLog::DEBUG)

14
15 server = HTTPServer.new(
16 :DocumentRoot => "/var2/www",
17 :Port => 20080,
18 :BindAddress => "192.168.207.128",
19 :Logger => logger )
20
21 trap("INT"){server.stop}
22
23 server.start

------------------------------------------------------------
青い部分が追記した箇所になります。

6~11行目で、ログを記録するファイルオブジェクトを生成。
13行目で、Logクラスのコンストラクタにファイルオブジェクトを渡してLogファイルオブジェクトを生成します。引数の2つ目はどのよなログを記録するかを指定しています。
今回は一番レベルの低い(DEBUG)を指定しました。
19行目で、HTTPServerクラスのコンストラクタに、Logオブジェクトを渡します。


では、サーバーを起動してみましょう。
------------------------------------------------------------

$ > ./server.rb &
$ > tail /var2/logs/log
[2008-12-19 12:30:30] INFO WEBrick 1.3.1
[2008-12-19 12:30:30] INFO ruby 1.8.7 (2008-06-09) [i686-linux]

------------------------------------------------------------
WEBrickの起動がログとして出力されました。

この後、ブラウザからアクセスしてログが出力されるか確認したのですが、出力はされませんでした。

おかしいなぁ。と思い、WEBrickを終了すると一気にログを吐き出しました。
------------------------------------------------------------

$> fg
./server.rb
【ctl + C】で停止
$> tail -20 /var2/logs/log
[2008-12-19 12:30:30] INFO WEBrick 1.3.1
[2008-12-19 12:30:30] INFO ruby 1.8.7 (2008-06-09) [i686-linux]
[2008-12-19 18:13:45] INFO WEBrick 1.3.1
[2008-12-19 18:13:45] INFO ruby 1.8.7 (2008-06-09) [i686-linux]
[2008-12-19 18:13:55] DEBUG TCPServer.new(192.168.207.128, 20080)
[2008-12-19 18:13:55] DEBUG WEBrick::HTTPServlet::FileHandler is mounted on /.
[2008-12-19 18:13:55] INFO WEBrick::HTTPServer#start: pid=2262 port=20080
[2008-12-19 18:46:31] DEBUG accept: 192.168.207.1:2994
[2008-12-19 18:46:51] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
[2008-12-19 18:47:11] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
[2008-12-19 18:47:11] ERROR `/favicon.ico' not found.
[2008-12-19 18:47:11] DEBUG close: 192.168.207.1:2994
[2008-12-19 18:47:21] DEBUG accept: 192.168.207.1:3011
[2008-12-19 18:47:41] DEBUG WEBrick::HTTPServlet::FileHandler is invoked.
[2008-12-19 18:47:41] ERROR `/favicon.ico' not found.
[2008-12-19 18:47:41] DEBUG close: 192.168.207.1:3011
[2008-12-19 18:48:25] INFO going to shutdown ...
[2008-12-19 18:48:25] INFO WEBrick::HTTPServer#start done.

------------------------------------------------------------
どうやら、ログの出力がFileオブジェクトに溜まったままで、WEBrickを終了しないとファイルに出力されなかったようです。
リファレンスにLog.new演算子の第一引数には、「メソッド << が定義されたオブジェクト。普通は String オブジェクトか IO オブジェクト。」と書いてあったので、Fileオブジェクトでいいのかな。と勘違いしていました。
単純にログファイルへのパスを指定すればOKのようです。

13行目を書き直します。(6~11行目は削除)
------------------------------------------------------------

13 logger = Log.new(log, BasicLog::DEBUG)

13 logger = Log.new("/var2/logs/log", BasicLog::DEBUG)

------------------------------------------------------------

これで、再度WEBrickを起動すると、tail -fでログのリアルタイム出力が確認できました。
めでたし。めでたし。

次回は、WEBrick上で、CGIを動かしてみようと思います。

2008年12月20日土曜日

WEBrickでHTTPサーバーを書いてみました。

こんにちは。モリモルです。

今回はRubyに標準添付されている、WEBrickモジュールを使って、HTTPサーバーを作ってみます。

公式リファレンスでは、
「汎用HTTPサーバーフレームワーク。HTTPサーバを簡単に作ることができます。」
とのことです。

WEBrickモジュールを使うと、一般的なHTTPサーバーが提供する多くの機能を実装できますが、今回はとりあえず、静的なHTMLファイルを表示するところまでやってみます。

以下の環境で行いました。
------------------------------------------------------------
クライアント:Windows Xp /IP:192.168.207.1
サーバー:CentOS release 5 (Final)/IP:192.168.207.128/ruby 1.8.7
------------------------------------------------------------

ディレクトリ構成は次のとおり
------------------------------------------------------------
/var2
|-- www <---DocumentRoot
 |-- index.html
------------------------------------------------------------
wwwディレクトリ以下は、サーバー用スクリプトを実行するユーザーがアクセスできるように、
権限を設定してください。

スクリプトを書いてみます。
server.rb
------------------------------------------------------------

1 #!/usr/local/bin/ruby
2
3 require 'webrick'
4 include WEBrick
5
6 server = HTTPServer.new(
7 :DocumentRoot => "/var2/www",
8 :Port => 20080,
9 :BindAddress => "192.168.207.128")
10
11 trap("INT"){server.stop}
12
13 server.start

------------------------------------------------------------


では、動かしてみます。
------------------------------------------------------------
$ > chmod 744 server.rb
$ > ./server.rb &
[1] 5035
$ > ps
5035 pts/1 00:00:00 server.rb
------------------------------------------------------------
psコマンドで起動が確認できました。

では、ブラウザからIP:192.168.207.128の20080番ポートに接続してみます。



はい。繋がりません。。

iptablesのフィルタにひっかかっていました。。

20080番ポートへの接続を許可します。
------------------------------------------------------------

$ > sudo iptables -t filter -A INPUT -p tcp --dport 20080 -j ACCEPT
$ > sudo /etc/init.d/iptables save
$ > sudo service iptables restart

------------------------------------------------------------

で、
フィルタはこうなりました。
------------------------------------------------------------

$ > sudo iptables -t filter -L INPUT
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp
ACCEPT tcp -- anywhere anywhere tcp dpt:pop3
ACCEPT tcp -- anywhere anywhere tcp dpt:smtp
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:20080

------------------------------------------------------------

再度、アクセスしてみます。



接続確認ができました!
ただ、反応が激遅いです。。VMware上で動いているサーバーからでしょうか。

今回のスクリプトでは、HTTPサーバーのログ情報は、標準エラー出力としてターミナルの画面に表示されていますので、次回は、ログをファイルに出力してみようと思います。
ではでは、