qoobaa-rack 1.0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +18 -0
- data/KNOWN-ISSUES +18 -0
- data/RDOX +0 -0
- data/README +353 -0
- data/Rakefile +164 -0
- data/SPEC +164 -0
- data/bin/rackup +176 -0
- data/contrib/rack_logo.svg +111 -0
- data/example/lobster.ru +4 -0
- data/example/protectedlobster.rb +14 -0
- data/example/protectedlobster.ru +8 -0
- data/lib/rack/adapter/camping.rb +22 -0
- data/lib/rack/auth/abstract/handler.rb +37 -0
- data/lib/rack/auth/abstract/request.rb +37 -0
- data/lib/rack/auth/basic.rb +58 -0
- data/lib/rack/auth/digest/md5.rb +124 -0
- data/lib/rack/auth/digest/nonce.rb +51 -0
- data/lib/rack/auth/digest/params.rb +55 -0
- data/lib/rack/auth/digest/request.rb +40 -0
- data/lib/rack/auth/openid.rb +487 -0
- data/lib/rack/builder.rb +63 -0
- data/lib/rack/cascade.rb +41 -0
- data/lib/rack/chunked.rb +49 -0
- data/lib/rack/commonlogger.rb +52 -0
- data/lib/rack/conditionalget.rb +47 -0
- data/lib/rack/content_length.rb +29 -0
- data/lib/rack/content_type.rb +23 -0
- data/lib/rack/deflater.rb +96 -0
- data/lib/rack/directory.rb +153 -0
- data/lib/rack/file.rb +88 -0
- data/lib/rack/handler/cgi.rb +61 -0
- data/lib/rack/handler/evented_mongrel.rb +8 -0
- data/lib/rack/handler/fastcgi.rb +88 -0
- data/lib/rack/handler/lsws.rb +60 -0
- data/lib/rack/handler/mongrel.rb +87 -0
- data/lib/rack/handler/scgi.rb +62 -0
- data/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/lib/rack/handler/thin.rb +18 -0
- data/lib/rack/handler/webrick.rb +71 -0
- data/lib/rack/handler.rb +69 -0
- data/lib/rack/head.rb +19 -0
- data/lib/rack/lint.rb +546 -0
- data/lib/rack/lobster.rb +65 -0
- data/lib/rack/lock.rb +16 -0
- data/lib/rack/methodoverride.rb +27 -0
- data/lib/rack/mime.rb +204 -0
- data/lib/rack/mock.rb +187 -0
- data/lib/rack/recursive.rb +57 -0
- data/lib/rack/reloader.rb +107 -0
- data/lib/rack/request.rb +248 -0
- data/lib/rack/response.rb +183 -0
- data/lib/rack/rewindable_input.rb +100 -0
- data/lib/rack/session/abstract/id.rb +142 -0
- data/lib/rack/session/cookie.rb +91 -0
- data/lib/rack/session/memcache.rb +109 -0
- data/lib/rack/session/pool.rb +100 -0
- data/lib/rack/showexceptions.rb +349 -0
- data/lib/rack/showstatus.rb +106 -0
- data/lib/rack/static.rb +38 -0
- data/lib/rack/urlmap.rb +55 -0
- data/lib/rack/utils.rb +528 -0
- data/lib/rack.rb +90 -0
- data/rack.gemspec +60 -0
- data/test/cgi/lighttpd.conf +20 -0
- data/test/cgi/test +9 -0
- data/test/cgi/test.fcgi +8 -0
- data/test/cgi/test.ru +7 -0
- data/test/multipart/binary +0 -0
- data/test/multipart/empty +10 -0
- data/test/multipart/file1.txt +1 -0
- data/test/multipart/ie +6 -0
- data/test/multipart/nested +10 -0
- data/test/multipart/none +9 -0
- data/test/multipart/text +10 -0
- data/test/spec_rack_auth_basic.rb +73 -0
- data/test/spec_rack_auth_digest.rb +226 -0
- data/test/spec_rack_auth_openid.rb +84 -0
- data/test/spec_rack_builder.rb +84 -0
- data/test/spec_rack_camping.rb +51 -0
- data/test/spec_rack_cascade.rb +48 -0
- data/test/spec_rack_cgi.rb +89 -0
- data/test/spec_rack_chunked.rb +62 -0
- data/test/spec_rack_commonlogger.rb +61 -0
- data/test/spec_rack_conditionalget.rb +41 -0
- data/test/spec_rack_content_length.rb +43 -0
- data/test/spec_rack_content_type.rb +30 -0
- data/test/spec_rack_deflater.rb +127 -0
- data/test/spec_rack_directory.rb +61 -0
- data/test/spec_rack_fastcgi.rb +89 -0
- data/test/spec_rack_file.rb +75 -0
- data/test/spec_rack_handler.rb +43 -0
- data/test/spec_rack_head.rb +30 -0
- data/test/spec_rack_lint.rb +521 -0
- data/test/spec_rack_lobster.rb +45 -0
- data/test/spec_rack_lock.rb +38 -0
- data/test/spec_rack_methodoverride.rb +60 -0
- data/test/spec_rack_mock.rb +243 -0
- data/test/spec_rack_mongrel.rb +189 -0
- data/test/spec_rack_recursive.rb +77 -0
- data/test/spec_rack_request.rb +504 -0
- data/test/spec_rack_response.rb +218 -0
- data/test/spec_rack_rewindable_input.rb +118 -0
- data/test/spec_rack_session_cookie.rb +82 -0
- data/test/spec_rack_session_memcache.rb +250 -0
- data/test/spec_rack_session_pool.rb +172 -0
- data/test/spec_rack_showexceptions.rb +21 -0
- data/test/spec_rack_showstatus.rb +72 -0
- data/test/spec_rack_static.rb +37 -0
- data/test/spec_rack_thin.rb +91 -0
- data/test/spec_rack_urlmap.rb +185 -0
- data/test/spec_rack_utils.rb +467 -0
- data/test/spec_rack_webrick.rb +130 -0
- data/test/testrequest.rb +57 -0
- data/test/unregistered_handler/rack/handler/unregistered.rb +7 -0
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
- metadata +276 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'rack/request'
|
3
|
+
require 'rack/utils'
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
# Rack::ShowStatus catches all empty responses the app it wraps and
|
7
|
+
# replaces them with a site explaining the error.
|
8
|
+
#
|
9
|
+
# Additional details can be put into <tt>rack.showstatus.detail</tt>
|
10
|
+
# and will be shown as HTML. If such details exist, the error page
|
11
|
+
# is always rendered, even if the reply was not empty.
|
12
|
+
|
13
|
+
class ShowStatus
|
14
|
+
def initialize(app)
|
15
|
+
@app = app
|
16
|
+
@template = ERB.new(TEMPLATE)
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
status, headers, body = @app.call(env)
|
21
|
+
headers = Utils::HeaderHash.new(headers)
|
22
|
+
empty = headers['Content-Length'].to_i <= 0
|
23
|
+
|
24
|
+
# client or server error, or explicit message
|
25
|
+
if (status.to_i >= 400 && empty) || env["rack.showstatus.detail"]
|
26
|
+
req = Rack::Request.new(env)
|
27
|
+
message = Rack::Utils::HTTP_STATUS_CODES[status.to_i] || status.to_s
|
28
|
+
detail = env["rack.showstatus.detail"] || message
|
29
|
+
body = @template.result(binding)
|
30
|
+
size = Rack::Utils.bytesize(body)
|
31
|
+
[status, headers.merge("Content-Type" => "text/html", "Content-Length" => size.to_s), [body]]
|
32
|
+
else
|
33
|
+
[status, headers, body]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def h(obj) # :nodoc:
|
38
|
+
case obj
|
39
|
+
when String
|
40
|
+
Utils.escape_html(obj)
|
41
|
+
else
|
42
|
+
Utils.escape_html(obj.inspect)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# :stopdoc:
|
47
|
+
|
48
|
+
# adapted from Django <djangoproject.com>
|
49
|
+
# Copyright (c) 2005, the Lawrence Journal-World
|
50
|
+
# Used under the modified BSD license:
|
51
|
+
# http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
|
52
|
+
TEMPLATE = <<'HTML'
|
53
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
54
|
+
<html lang="en">
|
55
|
+
<head>
|
56
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
57
|
+
<title><%=h message %> at <%=h req.script_name + req.path_info %></title>
|
58
|
+
<meta name="robots" content="NONE,NOARCHIVE" />
|
59
|
+
<style type="text/css">
|
60
|
+
html * { padding:0; margin:0; }
|
61
|
+
body * { padding:10px 20px; }
|
62
|
+
body * * { padding:0; }
|
63
|
+
body { font:small sans-serif; background:#eee; }
|
64
|
+
body>div { border-bottom:1px solid #ddd; }
|
65
|
+
h1 { font-weight:normal; margin-bottom:.4em; }
|
66
|
+
h1 span { font-size:60%; color:#666; font-weight:normal; }
|
67
|
+
table { border:none; border-collapse: collapse; width:100%; }
|
68
|
+
td, th { vertical-align:top; padding:2px 3px; }
|
69
|
+
th { width:12em; text-align:right; color:#666; padding-right:.5em; }
|
70
|
+
#info { background:#f6f6f6; }
|
71
|
+
#info ol { margin: 0.5em 4em; }
|
72
|
+
#info ol li { font-family: monospace; }
|
73
|
+
#summary { background: #ffc; }
|
74
|
+
#explanation { background:#eee; border-bottom: 0px none; }
|
75
|
+
</style>
|
76
|
+
</head>
|
77
|
+
<body>
|
78
|
+
<div id="summary">
|
79
|
+
<h1><%=h message %> <span>(<%= status.to_i %>)</span></h1>
|
80
|
+
<table class="meta">
|
81
|
+
<tr>
|
82
|
+
<th>Request Method:</th>
|
83
|
+
<td><%=h req.request_method %></td>
|
84
|
+
</tr>
|
85
|
+
<tr>
|
86
|
+
<th>Request URL:</th>
|
87
|
+
<td><%=h req.url %></td>
|
88
|
+
</tr>
|
89
|
+
</table>
|
90
|
+
</div>
|
91
|
+
<div id="info">
|
92
|
+
<p><%= detail %></p>
|
93
|
+
</div>
|
94
|
+
|
95
|
+
<div id="explanation">
|
96
|
+
<p>
|
97
|
+
You're seeing this error because you use <code>Rack::ShowStatus</code>.
|
98
|
+
</p>
|
99
|
+
</div>
|
100
|
+
</body>
|
101
|
+
</html>
|
102
|
+
HTML
|
103
|
+
|
104
|
+
# :startdoc:
|
105
|
+
end
|
106
|
+
end
|
data/lib/rack/static.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Rack
|
2
|
+
|
3
|
+
# The Rack::Static middleware intercepts requests for static files
|
4
|
+
# (javascript files, images, stylesheets, etc) based on the url prefixes
|
5
|
+
# passed in the options, and serves them using a Rack::File object. This
|
6
|
+
# allows a Rack stack to serve both static and dynamic content.
|
7
|
+
#
|
8
|
+
# Examples:
|
9
|
+
# use Rack::Static, :urls => ["/media"]
|
10
|
+
# will serve all requests beginning with /media from the "media" folder
|
11
|
+
# located in the current directory (ie media/*).
|
12
|
+
#
|
13
|
+
# use Rack::Static, :urls => ["/css", "/images"], :root => "public"
|
14
|
+
# will serve all requests beginning with /css or /images from the folder
|
15
|
+
# "public" in the current directory (ie public/css/* and public/images/*)
|
16
|
+
|
17
|
+
class Static
|
18
|
+
|
19
|
+
def initialize(app, options={})
|
20
|
+
@app = app
|
21
|
+
@urls = options[:urls] || ["/favicon.ico"]
|
22
|
+
root = options[:root] || Dir.pwd
|
23
|
+
@file_server = Rack::File.new(root)
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(env)
|
27
|
+
path = env["PATH_INFO"]
|
28
|
+
can_serve = @urls.any? { |url| path.index(url) == 0 }
|
29
|
+
|
30
|
+
if can_serve
|
31
|
+
@file_server.call(env)
|
32
|
+
else
|
33
|
+
@app.call(env)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/lib/rack/urlmap.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Rack
|
2
|
+
# Rack::URLMap takes a hash mapping urls or paths to apps, and
|
3
|
+
# dispatches accordingly. Support for HTTP/1.1 host names exists if
|
4
|
+
# the URLs start with <tt>http://</tt> or <tt>https://</tt>.
|
5
|
+
#
|
6
|
+
# URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part
|
7
|
+
# relevant for dispatch is in the SCRIPT_NAME, and the rest in the
|
8
|
+
# PATH_INFO. This should be taken care of when you need to
|
9
|
+
# reconstruct the URL in order to create links.
|
10
|
+
#
|
11
|
+
# URLMap dispatches in such a way that the longest paths are tried
|
12
|
+
# first, since they are most specific.
|
13
|
+
|
14
|
+
class URLMap
|
15
|
+
def initialize(map = {})
|
16
|
+
remap(map)
|
17
|
+
end
|
18
|
+
|
19
|
+
def remap(map)
|
20
|
+
@mapping = map.map { |location, app|
|
21
|
+
if location =~ %r{\Ahttps?://(.*?)(/.*)}
|
22
|
+
host, location = $1, $2
|
23
|
+
else
|
24
|
+
host = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
unless location[0] == ?/
|
28
|
+
raise ArgumentError, "paths need to start with /"
|
29
|
+
end
|
30
|
+
location = location.chomp('/')
|
31
|
+
|
32
|
+
[host, location, app]
|
33
|
+
}.sort_by { |(h, l, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first
|
34
|
+
end
|
35
|
+
|
36
|
+
def call(env)
|
37
|
+
path = env["PATH_INFO"].to_s.squeeze("/")
|
38
|
+
script_name = env['SCRIPT_NAME']
|
39
|
+
hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
|
40
|
+
@mapping.each { |host, location, app|
|
41
|
+
next unless (hHost == host || sName == host \
|
42
|
+
|| (host.nil? && (hHost == sName || hHost == sName+':'+sPort)))
|
43
|
+
next unless location == path[0, location.size]
|
44
|
+
next unless path[location.size] == nil || path[location.size] == ?/
|
45
|
+
|
46
|
+
return app.call(
|
47
|
+
env.merge(
|
48
|
+
'SCRIPT_NAME' => (script_name + location),
|
49
|
+
'PATH_INFO' => path[location.size..-1]))
|
50
|
+
}
|
51
|
+
[404, {"Content-Type" => "text/plain"}, ["Not Found: #{path}"]]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|