35
Rack 触ってみた Rack 触ってみた 本当に触ってみただけ @hamajyotan

Tottoruby 20110903

Embed Size (px)

DESCRIPTION

tottoruby

Citation preview

Page 1: Tottoruby 20110903

Rack 触ってみたRack 触ってみた本当に触ってみただけ

@hamajyotan

Page 2: Tottoruby 20110903

アジェンダ3本立て

近況報告

Rack ことはじめ, 触ってみる (Main)

触って困ったところ少し

雑談, 質疑応答

01 34

Page 3: Tottoruby 20110903

いまここ3本立て

近況報告 <== いまここ

Rack ことはじめ, 触ってみる

触って困ったところ少し

雑談, 質疑応答

02 34

Page 4: Tottoruby 20110903

近況報告まゆしぃ

トゥットゥルー, まだ数話しかみてない

野球で西武がビリでびっくりした

野球には全く興味がない

自分が知っている西武は常勝チームだった

室伏さんマジかっこいい

室伏になら投げられてもいい

03 34

Page 5: Tottoruby 20110903

いまここ3本立て

近況報告

Rack ことはじめ, 触ってみる <== いまここ

触って困ったところ少し

雑談, 質疑応答

04 34

Page 6: Tottoruby 20110903

ことはじめ, 触ってみるRack って何?

ちょっとググればわかることを得意げに話します

概要とか

仕組みとか

触ってみる

触ってみます

05 34

Page 7: Tottoruby 20110903

Rack とはWeb サーバと Web アプリの架け橋, グルー, I/F

色んな Web サーバ

webrick, thin, mongrel, passenger, unicorn, ..

色んな Web アプリ (framework)

rails, sinatra, camping, ...

Web サーバとアプリケーションの間のお約束

06 34

Page 8: Tottoruby 20110903

どんなお約束なの ?#call ってメッセージに反応するなにか

1つの引数を受け付ける

リクエストを意味する Hash

3つの要素を持つ Array を返す

ステータスコード

レスポンスヘッダを意味する Hash

レスポンスボディを意味する Array

07 34

Page 9: Tottoruby 20110903

つまりこんな感じ

Proc.new { |env| [ 200, {'Content-Type' => 'text/html'}, ['Hello, World!'] ]}

08 34

Page 10: Tottoruby 20110903

config.ru

require 'rubygems'require 'rack'

app = Proc.new { |env| [ 200, {'Content-Type' => 'text/html'}, ['Hello, World!'] ]}run app09 34

Page 11: Tottoruby 20110903

実行してみる

$ rackup [2011-08-30 11:18:31] INFO WEBrick 1.3.1[2011-08-30 11:18:31] INFO ruby 1.9.2 (2011-02-18) [i686-linux][2011-08-30 11:18:31] INFO WEBrick::HTTPServer#start: pid=8494 port=9292

10 34

Page 12: Tottoruby 20110903

リクエストしてみる

$ telnet 127.0.0.1 9292Trying 127.0.0.1...Connected to 127.0.0.1.Escape character is '^]'.GET / HTTP/1.1

HTTP/1.1 200 OK Content-Type: text/plainTransfer-Encoding: chunkedServer: WEBrick/1.3.1 (Ruby/1.9.2/2011-02-18)Date: Tue, 30 Aug 2011 02:09:49 GMTContent-Length: 23Connection: Keep-Alive

dHello, World!0

Connection closed by foreign host.11 34

Page 13: Tottoruby 20110903

反応してる

$ rackup [2011-08-30 11:18:31] INFO WEBrick 1.3.1[2011-08-30 11:18:31] INFO ruby 1.9.2 (2011-02-18) [i686-linux][2011-08-30 11:18:31] INFO WEBrick::HTTPServer#start: pid=8494 port=9292127.0.0.1 - - [30/Aug/2011 11:18:40] "GET / HTTP/1.1" 200 - 0.0012

12 34

Page 14: Tottoruby 20110903

mongrel で動かすには ?

$ rackup -s mongrel

13 34

Page 15: Tottoruby 20110903

passenger では ?config.ru 以外に少し必要

public/ ディレクトリ (空っぽでOK)

(任意) tmp/restart.txt

apache を再起動せずにアプリを再起動できる

14 34

Page 16: Tottoruby 20110903

pasenger で動かす-1

$ tree /home/hamajyotan/rack/test

/home/hamajyotan/rack/test├── config.ru├── public└── tmp └── restart.txt

15 34

Page 17: Tottoruby 20110903

passenger で動かす-2/home/hamajyotan/rack/test/ に配置されている前提で・・

<VirtualHost *:80> RackEnv production ServerName www.yourhost.com DocumentRoot /home/hamajyotan/rack/test/public <Directory /home/hamajyotan/rack/test/public> AllowOverride all Options -MultiViews </Directory></VirtualHost>

16 34

Page 18: Tottoruby 20110903

env って何が入っているの?

# config.rurequire 'rack'require 'yaml'run Proc.new { |env| [ 200, {'Content-Type' => 'text/plain', [env.to_yaml], ]}

17 34

Page 19: Tottoruby 20110903

env の中身

