Permalink
Browse files

Add RDocs

darcs-hash:20070301185301-4fc50-159ee23dc4ab0c209dcbf8d7e014a308d72434d7.gz
  • Loading branch information...
1 parent 9181a58 commit 376fa1e312a0ae5509673ea120ad6e68fb1c8d39 @chneukirchen chneukirchen committed Mar 1, 2007
View
@@ -5,9 +5,18 @@
$: << File.expand_path(File.dirname(__FILE__))
+
+# The Rack main module, serving as a namespace for all core Rack
+# modules and classes.
+#
+# All modules meant for use in your application are <tt>autoload</tt>ed here,
+# so it should be enough just to <tt>require rack.rb</tt> in your code.
+
module Rack
+ # The Rack version number.
VERSION = [0,1]
+ # Return the Rack version as a dotted string.
def self.version
VERSION.join(".")
end
@@ -29,11 +38,25 @@ def self.version
autoload :Request, "rack/request"
autoload :Response, "rack/response"
+ # *Adapters* connect Rack with third party web frameworks.
+ #
+ # Rack includes adapters for Camping and Rails.
+ #
+ # Refer to the submodules for framework-specific calling details.
+
module Adapter
autoload :Camping, "rack/adapter/camping"
autoload :Rails, "rack/adapter/rails"
end
+ # *Handlers* connect web servers with Rack.
+ #
+ # Rack includes Handlers for Mongrel, WEBrick, FastCGI and CGI.
+ #
+ # Handlers usually are activated by calling <tt>MyHandler.run(myapp)</tt>.
+ # A second optional hash can be passed to include server-specific
+ # configuration.
+
module Handler
autoload :CGI, "rack/handler/cgi"
autoload :FastCGI, "rack/handler/fastcgi"
View
@@ -1,4 +1,21 @@
module Rack
+ # Rack::Builder implements a small DSL to iteratively construct Rack
+ # applications.
+ #
+ # Example:
+ #
+ # app = Rack::Builder.new {
+ # use Rack::CommonLogger
+ # use Rack::ShowExceptions
+ # map "/lobster" do
+ # use Rack::Lint
+ # run Rack::Lobster.new
+ # end
+ # }
+ #
+ # +use+ adds a middleware to the stack, +run+ dispatches to an application.
+ # You can use +map+ to construct a Rack::URLMap in a convenient way.
+
class Builder
def initialize(&block)
@ins = []
View
@@ -1,4 +1,8 @@
module Rack
+ # Rack::Cascade tries an request on several apps, and returns the
+ # first response that is not 404 (or in a list of configurable
+ # status codes).
+
class Cascade
attr_reader :apps
@@ -1,4 +1,8 @@
module Rack
+ # Rack::CommonLogger forwards every request to an +app+ given, and
+ # logs a line in the Apache common log format to the +logger+, or
+ # rack.errors by default.
+
class CommonLogger
def initialize(app, logger=nil)
@app = app
@@ -17,6 +21,7 @@ def _call(env)
[@status, @header, self]
end
+ # By default, log to rack.errors.
def <<(str)
@env["rack.errors"].write(str)
@env["rack.errors"].flush
View
@@ -1,4 +1,10 @@
module Rack
+ # Rack::File serves files below the +root+ given, according to the
+ # path info of the Rack request.
+ #
+ # Handlers can detect if bodies are a Rack::File, and use mechanisms
+ # like sendfile on the +path+.
+
class File
attr_accessor :root
attr_accessor :path
@@ -40,7 +46,8 @@ def each
}
end
- # From WEBrick
+ # :stopdoc:
+ # From WEBrick.
MIME_TYPES = {
"ai" => "application/postscript",
"asc" => "text/plain",
@@ -96,5 +103,6 @@ def each
"xwd" => "image/x-xwindowdump",
"zip" => "application/zip",
}
+ # :startdoc:
end
end
View
@@ -1,9 +1,14 @@
module Rack
+ # Rack::Lint validates your application and the requests and
+ # responses according to the Rack spec.
+
class Lint
def initialize(app)
@app = app
end
+ # :stopdoc:
+
class LintError < RuntimeError; end
module Assertion
def assert(message, &block)
@@ -376,6 +381,9 @@ def close
@closed = true
@body.close if @body.respond_to?(:close)
end
+
+ # :startdoc:
+
end
end
View
@@ -1,60 +1,62 @@
require 'zlib'
-# Paste has a Pony, Rack has a Lobster!
-
module Rack
- LobsterString = Zlib::Inflate.inflate("eJx9kEEOwyAMBO99xd7MAcytUhPlJyj2
- P6jy9i4k9EQyGAnBarEXeCBqSkntNXsi/ZCvC48zGQoZKikGrFMZvgS5ZHd+aGWVuWwhVF0
- t1drVmiR42HcWNz5w3QanT+2gIvTVCiE1lm1Y0eU4JGmIIbaKwextKn8rvW+p5PIwFl8ZWJ
- I8jyiTlhTcYXkekJAzTyYN6E08A+dk8voBkAVTJQ==".delete("\n ").unpack("m*")[0])
+ # Paste has a Pony, Rack has a Lobster!
+ class Lobster
+ LobsterString = Zlib::Inflate.inflate("eJx9kEEOwyAMBO99xd7MAcytUhPlJyj2
+ P6jy9i4k9EQyGAnBarEXeCBqSkntNXsi/ZCvC48zGQoZKikGrFMZvgS5ZHd+aGWVuWwhVF0
+ t1drVmiR42HcWNz5w3QanT+2gIvTVCiE1lm1Y0eU4JGmIIbaKwextKn8rvW+p5PIwFl8ZWJ
+ I8jyiTlhTcYXkekJAzTyYN6E08A+dk8voBkAVTJQ==".delete("\n ").unpack("m*")[0])
- Lobster = lambda { |env|
- if env["QUERY_STRING"].include?("flip")
- lobster = LobsterString.split("\n").
- map { |line| line.ljust(42).reverse }.
- join("\n")
- href = "?"
- else
- lobster = LobsterString
- href = "?flip"
+ LambdaLobster = lambda { |env|
+ if env["QUERY_STRING"].include?("flip")
+ lobster = LobsterString.split("\n").
+ map { |line| line.ljust(42).reverse }.
+ join("\n")
+ href = "?"
+ else
+ lobster = LobsterString
+ href = "?flip"
+ end
+
+ [200, {"Content-Type" => "text/html"},
+ ["<title>Lobstericious!</title>",
+ "<pre>", lobster, "</pre>",
+ "<a href='#{href}'>flip!</a>"]
+ ]
+ }
+
+ def call(env)
+ req = Request.new(env)
+ if req.GET["flip"] == "left"
+ lobster = LobsterString.split("\n").
+ map { |line| line.ljust(42).reverse }.
+ join("\n")
+ href = "?flip=right"
+ elsif req.GET["flip"] == "crash"
+ raise "Lobster crashed"
+ else
+ lobster = LobsterString
+ href = "?flip=left"
+ end
+
+ Response.new.finish do |res|
+ res.write "<title>Lobstericious!</title>"
+ res.write "<pre>"
+ res.write lobster
+ res.write "</pre>"
+ res.write "<p><a href='#{href}'>flip!</a></p>"
+ res.write "<p><a href='?flip=crash'>crash!</a></p>"
+ end
end
- [200, {"Content-Type" => "text/html"},
- ["<title>Lobstericious!</title>",
- "<pre>", lobster, "</pre>",
- "<a href='#{href}'>flip!</a>"]
- ]
- }
-
- Lobster2 = lambda { |env|
- req = Request.new(env)
- if req.GET["flip"] == "left"
- lobster = LobsterString.split("\n").
- map { |line| line.ljust(42).reverse }.
- join("\n")
- href = "?flip=right"
- elsif req.GET["flip"] == "crash"
- raise "Lobster crashed"
- else
- lobster = LobsterString
- href = "?flip=left"
- end
-
- Response.new.finish do |res|
- res.write "<title>Lobstericious!</title>"
- res.write "<pre>"
- res.write lobster
- res.write "</pre>"
- res.write "<p><a href='#{href}'>flip!</a></p>"
- res.write "<p><a href='?flip=crash'>crash!</a></p>"
- end
- }
+ end
end
if $0 == __FILE__
require 'rack'
require 'rack/showexceptions'
Rack::Handler::WEBrick.run \
- Rack::ShowExceptions.new(Rack::Lint.new(Rack::Lobster2)),
+ Rack::ShowExceptions.new(Rack::Lint.new(Rack::Lobster.new)),
:Port => 9202
end
View
@@ -4,6 +4,19 @@
require 'rack/utils'
module Rack
+ # Rack::MockRequest helps testing your Rack application without
+ # actually using HTTP.
+ #
+ # After performing a request on a URL with get/post/put/delete, it
+ # returns a MockResponse with useful helper methods for effective
+ # testing.
+ #
+ # You can pass a hash with additional configuration to the
+ # get/post/put/delete.
+ # <tt>:input</tt>:: A String or IO-like to be used as rack.input.
+ # <tt>:fatal</tt>:: Raise a FatalWarning if the app writes to rack.errors.
+ # <tt>:lint</tt>:: If true, wrap the application in a Rack::Lint.
+
class MockRequest
class FatalWarning < RuntimeError
end
@@ -52,6 +65,7 @@ def request(method="GET", uri="", opts={})
MockResponse.new(*(app.call(env) + [errors]))
end
+ # Return the Rack environment used for a request to +uri+.
def self.env_for(uri="", opts={})
uri = URI(uri)
env = DEFAULT_ENV.dup
@@ -86,6 +100,10 @@ def self.env_for(uri="", opts={})
end
end
+ # Rack::MockResponse provides useful helpers for testing your apps.
+ # Usually, you don't create the MockResponse on your own, but use
+ # MockRequest.
+
class MockResponse
def initialize(status, headers, body, errors=StringIO.new(""))
@status = status.to_i
View
@@ -1,6 +1,12 @@
require 'uri'
module Rack
+ # Rack::ForwardRequest gets caught by Rack::Recursive and redirects
+ # the current request to the app at +url+.
+ #
+ # raise ForwardRequest.new("/not-found")
+ #
+
class ForwardRequest < Exception
attr_reader :url, :env
@@ -18,6 +24,11 @@ def initialize(url, env={})
end
end
+ # Rack::Recursive allows applications called down the chain to
+ # include data from other applications (by using
+ # <tt>rack['rack.recursive.include'][...]</tt> or raise a
+ # ForwardRequest to redirect internally.
+
class Recursive
def initialize(app)
@app = app
@@ -1,6 +1,12 @@
require 'thread'
module Rack
+ # Rack::Reloader checks on every request, but at most every +secs+
+ # seconds, if a file loaded changed, and reloads it, logging to
+ # rack.errors.
+ #
+ # It is recommended you use ShowExceptions to catch SyntaxErrors etc.
+
class Reloader
def initialize(app, secs=10)
@app = app
View
@@ -1,7 +1,16 @@
require 'rack/utils'
module Rack
+ # Rack::Request provides a convenient interface to a Rack
+ # environment. It is stateless, the environment +env+ passed to the
+ # constructor will be directly modified.
+ #
+ # req = Rack::Request.new(env)
+ # req.post?
+ # req.params["data"]
+
class Request
+ # The environment of the request.
attr_reader :env
def initialize(env)
@@ -29,6 +38,7 @@ def post?; request_method == "POST" end
def put?; request_method == "PUT" end
def delete?; request_method == "DELETE" end
+ # Returns the data recieved in the query string.
def GET
if @env["rack.request.query_string"] == query_string
@env["rack.request.query_hash"]
@@ -39,6 +49,10 @@ def GET
end
end
+ # Returns the data recieved in the request body.
+ #
+ # This method support both application/x-www-form-urlencoded and
+ # multipart/form-data.
def POST
if @env["rack.request.form_input"] == @env["rack.input"]
@env["rack.request.form_hash"]
@@ -53,6 +67,7 @@ def POST
end
end
+ # The union of GET and POST data.
def params
self.GET.update(self.POST)
end
@@ -74,6 +89,7 @@ def xhr?
@env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
end
+ # Tries to return a remake of the original request URL as a string.
def url
url = scheme + "://"
url << host
Oops, something went wrong. Retry.

0 comments on commit 376fa1e

Please sign in to comment.