kastner-rack 0.3.171

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. data/AUTHORS +8 -0
  2. data/COPYING +18 -0
  3. data/KNOWN-ISSUES +18 -0
  4. data/README +273 -0
  5. data/Rakefile +185 -0
  6. data/bin/rackup +172 -0
  7. data/contrib/rack_logo.svg +111 -0
  8. data/example/lobster.ru +4 -0
  9. data/example/protectedlobster.rb +14 -0
  10. data/example/protectedlobster.ru +8 -0
  11. data/lib/rack.rb +85 -0
  12. data/lib/rack/adapter/camping.rb +22 -0
  13. data/lib/rack/auth/abstract/handler.rb +28 -0
  14. data/lib/rack/auth/abstract/request.rb +37 -0
  15. data/lib/rack/auth/basic.rb +58 -0
  16. data/lib/rack/auth/digest/md5.rb +124 -0
  17. data/lib/rack/auth/digest/nonce.rb +51 -0
  18. data/lib/rack/auth/digest/params.rb +55 -0
  19. data/lib/rack/auth/digest/request.rb +40 -0
  20. data/lib/rack/auth/openid.rb +437 -0
  21. data/lib/rack/builder.rb +67 -0
  22. data/lib/rack/cascade.rb +36 -0
  23. data/lib/rack/commonlogger.rb +61 -0
  24. data/lib/rack/conditionalget.rb +42 -0
  25. data/lib/rack/deflater.rb +63 -0
  26. data/lib/rack/directory.rb +149 -0
  27. data/lib/rack/file.rb +84 -0
  28. data/lib/rack/handler.rb +46 -0
  29. data/lib/rack/handler/cgi.rb +57 -0
  30. data/lib/rack/handler/evented_mongrel.rb +8 -0
  31. data/lib/rack/handler/fastcgi.rb +86 -0
  32. data/lib/rack/handler/lsws.rb +52 -0
  33. data/lib/rack/handler/mongrel.rb +78 -0
  34. data/lib/rack/handler/scgi.rb +57 -0
  35. data/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  36. data/lib/rack/handler/webrick.rb +61 -0
  37. data/lib/rack/head.rb +19 -0
  38. data/lib/rack/lint.rb +463 -0
  39. data/lib/rack/lobster.rb +65 -0
  40. data/lib/rack/methodoverride.rb +21 -0
  41. data/lib/rack/mime.rb +204 -0
  42. data/lib/rack/mock.rb +160 -0
  43. data/lib/rack/recursive.rb +57 -0
  44. data/lib/rack/reloader.rb +64 -0
  45. data/lib/rack/request.rb +217 -0
  46. data/lib/rack/response.rb +171 -0
  47. data/lib/rack/session/abstract/id.rb +140 -0
  48. data/lib/rack/session/cookie.rb +89 -0
  49. data/lib/rack/session/memcache.rb +97 -0
  50. data/lib/rack/session/pool.rb +73 -0
  51. data/lib/rack/showexceptions.rb +348 -0
  52. data/lib/rack/showstatus.rb +105 -0
  53. data/lib/rack/static.rb +38 -0
  54. data/lib/rack/urlmap.rb +48 -0
  55. data/lib/rack/utils.rb +318 -0
  56. data/rack.gemspec +31 -0
  57. data/test/cgi/lighttpd.conf +20 -0
  58. data/test/cgi/test +9 -0
  59. data/test/cgi/test.fcgi +8 -0
  60. data/test/cgi/test.ru +7 -0
  61. data/test/spec_rack_auth_basic.rb +69 -0
  62. data/test/spec_rack_auth_digest.rb +169 -0
  63. data/test/spec_rack_auth_openid.rb +137 -0
  64. data/test/spec_rack_builder.rb +84 -0
  65. data/test/spec_rack_camping.rb +51 -0
  66. data/test/spec_rack_cascade.rb +50 -0
  67. data/test/spec_rack_cgi.rb +89 -0
  68. data/test/spec_rack_commonlogger.rb +32 -0
  69. data/test/spec_rack_conditionalget.rb +41 -0
  70. data/test/spec_rack_deflater.rb +70 -0
  71. data/test/spec_rack_directory.rb +56 -0
  72. data/test/spec_rack_fastcgi.rb +89 -0
  73. data/test/spec_rack_file.rb +57 -0
  74. data/test/spec_rack_handler.rb +24 -0
  75. data/test/spec_rack_head.rb +30 -0
  76. data/test/spec_rack_lint.rb +371 -0
  77. data/test/spec_rack_lobster.rb +45 -0
  78. data/test/spec_rack_methodoverride.rb +31 -0
  79. data/test/spec_rack_mock.rb +152 -0
  80. data/test/spec_rack_mongrel.rb +170 -0
  81. data/test/spec_rack_recursive.rb +77 -0
  82. data/test/spec_rack_request.rb +426 -0
  83. data/test/spec_rack_response.rb +173 -0
  84. data/test/spec_rack_session_cookie.rb +78 -0
  85. data/test/spec_rack_session_memcache.rb +132 -0
  86. data/test/spec_rack_session_pool.rb +84 -0
  87. data/test/spec_rack_showexceptions.rb +21 -0
  88. data/test/spec_rack_showstatus.rb +72 -0
  89. data/test/spec_rack_static.rb +37 -0
  90. data/test/spec_rack_urlmap.rb +175 -0
  91. data/test/spec_rack_utils.rb +174 -0
  92. data/test/spec_rack_webrick.rb +123 -0
  93. data/test/testrequest.rb +45 -0
  94. metadata +177 -0
@@ -0,0 +1,46 @@
1
+ module Rack
2
+ # *Handlers* connect web servers with Rack.
3
+ #
4
+ # Rack includes Handlers for Mongrel, WEBrick, FastCGI, CGI, SCGI
5
+ # and LiteSpeed.
6
+ #
7
+ # Handlers usually are activated by calling <tt>MyHandler.run(myapp)</tt>.
8
+ # A second optional hash can be passed to include server-specific
9
+ # configuration.
10
+ module Handler
11
+ def self.get(server)
12
+ return unless server
13
+
14
+ if klass = @handlers[server]
15
+ obj = Object
16
+ klass.split("::").each { |x| obj = obj.const_get(x) }
17
+ obj
18
+ else
19
+ Rack::Handler.const_get(server.capitalize)
20
+ end
21
+ end
22
+
23
+ def self.register(server, klass)
24
+ @handlers ||= {}
25
+ @handlers[server] = klass
26
+ end
27
+
28
+ autoload :CGI, "rack/handler/cgi"
29
+ autoload :FastCGI, "rack/handler/fastcgi"
30
+ autoload :Mongrel, "rack/handler/mongrel"
31
+ autoload :EventedMongrel, "rack/handler/evented_mongrel"
32
+ autoload :SwiftipliedMongrel, "rack/handler/swiftiplied_mongrel"
33
+ autoload :WEBrick, "rack/handler/webrick"
34
+ autoload :LSWS, "rack/handler/lsws"
35
+ autoload :SCGI, "rack/handler/scgi"
36
+
37
+ register 'cgi', 'Rack::Handler::CGI'
38
+ register 'fastcgi', 'Rack::Handler::FastCGI'
39
+ register 'mongrel', 'Rack::Handler::Mongrel'
40
+ register 'emongrel', 'Rack::Handler::EventedMongrel'
41
+ register 'smongrel', 'Rack::Handler::SwiftipliedMongrel'
42
+ register 'webrick', 'Rack::Handler::WEBrick'
43
+ register 'lsws', 'Rack::Handler::LSWS'
44
+ register 'scgi', 'Rack::Handler::SCGI'
45
+ end
46
+ end
@@ -0,0 +1,57 @@
1
+ module Rack
2
+ module Handler
3
+ class CGI
4
+ def self.run(app, options=nil)
5
+ serve app
6
+ end
7
+
8
+ def self.serve(app)
9
+ env = ENV.to_hash
10
+ env.delete "HTTP_CONTENT_LENGTH"
11
+
12
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
13
+
14
+ env.update({"rack.version" => [0,1],
15
+ "rack.input" => STDIN,
16
+ "rack.errors" => STDERR,
17
+
18
+ "rack.multithread" => false,
19
+ "rack.multiprocess" => true,
20
+ "rack.run_once" => true,
21
+
22
+ "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
23
+ })
24
+
25
+ env["QUERY_STRING"] ||= ""
26
+ env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
27
+ env["REQUEST_PATH"] ||= "/"
28
+
29
+ status, headers, body = app.call(env)
30
+ begin
31
+ send_headers status, headers
32
+ send_body body
33
+ ensure
34
+ body.close if body.respond_to? :close
35
+ end
36
+ end
37
+
38
+ def self.send_headers(status, headers)
39
+ STDOUT.print "Status: #{status}\r\n"
40
+ headers.each { |k, vs|
41
+ vs.each { |v|
42
+ STDOUT.print "#{k}: #{v}\r\n"
43
+ }
44
+ }
45
+ STDOUT.print "\r\n"
46
+ STDOUT.flush
47
+ end
48
+
49
+ def self.send_body(body)
50
+ body.each { |part|
51
+ STDOUT.print part
52
+ STDOUT.flush
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ require 'swiftcore/evented_mongrel'
2
+
3
+ module Rack
4
+ module Handler
5
+ class EventedMongrel < Handler::Mongrel
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,86 @@
1
+ require 'fcgi'
2
+ require 'socket'
3
+
4
+ module Rack
5
+ module Handler
6
+ class FastCGI
7
+ def self.run(app, options={})
8
+ file = options[:File] and STDIN.reopen(UNIXServer.new(file))
9
+ port = options[:Port] and STDIN.reopen(TCPServer.new(port))
10
+ FCGI.each { |request|
11
+ serve request, app
12
+ }
13
+ end
14
+
15
+ module ProperStream # :nodoc:
16
+ def each # This is missing by default.
17
+ while line = gets
18
+ yield line
19
+ end
20
+ end
21
+
22
+ def read(*args)
23
+ if args.empty?
24
+ super || "" # Empty string on EOF.
25
+ else
26
+ super
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.serve(request, app)
32
+ env = request.env
33
+ env.delete "HTTP_CONTENT_LENGTH"
34
+
35
+ request.in.extend ProperStream
36
+
37
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
38
+
39
+ env.update({"rack.version" => [0,1],
40
+ "rack.input" => request.in,
41
+ "rack.errors" => request.err,
42
+
43
+ "rack.multithread" => false,
44
+ "rack.multiprocess" => true,
45
+ "rack.run_once" => false,
46
+
47
+ "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
48
+ })
49
+
50
+ env["QUERY_STRING"] ||= ""
51
+ env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
52
+ env["REQUEST_PATH"] ||= "/"
53
+ env.delete "PATH_INFO" if env["PATH_INFO"] == ""
54
+ env.delete "CONTENT_TYPE" if env["CONTENT_TYPE"] == ""
55
+ env.delete "CONTENT_LENGTH" if env["CONTENT_LENGTH"] == ""
56
+
57
+ status, headers, body = app.call(env)
58
+ begin
59
+ send_headers request.out, status, headers
60
+ send_body request.out, body
61
+ ensure
62
+ body.close if body.respond_to? :close
63
+ request.finish
64
+ end
65
+ end
66
+
67
+ def self.send_headers(out, status, headers)
68
+ out.print "Status: #{status}\r\n"
69
+ headers.each { |k, vs|
70
+ vs.each { |v|
71
+ out.print "#{k}: #{v}\r\n"
72
+ }
73
+ }
74
+ out.print "\r\n"
75
+ out.flush
76
+ end
77
+
78
+ def self.send_body(out, body)
79
+ body.each { |part|
80
+ out.print part
81
+ out.flush
82
+ }
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,52 @@
1
+ require 'lsapi'
2
+ #require 'cgi'
3
+ module Rack
4
+ module Handler
5
+ class LSWS
6
+ def self.run(app, options=nil)
7
+ while LSAPI.accept != nil
8
+ serve app
9
+ end
10
+ end
11
+ def self.serve(app)
12
+ env = ENV.to_hash
13
+ env.delete "HTTP_CONTENT_LENGTH"
14
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
15
+ env.update({"rack.version" => [0,1],
16
+ "rack.input" => STDIN,
17
+ "rack.errors" => STDERR,
18
+ "rack.multithread" => false,
19
+ "rack.multiprocess" => true,
20
+ "rack.run_once" => false,
21
+ "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
22
+ })
23
+ env["QUERY_STRING"] ||= ""
24
+ env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
25
+ env["REQUEST_PATH"] ||= "/"
26
+ status, headers, body = app.call(env)
27
+ begin
28
+ send_headers status, headers
29
+ send_body body
30
+ ensure
31
+ body.close if body.respond_to? :close
32
+ end
33
+ end
34
+ def self.send_headers(status, headers)
35
+ print "Status: #{status}\r\n"
36
+ headers.each { |k, vs|
37
+ vs.each { |v|
38
+ print "#{k}: #{v}\r\n"
39
+ }
40
+ }
41
+ print "\r\n"
42
+ STDOUT.flush
43
+ end
44
+ def self.send_body(body)
45
+ body.each { |part|
46
+ print part
47
+ STDOUT.flush
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,78 @@
1
+ require 'mongrel'
2
+ require 'stringio'
3
+
4
+ module Rack
5
+ module Handler
6
+ class Mongrel < ::Mongrel::HttpHandler
7
+ def self.run(app, options={})
8
+ server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
9
+ options[:Port] || 8080)
10
+ # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
11
+ # Use is similar to #run, replacing the app argument with a hash of
12
+ # { path=>app, ... } or an instance of Rack::URLMap.
13
+ if options[:map]
14
+ if app.is_a? Hash
15
+ app.each do |path, appl|
16
+ path = '/'+path unless path[0] == ?/
17
+ server.register(path, Rack::Handler::Mongrel.new(appl))
18
+ end
19
+ elsif app.is_a? URLMap
20
+ app.instance_variable_get(:@mapping).each do |(host, path, appl)|
21
+ next if !host.nil? && !options[:Host].nil? && options[:Host] != host
22
+ path = '/'+path unless path[0] == ?/
23
+ server.register(path, Rack::Handler::Mongrel.new(appl))
24
+ end
25
+ else
26
+ raise ArgumentError, "first argument should be a Hash or URLMap"
27
+ end
28
+ else
29
+ server.register('/', Rack::Handler::Mongrel.new(app))
30
+ end
31
+ yield server if block_given?
32
+ server.run.join
33
+ end
34
+
35
+ def initialize(app)
36
+ @app = app
37
+ end
38
+
39
+ def process(request, response)
40
+ env = {}.replace(request.params)
41
+ env.delete "HTTP_CONTENT_TYPE"
42
+ env.delete "HTTP_CONTENT_LENGTH"
43
+
44
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
45
+
46
+ env.update({"rack.version" => [0,1],
47
+ "rack.input" => request.body || StringIO.new(""),
48
+ "rack.errors" => STDERR,
49
+
50
+ "rack.multithread" => true,
51
+ "rack.multiprocess" => false, # ???
52
+ "rack.run_once" => false,
53
+
54
+ "rack.url_scheme" => "http",
55
+ })
56
+ env["QUERY_STRING"] ||= ""
57
+ env.delete "PATH_INFO" if env["PATH_INFO"] == ""
58
+
59
+ status, headers, body = @app.call(env)
60
+
61
+ begin
62
+ response.status = status.to_i
63
+ headers.each { |k, vs|
64
+ vs.each { |v|
65
+ response.header[k] = v
66
+ }
67
+ }
68
+ body.each { |part|
69
+ response.body << part
70
+ }
71
+ response.finished
72
+ ensure
73
+ body.close if body.respond_to? :close
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,57 @@
1
+ require 'scgi'
2
+ require 'stringio'
3
+
4
+ module Rack
5
+ module Handler
6
+ class SCGI < ::SCGI::Processor
7
+ attr_accessor :app
8
+
9
+ def self.run(app, options=nil)
10
+ new(options.merge(:app=>app,
11
+ :host=>options[:Host],
12
+ :port=>options[:Port],
13
+ :socket=>options[:Socket])).listen
14
+ end
15
+
16
+ def initialize(settings = {})
17
+ @app = settings[:app]
18
+ @log = Object.new
19
+ def @log.info(*args); end
20
+ def @log.error(*args); end
21
+ super(settings)
22
+ end
23
+
24
+ def process_request(request, input_body, socket)
25
+ env = {}.replace(request)
26
+ env.delete "HTTP_CONTENT_TYPE"
27
+ env.delete "HTTP_CONTENT_LENGTH"
28
+ env["REQUEST_PATH"], env["QUERY_STRING"] = env["REQUEST_URI"].split('?', 2)
29
+ env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
30
+ env["PATH_INFO"] = env["REQUEST_PATH"]
31
+ env["QUERY_STRING"] ||= ""
32
+ env["SCRIPT_NAME"] = ""
33
+ env.update({"rack.version" => [0,1],
34
+ "rack.input" => StringIO.new(input_body),
35
+ "rack.errors" => STDERR,
36
+
37
+ "rack.multithread" => true,
38
+ "rack.multiprocess" => true,
39
+ "rack.run_once" => false,
40
+
41
+ "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
42
+ })
43
+ status, headers, body = app.call(env)
44
+ begin
45
+ socket.write("Status: #{status}\r\n")
46
+ headers.each do |k, vs|
47
+ vs.each {|v| socket.write("#{k}: #{v}\r\n")}
48
+ end
49
+ socket.write("\r\n")
50
+ body.each {|s| socket.write(s)}
51
+ ensure
52
+ body.close if body.respond_to? :close
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ require 'swiftcore/swiftiplied_mongrel'
2
+
3
+ module Rack
4
+ module Handler
5
+ class SwiftipliedMongrel < Handler::Mongrel
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,61 @@
1
+ require 'webrick'
2
+ require 'stringio'
3
+
4
+ module Rack
5
+ module Handler
6
+ class WEBrick < WEBrick::HTTPServlet::AbstractServlet
7
+ def self.run(app, options={})
8
+ server = ::WEBrick::HTTPServer.new(options)
9
+ server.mount "/", Rack::Handler::WEBrick, app
10
+ trap(:INT) { server.shutdown }
11
+ yield server if block_given?
12
+ server.start
13
+ end
14
+
15
+ def initialize(server, app)
16
+ super server
17
+ @app = app
18
+ end
19
+
20
+ def service(req, res)
21
+ env = req.meta_vars
22
+ env.delete_if { |k, v| v.nil? }
23
+
24
+ env.update({"rack.version" => [0,1],
25
+ "rack.input" => StringIO.new(req.body.to_s),
26
+ "rack.errors" => STDERR,
27
+
28
+ "rack.multithread" => true,
29
+ "rack.multiprocess" => false,
30
+ "rack.run_once" => false,
31
+
32
+ "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
33
+ })
34
+
35
+ env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
36
+ env["QUERY_STRING"] ||= ""
37
+ env["REQUEST_PATH"] ||= "/"
38
+ env.delete "PATH_INFO" if env["PATH_INFO"] == ""
39
+
40
+ status, headers, body = @app.call(env)
41
+ begin
42
+ res.status = status.to_i
43
+ headers.each { |k, vs|
44
+ if k.downcase == "set-cookie"
45
+ res.cookies.concat vs.to_a
46
+ else
47
+ vs.each { |v|
48
+ res[k] = v
49
+ }
50
+ end
51
+ }
52
+ body.each { |part|
53
+ res.body << part
54
+ }
55
+ ensure
56
+ body.close if body.respond_to? :close
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end