rails request & middlewares

49
Rails Request & Middlewares Santosh Wadghule | @mechanicles BigBinary

Upload: santosh-wadghule

Post on 15-Jul-2015

173 views

Category:

Technology


0 download

TRANSCRIPT

Rails Request

&

Middlewares

Santosh Wadghule | @mechanicles

BigBinary

What is a request?

Request is a…

• It is set of instructions that tells a server what kind

of response we want.

• In simple way, when we hit any url in the browser

for some file, that is your actual request :)

• It is a part of HTTP (request/response) protocol.

• HTTP uses one of the verbs like GET, POST,

PUT & DELETE when you perform the request to

the server.

Rails Request Life Cycle

The Greatest of the Great Greek Geniuses!

Rails Request Life Cycle

Browser

Web Server

App Server

Routes

Controller

Model

View

Database

Rails App

Middlewares

What is a Web Server?

• Web Server is strictly HTTP based, it just takes

HTTP requests and sends back HTTP responses

to the clients(browsers).

• It is mostly designed to serve static files.

• It also has other functionality like request pipeline,

load balancing etc. App servers lack these

functionalities.

• E.g. Ngnix, Apache

What is an App Server?

• App Server actually runs your Rails app.

• App Server is mostly known for to serve dynamic pages.

• Web Server forwards its request to the App Server, and

App Server in turn forwards that request to the Rails app.

• In development mode, App Server can play role of web

server. In production it does not scale too much so we

need web server in between.

• Webrick, Passenger, Mongrel, Unicorn, Thin & etc.

Request to Rails app• Rails isn’t just one application, it has lots of independent Rack

applications (middlewares).

• When request comes to the Rails app, it goes through the list of

middleware series.

• Last part of that series, sends request to the routes file.

• Based on request, Rails decides which controller & action need to be

executed from the routes.

• After executing the controller’s action, Rails sends back response to the

the client.

• Web Server & App Server actually handle the job of sending response to

the proper client.

What is a Middleware?

• Middleware is Rack application.

• Middleware is basically a filter for request and

response.

• So middlewares isolate the different stages of

processing on the request and response.

Rails Middlewares

Web

Server

Rails App

A B C D

Routes

Controller

Models

Views

Here A, B, C & D are middlewaresEach of these does processing on request & response

Why Rails uses Middlewares?

• Before Rails 3, Rails provides, like handling of session,

parsing for parameters and etc were very tightly coupled.

• As Rails was growing, apps built on Rails had more

demanding requirements. For some apps, Rails gave lots

of additional stuffs by default, which was not required like

cookies/flash. For some other apps, to implement new

filter on the the request/response was not possible.

• In Rails 3 and after, all these issues have got solved by

using a concept of Rack.

Rack

What is a Rack?

• Rack is simple but powerful spec. Yes it is just spec.

• It is not web framework or web server.

• It is an interface that sits between your web server and your application.

It wraps HTTP requests and responses in the simplest way possible, it

unifies and distills the API for web servers, web frameworks and

software in between (i.e. middleware) into a single method call.

• Specification: A Rack application is a Ruby object (not a class) that responds to `call`. It takes exactly one argument, the environment

and returns an Array of three values, The status, the headers, and the

body. That’s it.

• Rack is created by Christian Neukirchen.

Simple Rack App

Rack it up

What is Rack::Builder?

• Rack::Builder implements a small DSL to iteratively

construct Rack applications.

• Rack::Builder is the thing that glues Rack middlewares and

application together and convert them into single entity/rack

application.

• Under the hood, ‘rackup’ command converts your config.ru

script to an instance of Rack::Builder.

• Think of Rack::Builder object as stack in which your actual

rack application is at bottom and all middlewares on top of

it. The whole stack you can call it as rack application too.

Rails’ Rack::Builder

• Same like Rack::Builder, we have similar concept in Rails,

it is called as ActionDispatch::MiddlewareStack.

• Better flexibility and more features to meet Rails’

requirement.

• Many of Action Dispatcher’s internal components are

implemented as Rack middleware.

• Rails::Application uses

ActionDispatch::MiddlewareStack to combine various

internal and external middlewares to form a complete Rails

Rack application.

Inspecting Rails Middlewares

• Rails provides a task for inspecting the

middleware stack in use.

• $ bin/rake middleware

$ bin/rake middleware

Note: List of the middlewares may be different for your Rails app

Request’s entry to MVC

• When request comes to your Rails app, it goes

through these middlewares. From top to

bottom.

• At the bottom, request enters into the your

Rails’ MVC area.

