Rails on Rack
作用:连接web server和web app,处理http requests.
图示:
rack app: A Rack application is a Ruby object that has a call method, which has a single argument, the environment,(corresponding to a HTTP request) and returns an array of 3 elements, status, headers and body(corresponding to a HTTP response, must respond to each method).
handlers: connect Rack to all these web application servers (WEBrick, Mongrel etc.).
adapters: connect Rack to various web frameworks (Sinatra, Rails etc.)
middleware: come between the calling client and the server, process the HTTP request before sending it to the server, and processing the HTTP response before returning it to the client.
安装和使用:
#安装
gem install rack
#创建rack对象,参考如上的说明,相应call方法,传递单个参数,返回status, headers, body, 如下所示
#proc对象
my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
#method对象
def my_method env
[200, {}, ["method called"]]
end
my_rack_method = method(:my_method)
#在irb中情况使用
#使用proc对象作为Rack app
require 'rack'
Rack::Handler.constants #=>[:FastCGI, :CGI, :WEBrick, :LSWS, :SCGI, :Thin]
my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
my_rack_proc.call({}) #=>[200, {"Content-Type" => "text/plain"}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
Rack::Handler::WEBrick.run my_rack_proc #http://localhost/8080默认进行访问
Rack::Handler::WEBrick.run my_rack_proc, :Port=> 9879 #指定端口
#使用method对象作为Rack app
require 'rack'
def my_method env
[200, {}, ["method called"]]
end
my_rack_method = method(:my_method)
Rack::Handler::WEBrick.run my_rack_method #http://localhost/8080默认进行访问
使用rackup
#只建立config.ru文件,作用是方便使用rack
#config.ru
Rack::Handler::WEBrick.run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
#执行
rackup config.ru
#建立config.ru和my_app.rb文件
#my_app.rb
class MyApp
def call env
[200, {"Content-Type" => "text/html"}, ["Hello Rack"]]
end
end
#config.ru
require './my_app' #my_app.rb和config.ru文件在同一个文件中
Rack::Handler::WEBrick.run MyApp.new
#执行
rackup config.ru
使用middleware
#简单使用middleware
#修改如上的config.ru文件
#my_app.rb
class MyApp
def call env
[200, {"Content-Type" => "text/html"}, ["Hello Rack"]]
end
end
#config.ru
require './my_app'
use Rack::Reloader #使用middleware的方式,这个插件作用是修改my_app.rb中的response中的内容,不用重启服务器
Rack::Handler::WEBrick.run MyApp.new
#创建middleware
#创建myrackmiddleware.rb文件,修改config.ru文件
#my_app.rb
class MyApp
def call env
[200, {"Content-Type" => "text/html"}, ["Hello Rack"]]
end
end
#myrackmiddleware.rb
class MyRackMiddleware
def initialize(appl)
@appl = appl
end
def call(env)
status, headers, body = @appl.call(env)
append_s = "... greetings from RubyLearning!!"
new_body = ""
body.each { |string| new_body << " " << string }
new_body << " " << append_s
[status, headers, [new_body]]
end
end
#config.ru
require './my_app'
require './myrackmiddleware'
use Rack::Reloader
use MyRackMiddleware
Rack::Handler::WEBrick.run MyApp.new
middleware成功案例
require "thin"
app = -> (env) do
slee 3
[ 200, { "Content-Type" => "text/plain" }, ["Hello World\n"] ]
end
class LoggingMiddleware
def initialize(app)
@app = app
end
def call(env)
before = Time.now.to_i
status, headers, body = @app.call(env)
after = Time.now.to_i
log_message = "App took #{after - before} seconds."
[status, headers, body << log_message]
end
end
use LoggingMiddleware
run app