--- GATEWAY_INTERFACE: CGI/1.1PATH_INFO: /QUERY_STRING: ""REMOTE_ADDR: 127.0.0.1REMOTE_HOST: localhostREQUEST_METHOD: GETREQUEST_URI: http://localhost:9292/SCRIPT_NAME: ""SERVER_NAME: localhostSERVER_PORT: "9292"SERVER_PROTOCOL: HTTP/1.1SERVER_SOFTWARE: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)HTTP_HOST: localhost:9292HTTP_CONNECTION: keep-aliveHTTP_USER_AGENT: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.218 Safari/535.1HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8HTTP_ACCEPT_ENCODING: gzip,deflate,sdchHTTP_ACCEPT_LANGUAGE: ja,en-US;q=0.8,en;q=0.6HTTP_ACCEPT_CHARSET: Shift_JIS,utf-8;q=0.7,*;q=0.3rack.version: - 1- 1rack.input: !ruby/object:Rack::Lint::InputWrapper input: !ruby/object:StringIO {}

rack.errors: !ruby/object:Rack::Lint::ErrorWrapper error: !ruby/object:IO {}

rack.multithread: truerack.multiprocess: falserack.run_once: falserack.url_scheme: httpHTTP_VERSION: HTTP/1.1REQUEST_PATH: /

18 34

Page 20: Tottoruby 20110903

ここまでのまとめrack 仕様に準拠したコード

#call - リクエストを引数に、レスポンスを返す関数

config.ru ってファイルを準備

#call に反応するインスタンスを run に与える

rack の仕様に準拠したサーバならどこでも動く

webrick, mongrel, passenger, ...

env の中にはリクエストに関する情報がある

path とか port とか useragent とか

method とか body とか19 34

Page 21: Tottoruby 20110903

Rack ミドルウェア基本は一緒

#call ってメッセージに応答

{ before | after } フィルタ

他の Rack アプリを内包する

デザパタで言うところの Decorator パターン

20 34

Page 22: Tottoruby 20110903

コードでおk?

class Middleware def initialize app @app = app end

def call env # before... code, header, body = @app.call env # after... [code, header, body] endend21 34

Page 23: Tottoruby 20110903

処理後レスポンスヘッダ付加

class AddServerHeader def initialize app @app = app end

def call env code, header, body = @app.call env header['Server'] = "#{header['Server']} (*^o^)=3" [code, header, body] endend

22 34

Page 24: Tottoruby 20110903

どうやって使う ?

# config.rurequire 'rack'require 'add_server_header'

app = Proc.new { |env| [200, {'Content-Type' => 'text/plain'}, ['Hello, World']]}

use AddServerHeaderrun app

23 34

Page 25: Tottoruby 20110903

use がキモ

# これはuse AddServerHeaderrun app

# これと同じmiddleware = AddServerHeader.new(app)run middleware

24 34

Page 26: Tottoruby 20110903

use がキモ

# これはuse AddServerHeaderuse Otherrun app

# これと同じmiddleware = AddServerHeader.new(Other.new(app))run middleware

25 34

Page 27: Tottoruby 20110903

use がキモ

# これはuse AddServerHeaderuse AddServerHeaderrun app

# これと同じmiddleware = AddServerHeader.new(AddServerHeader.new(app))run middleware

26 34

Page 28: Tottoruby 20110903

いろんなミドルウェアRack::Auth::Basic

基本認証を実現

Rack::Static

静的ファイルを出力する

Rack::ConditionalGet

条件付き GET を実現

Etc..

27 34

Page 29: Tottoruby 20110903

例えば基本認証

# config.rurequire 'rack'app = Proc.new { |env| [200, {'Content-Type' => 'text/plain'}, ['Hello, World']]}use Rack::Auth::Basic, 'mayusi-' do |user, pass| user == 'mayusi-' && pass == 'mayusi-!'endrun app

# ちなみ use 以下はこれと同じ# auth = Rack::Auth::Basic.new(app, 'mayusi-') do |user, pass|# user == 'mayusi-' && pass == 'mayusi-!'# end# run auth

28 34

Page 30: Tottoruby 20110903

ここまでのまとめミドルウェア

基本は rack アプリケーションと同じ

#call を持つ

env を引数に受け取る

レスポンスを返す

他のアプリケーションを Decorator パターンで内包する

29 34

Page 31: Tottoruby 20110903

いまここ3本立て

近況報告

Rack ことはじめ, 触ってみる

触って困ったところ少し <== いまここ

雑談, 質疑応答

30 34

Page 32: Tottoruby 20110903

困ったところWEBrick

'Content-Length: 0' をガン無視

env['CONTENT_LENGTH'] = '0' って設定してくれない

他の Web サーバはしてくれた

GET パラメータのセパレータ

& だけでなく、 ; もセパレータ扱い

RFC 的に正しいか良く分かっていません

31 34

Page 33: Tottoruby 20110903

Paranoia なところHTTP のヘッダ名

大文字小文字区別しても良いのか否か?

アンダースコアをヘッダ名にできないけど・・

x-hoge-hogehoge: fuga# => env['HTTP_X_HOGE_HOGEHOGE'] = 'fuga'x-hoge_HogeHoge: piyo# => env['HTTP_X_HOGE_HOGEHOGE'] = 'piyo'

32 34

Page 34: Tottoruby 20110903

最後にrack を利用したアプリケーション例

というか宣伝 ?

https://github.com/hamajyotan/castoro-s3-adapter

castoro-s3-adapter ってのを作成中です

castoro をバックエンドにした Amazon s3 実装

というか castoro を S3 プロトコルでアクセス可能にするもの

33 34

Page 35: Tottoruby 20110903

おわりですご清聴有難うございます

質問ありましたらどうぞ

雑談でもおk

34 34