Lets go through these middlewares and

understand what these middlewares do

Rack::Sendfile

• Sets server specific X-Sendfile header.

• Configure this via config.action_dispatch.x_sendfile_header option

• The Sendfile middleware intercepts responses whose body

is being served from a file and replaces it with a server

specific X-Sendfile header. The web server is then

responsible for writing the file contents to the client.

• This reduces the amount of work required by the Ruby

backend and takes advantage of the web server's

optimized file delivery code.

ActionDispatch::Static

• This middleware will attempt to return the

contents of a file's body from disk in the

response. If a file is not found on disk, the

request will be delegated to the application

stack. This middleware is commonly initialized to serve assets from a server's `public/`

directory.

• Used to serve static files. Disabled if config.serve_static_files is false.

Rack::Lock

• Sets env["rack.multithread"] flag to false

and wraps the application within a Mutex.

• Rack::Lock locks every request inside a mutex,

so that every request will effectively be

executed synchronously.

ActiveSupport::Cache::Strategy::LocalCache::Middleware

• From doc It says, “Caches that implement

LocalCache will be backed by an in-memory

cache for the duration of a block. Repeated

calls to the cache for the same key will hit the

in-memory cache for faster access”.

• This cache is not thread safe.

Rack::Runtime

• Sets an "X-Runtime" response header,

indicating the response time of the request, in

seconds.

Rack::MethodOverride

• Allows the method to be overridden if

params[:_method] is set. This is the middleware

which supports the PUT and DELETE HTTP method

types.

• Rails forms convert PUT/DELTE request into the

POST request and passes the param[:_method]

which may be has values like ‘PUT’ & ‘DELETE’ etc.

• Then this middle converts the post request, into

proper request PUT/DELETE which user has initiated

for.

ActionDispatch::RequestId

• Assigns a unique id to the request.

• Sends back this unique id in X-Request-ID

response header.

Rails::Rack::Logger

• Notifies the logs that the request has began.

After request is complete, flushes all the logs.

ActionDispatch::ShowExceptions

• This middleware rescues any exception

returned by the application and calls an

exceptions app that will wrap it in a format for

the end user.

ActionDispatch::DebugExceptions

• This middleware is responsible for logging

exceptions and showing a debugging page in

case the request is local.

ActionDispatch::RemoteIp

• It captures the remote IP address.

• Checks for IP spoofing attacks.

ActionDispatch::Reloader

• Provides prepare and cleanup callbacks,

intended to assist with code reloading during

development.

ActionDispatch::Callbacks

• Provides callbacks to be executed before and

after dispatching the request.

ActiveRecord::Migration::CheckPending

• Checks pending migrations and raises

ActiveRecord::PendingMigrationError if any

migrations are pending.

ActiveRecord::ConnectionAdapters::ConnectionManagement

• Cleans active connections after each request.

• It will not clean the active connections if env[‘rack.test’] set to true.

ActiveRecord::QueryCache

• Enables the Active Record query cache for

request.

• It clears the cache after executing the request.

ActionDispatch::Cookies

• Sets cookies for the request.

ActionDispatch::Session::CookieStore

• Responsible for storing the session in cookies.

• It is dramatically faster than the alternatives.

ActionDispatch::Flash

• Sets up the flash keys.

• Only available if config.action_controller.session_store is

set to a value.

ActionDispatch::ParamsParser

• Parses out parameters from the request into

params.

Rack::Head

• Rack::Head returns an empty body for all

HEAD requests. It leaves all other requests

unchanged.

• Converts HEAD requests to GET requests and

serves them as so.

Rack::ConditionalGet

• Adds support for "Conditional GET" so that

server responds with nothing if page wasn't

changed.

Rack::ETag

• Adds ETag header on all String bodies. ETags

are used to validate cache.

Warden::Manager

• The middleware for Rack Authentication.

• It injects an authentication object into the rack

environment hash

Rack::Deflater

• This middleware enables compression of http

responses.

• Supports these compression algorithms(gzip,

deflate, identity)

RailsRequest::Application.routes

• Here RailsRequest will be different based on your Rails app

• This code returns the instance of ActionDispatch::Routing::RouteSet class

which is also a Rack application.

• After this, request goes to config/routes.rb file and from there it enters into

your MVC.

• Controller creates response & sends back it again to these middlewares stack.

• Middlewares may be can filter that response if necessary.

• Finally response goes to client through the app server & web server.

• How does Rails handle the routes and create the response in a way of [status,

header, body]? Well, that’s the topic for another talk.

Thanks :)