sinatra 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

Files changed (83) hide show
  1. data/CHANGELOG +1 -0
  2. data/LICENSE +22 -0
  3. data/Manifest +78 -1
  4. data/lib/sinatra.rb +12 -1
  5. data/sinatra.gemspec +7 -14
  6. data/vendor/rack/AUTHORS +7 -0
  7. data/vendor/rack/COPYING +18 -0
  8. data/vendor/rack/KNOWN-ISSUES +18 -0
  9. data/vendor/rack/README +242 -0
  10. data/vendor/rack/Rakefile +174 -0
  11. data/vendor/rack/bin/rackup +153 -0
  12. data/vendor/rack/contrib/rack_logo.svg +111 -0
  13. data/vendor/rack/example/lobster.ru +4 -0
  14. data/vendor/rack/example/protectedlobster.rb +14 -0
  15. data/vendor/rack/example/protectedlobster.ru +8 -0
  16. data/vendor/rack/lib/rack.rb +92 -0
  17. data/vendor/rack/lib/rack/adapter/camping.rb +22 -0
  18. data/vendor/rack/lib/rack/auth/abstract/handler.rb +28 -0
  19. data/vendor/rack/lib/rack/auth/abstract/request.rb +37 -0
  20. data/vendor/rack/lib/rack/auth/basic.rb +58 -0
  21. data/vendor/rack/lib/rack/auth/digest/md5.rb +124 -0
  22. data/vendor/rack/lib/rack/auth/digest/nonce.rb +51 -0
  23. data/vendor/rack/lib/rack/auth/digest/params.rb +55 -0
  24. data/vendor/rack/lib/rack/auth/digest/request.rb +40 -0
  25. data/vendor/rack/lib/rack/auth/openid.rb +116 -0
  26. data/vendor/rack/lib/rack/builder.rb +56 -0
  27. data/vendor/rack/lib/rack/cascade.rb +36 -0
  28. data/vendor/rack/lib/rack/commonlogger.rb +56 -0
  29. data/vendor/rack/lib/rack/file.rb +112 -0
  30. data/vendor/rack/lib/rack/handler/cgi.rb +57 -0
  31. data/vendor/rack/lib/rack/handler/fastcgi.rb +83 -0
  32. data/vendor/rack/lib/rack/handler/lsws.rb +52 -0
  33. data/vendor/rack/lib/rack/handler/mongrel.rb +78 -0
  34. data/vendor/rack/lib/rack/handler/scgi.rb +57 -0
  35. data/vendor/rack/lib/rack/handler/webrick.rb +57 -0
  36. data/vendor/rack/lib/rack/lint.rb +394 -0
  37. data/vendor/rack/lib/rack/lobster.rb +65 -0
  38. data/vendor/rack/lib/rack/mock.rb +160 -0
  39. data/vendor/rack/lib/rack/recursive.rb +57 -0
  40. data/vendor/rack/lib/rack/reloader.rb +64 -0
  41. data/vendor/rack/lib/rack/request.rb +197 -0
  42. data/vendor/rack/lib/rack/response.rb +166 -0
  43. data/vendor/rack/lib/rack/session/abstract/id.rb +126 -0
  44. data/vendor/rack/lib/rack/session/cookie.rb +71 -0
  45. data/vendor/rack/lib/rack/session/memcache.rb +83 -0
  46. data/vendor/rack/lib/rack/session/pool.rb +67 -0
  47. data/vendor/rack/lib/rack/showexceptions.rb +344 -0
  48. data/vendor/rack/lib/rack/showstatus.rb +103 -0
  49. data/vendor/rack/lib/rack/static.rb +38 -0
  50. data/vendor/rack/lib/rack/urlmap.rb +48 -0
  51. data/vendor/rack/lib/rack/utils.rb +240 -0
  52. data/vendor/rack/test/cgi/lighttpd.conf +20 -0
  53. data/vendor/rack/test/cgi/test +9 -0
  54. data/vendor/rack/test/cgi/test.fcgi +7 -0
  55. data/vendor/rack/test/cgi/test.ru +7 -0
  56. data/vendor/rack/test/spec_rack_auth_basic.rb +69 -0
  57. data/vendor/rack/test/spec_rack_auth_digest.rb +169 -0
  58. data/vendor/rack/test/spec_rack_builder.rb +50 -0
  59. data/vendor/rack/test/spec_rack_camping.rb +47 -0
  60. data/vendor/rack/test/spec_rack_cascade.rb +50 -0
  61. data/vendor/rack/test/spec_rack_cgi.rb +91 -0
  62. data/vendor/rack/test/spec_rack_commonlogger.rb +32 -0
  63. data/vendor/rack/test/spec_rack_fastcgi.rb +91 -0
  64. data/vendor/rack/test/spec_rack_file.rb +40 -0
  65. data/vendor/rack/test/spec_rack_lint.rb +317 -0
  66. data/vendor/rack/test/spec_rack_lobster.rb +45 -0
  67. data/vendor/rack/test/spec_rack_mock.rb +152 -0
  68. data/vendor/rack/test/spec_rack_mongrel.rb +165 -0
  69. data/vendor/rack/test/spec_rack_recursive.rb +77 -0
  70. data/vendor/rack/test/spec_rack_request.rb +384 -0
  71. data/vendor/rack/test/spec_rack_response.rb +167 -0
  72. data/vendor/rack/test/spec_rack_session_cookie.rb +49 -0
  73. data/vendor/rack/test/spec_rack_session_memcache.rb +100 -0
  74. data/vendor/rack/test/spec_rack_session_pool.rb +84 -0
  75. data/vendor/rack/test/spec_rack_showexceptions.rb +21 -0
  76. data/vendor/rack/test/spec_rack_showstatus.rb +71 -0
  77. data/vendor/rack/test/spec_rack_static.rb +37 -0
  78. data/vendor/rack/test/spec_rack_urlmap.rb +175 -0
  79. data/vendor/rack/test/spec_rack_utils.rb +57 -0
  80. data/vendor/rack/test/spec_rack_webrick.rb +106 -0
  81. data/vendor/rack/test/testrequest.rb +43 -0
  82. metadata +81 -4
  83. data/Rakefile +0 -24
@@ -0,0 +1,8 @@
1
+ require 'rack/lobster'
2
+
3
+ use Rack::ShowExceptions
4
+ use Rack::Auth::Basic do |username, password|
5
+ 'secret' == password
6
+ end
7
+
8
+ run Rack::Lobster.new
@@ -0,0 +1,92 @@
1
+ # Copyright (C) 2007, 2008 Christian Neukirchen <purl.org/net/chneukirchen>
2
+ #
3
+ # Rack is freely distributable under the terms of an MIT-style license.
4
+ # See COPYING or http://www.opensource.org/licenses/mit-license.php.
5
+
6
+ $: << File.expand_path(File.dirname(__FILE__))
7
+
8
+
9
+ # The Rack main module, serving as a namespace for all core Rack
10
+ # modules and classes.
11
+ #
12
+ # All modules meant for use in your application are <tt>autoload</tt>ed here,
13
+ # so it should be enough just to <tt>require rack.rb</tt> in your code.
14
+
15
+ module Rack
16
+ # The Rack protocol version number implemented.
17
+ VERSION = [0,1]
18
+
19
+ # Return the Rack protocol version as a dotted string.
20
+ def self.version
21
+ VERSION.join(".")
22
+ end
23
+
24
+ autoload :Builder, "rack/builder"
25
+ autoload :Cascade, "rack/cascade"
26
+ autoload :CommonLogger, "rack/commonlogger"
27
+ autoload :File, "rack/file"
28
+ autoload :ForwardRequest, "rack/recursive"
29
+ autoload :Lint, "rack/lint"
30
+ autoload :Recursive, "rack/recursive"
31
+ autoload :Reloader, "rack/reloader"
32
+ autoload :ShowExceptions, "rack/showexceptions"
33
+ autoload :ShowStatus, "rack/showstatus"
34
+ autoload :Static, "rack/static"
35
+ autoload :URLMap, "rack/urlmap"
36
+ autoload :Utils, "rack/utils"
37
+
38
+ autoload :MockRequest, "rack/mock"
39
+ autoload :MockResponse, "rack/mock"
40
+
41
+ autoload :Request, "rack/request"
42
+ autoload :Response, "rack/response"
43
+
44
+ module Auth
45
+ autoload :Basic, "rack/auth/basic"
46
+ autoload :AbstractRequest, "rack/auth/abstract/request"
47
+ autoload :AbstractHandler, "rack/auth/abstract/handler"
48
+ autoload :OpenID, "rack/auth/openid"
49
+ module Digest
50
+ autoload :MD5, "rack/auth/digest/md5"
51
+ autoload :Nonce, "rack/auth/digest/nonce"
52
+ autoload :Params, "rack/auth/digest/params"
53
+ autoload :Request, "rack/auth/digest/request"
54
+ end
55
+ end
56
+
57
+ module Session
58
+ autoload :Cookie, "rack/session/cookie"
59
+ autoload :Pool, "rack/session/pool"
60
+ autoload :Memcache, "rack/session/memcache"
61
+ end
62
+
63
+ # *Adapters* connect Rack with third party web frameworks.
64
+ #
65
+ # Rack includes an adapter for Camping, see README for other
66
+ # frameworks supporting Rack in their code bases.
67
+ #
68
+ # Refer to the submodules for framework-specific calling details.
69
+
70
+ module Adapter
71
+ autoload :Camping, "rack/adapter/camping"
72
+ end
73
+
74
+ # *Handlers* connect web servers with Rack.
75
+ #
76
+ # Rack includes Handlers for Mongrel, WEBrick, FastCGI, CGI, SCGI
77
+ # and LiteSpeed.
78
+ #
79
+ # Handlers usually are activated by calling <tt>MyHandler.run(myapp)</tt>.
80
+ # A second optional hash can be passed to include server-specific
81
+ # configuration.
82
+
83
+ module Handler
84
+ autoload :CGI, "rack/handler/cgi"
85
+ autoload :FastCGI, "rack/handler/fastcgi"
86
+ autoload :Mongrel, "rack/handler/mongrel"
87
+ autoload :WEBrick, "rack/handler/webrick"
88
+ autoload :LSWS, "rack/handler/lsws"
89
+ autoload :SCGI, "rack/handler/scgi"
90
+ end
91
+ end
92
+
@@ -0,0 +1,22 @@
1
+ module Rack
2
+ module Adapter
3
+ class Camping
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ env["PATH_INFO"] ||= ""
10
+ env["SCRIPT_NAME"] ||= ""
11
+ controller = @app.run(env['rack.input'], env)
12
+ h = controller.headers
13
+ h.each_pair do |k,v|
14
+ if v.kind_of? URI
15
+ h[k] = v.to_s
16
+ end
17
+ end
18
+ [controller.status, controller.headers, controller.body]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ module Rack
2
+ module Auth
3
+ # Rack::Auth::AbstractHandler implements common authentication functionality.
4
+ #
5
+ # +realm+ should be set for all handlers.
6
+
7
+ class AbstractHandler
8
+
9
+ attr_accessor :realm
10
+
11
+ def initialize(app, &authenticator)
12
+ @app, @authenticator = app, authenticator
13
+ end
14
+
15
+
16
+ private
17
+
18
+ def unauthorized(www_authenticate = challenge)
19
+ return [ 401, { 'WWW-Authenticate' => www_authenticate.to_s }, [] ]
20
+ end
21
+
22
+ def bad_request
23
+ [ 400, {}, [] ]
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,37 @@
1
+ module Rack
2
+ module Auth
3
+ class AbstractRequest
4
+
5
+ def initialize(env)
6
+ @env = env
7
+ end
8
+
9
+ def provided?
10
+ !authorization_key.nil?
11
+ end
12
+
13
+ def parts
14
+ @parts ||= @env[authorization_key].split(' ', 2)
15
+ end
16
+
17
+ def scheme
18
+ @scheme ||= parts.first.downcase.to_sym
19
+ end
20
+
21
+ def params
22
+ @params ||= parts.last
23
+ end
24
+
25
+
26
+ private
27
+
28
+ AUTHORIZATION_KEYS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION']
29
+
30
+ def authorization_key
31
+ @authorization_key ||= AUTHORIZATION_KEYS.detect { |key| @env.has_key?(key) }
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,58 @@
1
+ require 'rack/auth/abstract/handler'
2
+ require 'rack/auth/abstract/request'
3
+
4
+ module Rack
5
+ module Auth
6
+ # Rack::Auth::Basic implements HTTP Basic Authentication, as per RFC 2617.
7
+ #
8
+ # Initialize with the Rack application that you want protecting,
9
+ # and a block that checks if a username and password pair are valid.
10
+ #
11
+ # See also: <tt>example/protectedlobster.rb</tt>
12
+
13
+ class Basic < AbstractHandler
14
+
15
+ def call(env)
16
+ auth = Basic::Request.new(env)
17
+
18
+ return unauthorized unless auth.provided?
19
+
20
+ return bad_request unless auth.basic?
21
+
22
+ if valid?(auth)
23
+ env['REMOTE_USER'] = auth.username
24
+
25
+ return @app.call(env)
26
+ end
27
+
28
+ unauthorized
29
+ end
30
+
31
+
32
+ private
33
+
34
+ def challenge
35
+ 'Basic realm="%s"' % realm
36
+ end
37
+
38
+ def valid?(auth)
39
+ @authenticator.call(*auth.credentials)
40
+ end
41
+
42
+ class Request < Auth::AbstractRequest
43
+ def basic?
44
+ :basic == scheme
45
+ end
46
+
47
+ def credentials
48
+ @credentials ||= params.unpack("m*").first.split(/:/, 2)
49
+ end
50
+
51
+ def username
52
+ credentials.first
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,124 @@
1
+ require 'rack/auth/abstract/handler'
2
+ require 'rack/auth/digest/request'
3
+ require 'rack/auth/digest/params'
4
+ require 'rack/auth/digest/nonce'
5
+ require 'digest/md5'
6
+
7
+ module Rack
8
+ module Auth
9
+ module Digest
10
+ # Rack::Auth::Digest::MD5 implements the MD5 algorithm version of
11
+ # HTTP Digest Authentication, as per RFC 2617.
12
+ #
13
+ # Initialize with the [Rack] application that you want protecting,
14
+ # and a block that looks up a plaintext password for a given username.
15
+ #
16
+ # +opaque+ needs to be set to a constant base64/hexadecimal string.
17
+ #
18
+ class MD5 < AbstractHandler
19
+
20
+ attr_accessor :opaque
21
+
22
+ attr_writer :passwords_hashed
23
+
24
+ def initialize(app)
25
+ super
26
+ @passwords_hashed = nil
27
+ end
28
+
29
+ def passwords_hashed?
30
+ !!@passwords_hashed
31
+ end
32
+
33
+ def call(env)
34
+ auth = Request.new(env)
35
+
36
+ unless auth.provided?
37
+ return unauthorized
38
+ end
39
+
40
+ if !auth.digest? || !auth.correct_uri? || !valid_qop?(auth)
41
+ return bad_request
42
+ end
43
+
44
+ if valid?(auth)
45
+ if auth.nonce.stale?
46
+ return unauthorized(challenge(:stale => true))
47
+ else
48
+ env['REMOTE_USER'] = auth.username
49
+
50
+ return @app.call(env)
51
+ end
52
+ end
53
+
54
+ unauthorized
55
+ end
56
+
57
+
58
+ private
59
+
60
+ QOP = 'auth'.freeze
61
+
62
+ def params(hash = {})
63
+ Params.new do |params|
64
+ params['realm'] = realm
65
+ params['nonce'] = Nonce.new.to_s
66
+ params['opaque'] = H(opaque)
67
+ params['qop'] = QOP
68
+
69
+ hash.each { |k, v| params[k] = v }
70
+ end
71
+ end
72
+
73
+ def challenge(hash = {})
74
+ "Digest #{params(hash)}"
75
+ end
76
+
77
+ def valid?(auth)
78
+ valid_opaque?(auth) && valid_nonce?(auth) && valid_digest?(auth)
79
+ end
80
+
81
+ def valid_qop?(auth)
82
+ QOP == auth.qop
83
+ end
84
+
85
+ def valid_opaque?(auth)
86
+ H(opaque) == auth.opaque
87
+ end
88
+
89
+ def valid_nonce?(auth)
90
+ auth.nonce.valid?
91
+ end
92
+
93
+ def valid_digest?(auth)
94
+ digest(auth, @authenticator.call(auth.username)) == auth.response
95
+ end
96
+
97
+ def md5(data)
98
+ ::Digest::MD5.hexdigest(data)
99
+ end
100
+
101
+ alias :H :md5
102
+
103
+ def KD(secret, data)
104
+ H([secret, data] * ':')
105
+ end
106
+
107
+ def A1(auth, password)
108
+ [ auth.username, auth.realm, password ] * ':'
109
+ end
110
+
111
+ def A2(auth)
112
+ [ auth.method, auth.uri ] * ':'
113
+ end
114
+
115
+ def digest(auth, password)
116
+ password_hash = passwords_hashed? ? password : H(A1(auth, password))
117
+
118
+ KD(password_hash, [ auth.nonce, auth.nc, auth.cnonce, QOP, H(A2(auth)) ] * ':')
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,51 @@
1
+ require 'digest/md5'
2
+
3
+ module Rack
4
+ module Auth
5
+ module Digest
6
+ # Rack::Auth::Digest::Nonce is the default nonce generator for the
7
+ # Rack::Auth::Digest::MD5 authentication handler.
8
+ #
9
+ # +private_key+ needs to set to a constant string.
10
+ #
11
+ # +time_limit+ can be optionally set to an integer (number of seconds),
12
+ # to limit the validity of the generated nonces.
13
+
14
+ class Nonce
15
+
16
+ class << self
17
+ attr_accessor :private_key, :time_limit
18
+ end
19
+
20
+ def self.parse(string)
21
+ new(*string.unpack("m*").first.split(' ', 2))
22
+ end
23
+
24
+ def initialize(timestamp = Time.now, given_digest = nil)
25
+ @timestamp, @given_digest = timestamp.to_i, given_digest
26
+ end
27
+
28
+ def to_s
29
+ [([ @timestamp, digest ] * ' ')].pack("m*").strip
30
+ end
31
+
32
+ def digest
33
+ ::Digest::MD5.hexdigest([ @timestamp, self.class.private_key ] * ':')
34
+ end
35
+
36
+ def valid?
37
+ digest == @given_digest
38
+ end
39
+
40
+ def stale?
41
+ !self.class.time_limit.nil? && (@timestamp - Time.now.to_i) < self.class.time_limit
42
+ end
43
+
44
+ def fresh?
45
+ !stale?
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ module Rack
2
+ module Auth
3
+ module Digest
4
+ class Params < Hash
5
+
6
+ def self.parse(str)
7
+ split_header_value(str).inject(new) do |header, param|
8
+ k, v = param.split('=', 2)
9
+ header[k] = dequote(v)
10
+ header
11
+ end
12
+ end
13
+
14
+ def self.dequote(str) # From WEBrick::HTTPUtils
15
+ ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
16
+ ret.gsub!(/\\(.)/, "\\1")
17
+ ret
18
+ end
19
+
20
+ def self.split_header_value(str) # From WEBrick::HTTPUtils
21
+ str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+)(?:,\s*|\Z)/n).collect{ |v| v[0] }
22
+ end
23
+
24
+ def initialize
25
+ super
26
+
27
+ yield self if block_given?
28
+ end
29
+
30
+ def [](k)
31
+ super k.to_s
32
+ end
33
+
34
+ def []=(k, v)
35
+ super k.to_s, v.to_s
36
+ end
37
+
38
+ UNQUOTED = ['qop', 'nc', 'stale']
39
+
40
+ def to_s
41
+ inject([]) do |parts, (k, v)|
42
+ parts << "#{k}=" + (UNQUOTED.include?(k) ? v.to_s : quote(v))
43
+ parts
44
+ end.join(', ')
45
+ end
46
+
47
+ def quote(str) # From WEBrick::HTTPUtils
48
+ '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
49
+ end
50
+
51
+ end
52
+ end
53
+ end
54
+ end
55
+