Basic tutorial on Rack middleware in Ruby on Rails, railsrack

Source: Internet
Author: User
Tags sendfile

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.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.