Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rack #4

Closed
dylanninin opened this issue Aug 1, 2016 · 2 comments
Closed

Rack #4

dylanninin opened this issue Aug 1, 2016 · 2 comments
Assignees
Milestone

Comments

@dylanninin
Copy link
Owner

dylanninin commented Aug 1, 2016

Rack provides a minimal interface between webservers that support Ruby and Ruby frameworks.

  • Web Servers: like WEBrick, Mongrel, Puma etc.
  • Interface:
    • Handlers: the respective handler for any supported Web Server
    • Middlewares: the request/response customized chain between Web Server and the framework
    • Adapters: the respective adapter for any Ruby/Ruby Framework
  • Ruby/Ruby Frameworks: like Rails, Sinatra etc.

image

Request/Response

A HTTP request is a triplet consisting of a method and resource pair, a set of headers and an optional body while a HTTP response is in triplet consisting of a response code, a set of headers and an optional body.

app = Proc.new {|env|
  puts "#{Time.now}, env: #{env}"

  # status_code, headers, body
  [200, {}, ["Hello. The time is #{Time.now}"]]
}

puts app.call({}) # =>
#2016-08-01 13:59:43 +0800, env: {}
#[200, {}, [Hello. The time is 2016-08-01 13:59:43 +0800]

require 'rack'
puts Rack::Handler.constants # =>
#[CGI, FastCGI, WEBrick, LSWS, SCGI, Thin]

Rack::Handler::WEBrick.run app # =>
#[2016-08-01 14:01:05] INFO  WEBrick 1.3.1
#[2016-08-01 14:01:05] INFO  ruby 2.3.1 (2016-04-26) [x86_64-darwin15]
#[2016-08-01 14:01:05] INFO  WEBrick::HTTPServer#start: pid=71956 port=8080

################################################################################
#
# Terminal request with httpie
#
#http :8080
#HTTP/1.1 200 OK
#Connection: Keep-Alive
#Content-Length: 44
#Date: Mon, 01 Aug 2016 06:01:28 GMT
#Server: WEBrick/1.3.1 (Ruby/2.3.1/2016-04-26)
#
#Hello. The time is 2016-08-01 14:01:28 +0800
################################################################################

################################################################################
#
# Rack formatted log
#
#2016-08-01 14:01:28 +0800,
# env: {
#   "GATEWAY_INTERFACE"=>"CGI/1.1",
#   "PATH_INFO"=>"/",
#   "QUERY_STRING"=>"",
#   "REMOTE_ADDR"=>"127.0.0.1",
#   "REMOTE_HOST"=>"127.0.0.1",
#   "REQUEST_METHOD"=>"GET",
#   "REQUEST_URI"=>"http://localhost:8080/",
#   "SCRIPT_NAME"=>"",
#   "SERVER_NAME"=>"localhost",
#   "SERVER_PORT"=>"8080",
#   "SERVER_PROTOCOL"=>"HTTP/1.1",
#   "SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/2.3 #.1/2016-04-26)",
#   "HTTP_HOST"=>"localhost:8080",
#   "HTTP_ACCEPT_ENCODING"=>"gzip, deflate",
#   "HTTP_USER_AGENT"=>"HTTPie/0.9.4",
#   "HTTP_CONNECTION"=>"keep-alive",
#   "HTTP_ACCEPT"=>"*/*",
#   "rack.version"=>[1, #3],
#   "rack.input"=>#<StringIO:0x007fede39d7730>,
#   "rack#.errors"=>#<IO:<STDERR>>,
#   "rack.multithread"=>true,
#   "rack#.multiprocess"=>false,
#   "rack.run_once"=>false,
#   "rack.url_scheme"=>"http",
#   "rack.hijack?"=>true,
#   "rack#.hijack"=>#<Proc:0x007fede39d75c8@/Users/dylanninin/.rvm/gems/ruby-2.3#.1/gems/rack-2.0.1/lib/rack/handler/webrick.rb:74 (lambda)>,
#   "rack#.hijack_io"=>nil,
#   "HTTP_VERSION"=>"HTTP/1.1",
#   "REQUEST_PATH"=>"/"
# }
#127.0.0.1 - - [01/Aug/2016:14:01:28 CST] "GET / HTTP/1.1" 200 44

References

@dylanninin dylanninin self-assigned this Aug 1, 2016
@dylanninin dylanninin modified the milestone: Sprint 1 Aug 1, 2016
@dylanninin
Copy link
Owner Author

Middleware

   ...
   def start &blk
      ...
      server.run wrapped_app, options, &blk
    end
    ...
      def build_app(app)
        middleware[options[:environment]].reverse_each do |middleware|
          middleware = middleware.call(self) if middleware.respond_to?(:call)
          next unless middleware
          klass, *args = middleware
          app = klass.new(app, *args)
        end
        app
      end

      def wrapped_app
        @wrapped_app ||= build_app app
      end

@dylanninin
Copy link
Owner Author

dylanninin commented Aug 17, 2016

The Onion Architecture is a awesome picture illustrating the middlewares around an App

image

Example:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant