Basic tutorial on Rack middleware in Ruby on Rails, railsrack
Rack is a framework between the ruby server and the rack application. rails and sinatra are both built based on rack and belong to rack applications.
Rack provides a standard interface for interacting with the server. The standard rack Program is an object that can respond to call. It can be an object, Proc, lambda, or even method. It receives the env parameter (Environment object) and returns an array, including:
- Status, http response status code
- It can be hash, which is the http header information
- Object with the each method, and the each returns a string
Rack is extended through middleware, that is, the original rack program is decorated and further processed based on the original returned array, and the rack object is returned.
Simple rack Program
require 'rack'
app = lambda{|env|[200,{},["hello from rack"]]}
Rack::Handler::WEBrick.run app
Use the middleware rack program:
Require 'rack'
class Decorator
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
new_body = "from middleware input <br/>"
body.each{|str| new_body << str}
headers['Content-Length'] = new_body.bytesize.to_s
[status, headers, [new_body]]
end
end
app = lambda{|env|[200,{},["hello from rack"]]}
Rack::Handler::WEBrick.run Decorator.new(app)
The Method Using Middleware above is easy to confuse when multiple methods are used, and rack has a Builder class that can be effectively managed.
Use the following
Require 'rack'
require 'decorator'
app = Rack::Builder.new{
use Rack::ContentLength
use Decorator
run lambda {|env| [200, {"Content-Type"=>"text/html"}, ["hello world"]]}
}.to_app
Rack::Handler::WEBrick.run app
You can use the map method of Rack: Builder to create rack programs with routes.
Require 'rack'
app = Rack::Builder.new {
map '/hello' do
run lambda {|env| [200, {"Content-Type" => "text/html"}, ["hello"]] } end
map '/world' do
run lambda {|env| [200, {"Content-Type" => "text/html"}, ["world"]] }
end
map '/' do
run lambda {|env| [200, {"Content-Type" => "text/html"}, ["all"]] } end
}.to_app
Rack::Handler::WEBrick.run app, :Port => 3000
Due to the full stack of rails, there are many rack middleware, which are used by websites or APIs with high concurrency but simple business.
The response time is too long. In this case, you can consider using rack Or sinatra.
There are two ways to start an rack program:
1. Run the. rb file directly using ruby. The service is started on 8080 by default and there is no log file.
2. Use rackup. The service is started in 9292 by default. There are log files. You can use-o to specify the ip address and-p to specify the port number.
require 'rack'
app = lambda{|env| [200,{},["hello world"]] }
Rack::Server.new.server.run app
ruby xxx.rb
#test.ru
run lambda{|env| [ 200,{},["rackup start"] ]}
rackup test.ru
Rack loads some middleware by default at startup:
def logging_middleware
lambda { |server|
server.server.name =~ /CGI/ || server.options[:quiet] ? nil : [Rack::CommonLogger, $stderr]
}
end
m = Hash.new {|h,k| h[k] = []}
m["deployment"] = [
[Rack::ContentLength],
[Rack::Chunked],
logging_middleware,
[Rack::TempfileReaper]
]
m["development"] = [
[Rack::ContentLength],
[Rack::Chunked],
logging_middleware,
[Rack::ShowExceptions],
[Rack::Lint],
[Rack::TempfileReaper]
]
m
end
Including access records for body length error messages.
Rack has a Directory middleware that can generate a web Service for Directory files.
A simple sentence:
#test.ru
run Rack::Directory.new "~/"
rackup test.ru
In this way, all the files and folders in the home directory are displayed in the browser.
Use rake middleware in the rails application to display all middleware (middleware)
** **rake middleware
use Rack::Sendfile
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007feef1563b90>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
run Fool::Application.routes
Rails uses some middleware defined by rack and customizes some middleware. The custom routes is the rack program, and routes changes the action of rails controller to lambda and runs the program as rack, enter
2.2.1 :001 > QuestionsController.action(:new)
=> #<Proc:0x007fbe482ee0b0@/Users/killman/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.1/lib/action_controller/metal.rb:237 (lambda)>
You can add, delete, and modify middleware in config/application. rb.
config.middleware.use(new_middleware, args)#:Add new middleware to the end of the list;
config.middleware.insert_before(existing_middleware,
new_middleware, args)#:在 existing_middleware
Add new middleware before;
config.middleware.insert_after(existing_middleware,
new_middleware, args)#:in existing_middleware
Then add the new middleware;
config.middleware.swap ActionDispatch :: ShowExceptions, Lifo :: ShowExceptions #Replace middleware
config.middleware.delete "Rack :: Lock" #Delete middleware
Role of middleware:
- Rack: Sendfile: sets the X-Sendfile header on the server. Use the config. action_dispatch.x_sendfile_header option.
- ActionDispatch: Static: used to serve Static resource files. If the option config. serve_static_assets is false, disable this middleware.
- Rack: Lock: Set env ["rack. multithread"] flag to false, and the program is placed in the mutex Lock.
- ActiveSupport: Cache: Strategy: LocalCache: Middleware: Save the Cache in the memory, which is not thread-safe.
- Rack: Runtime: sets the X-Runtime header, that is, the length of the request to be executed, measured in seconds.
- Rack: MethodOverride: If the params [: _ method] parameter is specified, the request method used is overwritten. This middleware implements the PUT and DELETE methods.
- ActionDispatch: RequestId: Set a unique X-Request-Id header in the response, and enable the ActionDispatch: Request # uuid method.
- Rails: Rack: Logger: the reminder log when the request starts. logs are written after the request is complete.
- ActionDispatch: ShowExceptions: All exceptions thrown by the remedy program. It calls the program that handles exceptions and displays them to users in a specific format.
- ActionDispatch: DebugExceptions: If you develop an exception locally, write the exception to the log and display a debugging page.
- ActionDispatch: RemoteIp: Check the IP address of the spoofing attack.
- ActionDispatch: Reloader: Provides "prepare" and "Clean Up" callbacks to help code reload in the development environment.
- ActionDispatch: Callbacks: Call the "prepare" Callback before processing the request.
- ActiveRecord: Migration: CheckPending: Check whether the Migration is to be run. If yes, an ActiveRecord: PendingMigrationError error is thrown.
- ActiveRecord: ConnectionAdapters: ConnectionManagement: after the request is processed, clear the active connection unless rack. test is set to true in the environment where the request is initiated.
- ActiveRecord: QueryCache: Enable the Active Record query cache.
- ActionDispatch: Cookies: set cookies for requests.
- ActionDispatch: Session: CookieStore: stores sessions in cookies.
- ActionDispatch: Flash: Set the key of the Flash message. It is available only when the config. action_controller.session_store option is set.
- ActionDispatch: ParamsParser: returns the parameters in the request to params.
- ActionDispatch: Head: converts a HEAD request to a GET request and processes it.
- Rack: ConditionalGet: added support for "Conditional GET". If the page is not modified, it will not respond.
- Rack: ETag: adds the ETags header to all string-type subjects. ETags is used to verify the cache.