passenger 2.2.1 → 2.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 passenger might be problematic. Click here for more details.

Files changed (216) hide show
  1. data/Rakefile +66 -79
  2. data/bin/passenger-install-nginx-module +1 -1
  3. data/bin/passenger-memory-stats +1 -1
  4. data/bin/passenger-spawn-server +8 -2
  5. data/doc/Users guide Apache.html +33 -49
  6. data/doc/Users guide Apache.txt +28 -27
  7. data/doc/Users guide Nginx.html +9 -19
  8. data/doc/Users guide Nginx.txt +8 -20
  9. data/doc/cxxapi/Bucket_8h-source.html +1 -1
  10. data/doc/cxxapi/Configuration_8h-source.html +297 -300
  11. data/doc/cxxapi/DirectoryMapper_8h-source.html +1 -1
  12. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  13. data/doc/cxxapi/annotated.html +1 -1
  14. data/doc/cxxapi/classHooks-members.html +1 -1
  15. data/doc/cxxapi/classHooks.html +1 -1
  16. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +1 -1
  17. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +1 -1
  18. data/doc/cxxapi/classes.html +1 -1
  19. data/doc/cxxapi/definitions_8h-source.html +1 -1
  20. data/doc/cxxapi/files.html +1 -1
  21. data/doc/cxxapi/functions.html +1 -1
  22. data/doc/cxxapi/functions_func.html +1 -1
  23. data/doc/cxxapi/graph_legend.html +1 -1
  24. data/doc/cxxapi/group__Configuration.html +1 -23
  25. data/doc/cxxapi/group__Core.html +1 -1
  26. data/doc/cxxapi/group__Hooks.html +1 -1
  27. data/doc/cxxapi/group__Support.html +1 -1
  28. data/doc/cxxapi/main.html +1 -1
  29. data/doc/cxxapi/modules.html +1 -1
  30. data/doc/users_guide_snippets/rackup_specifications.txt +4 -2
  31. data/ext/apache2/Configuration.h +0 -3
  32. data/ext/apache2/Hooks.cpp +5 -3
  33. data/ext/common/ApplicationPoolServer.h +1 -0
  34. data/ext/common/ApplicationPoolServerExecutable.cpp +5 -2
  35. data/ext/common/SpawnManager.h +1 -0
  36. data/ext/common/Utils.cpp +22 -23
  37. data/ext/common/Utils.h +32 -21
  38. data/ext/common/Version.h +31 -0
  39. data/ext/nginx/ContentHandler.c +61 -8
  40. data/ext/nginx/HelperServer.cpp +3 -0
  41. data/ext/nginx/HttpStatusExtractor.h +185 -0
  42. data/ext/nginx/StaticContentHandler.c +18 -3
  43. data/ext/nginx/config +2 -1
  44. data/ext/nginx/ngx_http_passenger_module.c +21 -15
  45. data/ext/oxt/backtrace.cpp +4 -2
  46. data/ext/oxt/spin_lock.hpp +3 -3
  47. data/lib/phusion_passenger/abstract_request_handler.rb +5 -3
  48. data/lib/phusion_passenger/admin_tools/control_process.rb +6 -1
  49. data/lib/phusion_passenger/constants.rb +2 -2
  50. data/lib/phusion_passenger/rack/application_spawner.rb +2 -1
  51. data/lib/phusion_passenger/rack/request_handler.rb +45 -35
  52. data/lib/phusion_passenger/templates/nginx/config_snippets.txt.erb +1 -1
  53. data/lib/phusion_passenger/utils.rb +13 -3
  54. data/misc/rake/cplusplus.rb +7 -0
  55. data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +2 -0
  56. data/test/ApplicationPoolTest.cpp +39 -62
  57. data/test/CxxTestMain.cpp +6 -6
  58. data/test/HttpStatusExtractorTest.cpp +17 -0
  59. data/test/StandardApplicationPoolTest.cpp +2 -0
  60. data/test/UtilsTest.cpp +17 -28
  61. data/test/ruby/abstract_request_handler_spec.rb +3 -7
  62. data/test/ruby/utils_spec.rb +18 -13
  63. data/test/ruby/wsgi/application_spawner_spec.rb +5 -9
  64. data/test/stub/railsapp/app/controllers/{bar_controller_1.rb → bar_controller.rb} +0 -0
  65. data/test/stub/railsapp/app/controllers/bar_controller_1.txt +5 -0
  66. data/test/stub/railsapp/app/controllers/{bar_controller_2.rb → bar_controller_2.txt} +0 -0
  67. data/test/support/Support.h +20 -0
  68. data/test/support/config.rb +13 -0
  69. data/vendor/README +4 -3
  70. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/COPYING +1 -1
  71. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/KNOWN-ISSUES +0 -0
  72. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/README +54 -7
  73. data/vendor/rack-1.0.0-git/Rakefile +164 -0
  74. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack.rb +7 -3
  75. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/adapter/camping.rb +0 -0
  76. data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/handler.rb +37 -0
  77. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/auth/abstract/request.rb +0 -0
  78. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/auth/basic.rb +0 -0
  79. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/auth/digest/md5.rb +1 -1
  80. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/auth/digest/nonce.rb +0 -0
  81. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/auth/digest/params.rb +0 -0
  82. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/auth/digest/request.rb +2 -2
  83. data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +480 -0
  84. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/builder.rb +1 -5
  85. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/cascade.rb +0 -0
  86. data/vendor/rack-1.0.0-git/lib/rack/chunked.rb +49 -0
  87. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/commonlogger.rb +0 -0
  88. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/conditionalget.rb +4 -0
  89. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/content_length.rb +7 -3
  90. data/vendor/rack-1.0.0-git/lib/rack/content_type.rb +23 -0
  91. data/vendor/rack-1.0.0-git/lib/rack/deflater.rb +96 -0
  92. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/directory.rb +5 -2
  93. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/file.rb +4 -1
  94. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler.rb +22 -1
  95. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/cgi.rb +7 -3
  96. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/evented_mongrel.rb +0 -0
  97. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/fastcgi.rb +26 -24
  98. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/lsws.rb +7 -4
  99. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/mongrel.rb +5 -3
  100. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/scgi.rb +5 -3
  101. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/swiftiplied_mongrel.rb +0 -0
  102. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/thin.rb +3 -0
  103. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/handler/webrick.rb +11 -5
  104. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/head.rb +0 -0
  105. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/lint.rb +138 -66
  106. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/lobster.rb +0 -0
  107. data/vendor/rack-1.0.0-git/lib/rack/lock.rb +16 -0
  108. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/methodoverride.rb +0 -0
  109. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/mime.rb +4 -4
  110. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/mock.rb +42 -5
  111. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/recursive.rb +0 -0
  112. data/vendor/rack-1.0.0-git/lib/rack/reloader.rb +106 -0
  113. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/request.rb +46 -10
  114. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/response.rb +15 -3
  115. data/vendor/rack-1.0.0-git/lib/rack/rewindable_input.rb +98 -0
  116. data/vendor/rack-1.0.0-git/lib/rack/session/abstract/id.rb +142 -0
  117. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/session/cookie.rb +2 -0
  118. data/vendor/rack-1.0.0-git/lib/rack/session/memcache.rb +109 -0
  119. data/vendor/rack-1.0.0-git/lib/rack/session/pool.rb +100 -0
  120. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/showexceptions.rb +2 -1
  121. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/showstatus.rb +1 -1
  122. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/static.rb +0 -0
  123. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/urlmap.rb +12 -5
  124. data/vendor/{rack-0.9.1 → rack-1.0.0-git}/lib/rack/utils.rb +212 -65
  125. metadata +71 -170
  126. data/doc/rdoc/classes/ConditionVariable.html +0 -194
  127. data/doc/rdoc/classes/Exception.html +0 -120
  128. data/doc/rdoc/classes/GC.html +0 -113
  129. data/doc/rdoc/classes/IO.html +0 -169
  130. data/doc/rdoc/classes/PhusionPassenger.html +0 -238
  131. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +0 -153
  132. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +0 -506
  133. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +0 -692
  134. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +0 -97
  135. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +0 -96
  136. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +0 -97
  137. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +0 -96
  138. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +0 -598
  139. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +0 -140
  140. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +0 -264
  141. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +0 -138
  142. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +0 -154
  143. data/doc/rdoc/classes/PhusionPassenger/Application.html +0 -283
  144. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +0 -172
  145. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +0 -145
  146. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +0 -175
  147. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +0 -141
  148. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +0 -92
  149. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +0 -489
  150. data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +0 -350
  151. data/doc/rdoc/classes/PhusionPassenger/Rack.html +0 -91
  152. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +0 -185
  153. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +0 -184
  154. data/doc/rdoc/classes/PhusionPassenger/Railz.html +0 -95
  155. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +0 -419
  156. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +0 -98
  157. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +0 -200
  158. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +0 -443
  159. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +0 -98
  160. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +0 -154
  161. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +0 -402
  162. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +0 -125
  163. data/doc/rdoc/classes/PhusionPassenger/Utils.html +0 -694
  164. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +0 -140
  165. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +0 -89
  166. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +0 -188
  167. data/doc/rdoc/classes/PlatformInfo.html +0 -831
  168. data/doc/rdoc/classes/RakeExtensions.html +0 -197
  169. data/doc/rdoc/classes/Signal.html +0 -134
  170. data/doc/rdoc/created.rid +0 -1
  171. data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -240
  172. data/doc/rdoc/files/README.html +0 -157
  173. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +0 -92
  174. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +0 -129
  175. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +0 -131
  176. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +0 -126
  177. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +0 -130
  178. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +0 -129
  179. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +0 -122
  180. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +0 -127
  181. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +0 -126
  182. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +0 -122
  183. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +0 -134
  184. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +0 -122
  185. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +0 -122
  186. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +0 -126
  187. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +0 -122
  188. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +0 -122
  189. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +0 -127
  190. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +0 -133
  191. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +0 -126
  192. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +0 -143
  193. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +0 -126
  194. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +0 -145
  195. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +0 -127
  196. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +0 -122
  197. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +0 -161
  198. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +0 -175
  199. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +0 -129
  200. data/doc/rdoc/files/misc/rake/extensions_rb.html +0 -130
  201. data/doc/rdoc/fr_class_index.html +0 -90
  202. data/doc/rdoc/fr_file_index.html +0 -76
  203. data/doc/rdoc/fr_method_index.html +0 -195
  204. data/doc/rdoc/index.html +0 -26
  205. data/doc/rdoc/rdoc-style.css +0 -187
  206. data/vendor/rack-0.9.1/AUTHORS +0 -8
  207. data/vendor/rack-0.9.1/ChangeLog +0 -1423
  208. data/vendor/rack-0.9.1/Rakefile +0 -188
  209. data/vendor/rack-0.9.1/SPEC +0 -129
  210. data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +0 -28
  211. data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +0 -438
  212. data/vendor/rack-0.9.1/lib/rack/deflater.rb +0 -87
  213. data/vendor/rack-0.9.1/lib/rack/reloader.rb +0 -64
  214. data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +0 -153
  215. data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +0 -97
  216. data/vendor/rack-0.9.1/lib/rack/session/pool.rb +0 -73
@@ -1,188 +0,0 @@
1
- # Rakefile for Rack. -*-ruby-*-
2
- require 'rake/rdoctask'
3
- require 'rake/testtask'
4
-
5
-
6
- desc "Run all the tests"
7
- task :default => [:test]
8
-
9
- desc "Do predistribution stuff"
10
- task :predist => [:chmod, :changelog, :rdoc]
11
-
12
-
13
- desc "Make an archive as .tar.gz"
14
- task :dist => [:fulltest, :predist] do
15
- sh "git archive --format=tar --prefix=#{release}/ HEAD^{tree} >#{release}.tar"
16
- sh "pax -waf #{release}.tar -s ':^:#{release}/:' RDOX SPEC ChangeLog doc"
17
- sh "gzip -f -9 #{release}.tar"
18
- end
19
-
20
- # Helper to retrieve the "revision number" of the git tree.
21
- def git_tree_version
22
- if File.directory?(".git")
23
- @tree_version ||= `git describe`.strip.sub('-', '.')
24
- @tree_version << ".0" unless @tree_version.count('.') == 2
25
- else
26
- $: << "lib"
27
- require 'rack'
28
- @tree_version = Rack.release
29
- end
30
- @tree_version
31
- end
32
-
33
- def gem_version
34
- git_tree_version.gsub(/-.*/, '')
35
- end
36
-
37
- def release
38
- "rack-#{git_tree_version}"
39
- end
40
-
41
- def manifest
42
- `git ls-files`.split("\n")
43
- end
44
-
45
-
46
- desc "Make binaries executable"
47
- task :chmod do
48
- Dir["bin/*"].each { |binary| File.chmod(0775, binary) }
49
- Dir["test/cgi/test*"].each { |binary| File.chmod(0775, binary) }
50
- end
51
-
52
- desc "Generate a ChangeLog"
53
- task :changelog do
54
- File.open("ChangeLog", "w") { |out|
55
- `git log -z`.split("\0").map { |chunk|
56
- author = chunk[/Author: (.*)/, 1].strip
57
- date = chunk[/Date: (.*)/, 1].strip
58
- desc, detail = $'.strip.split("\n", 2)
59
- detail ||= ""
60
- detail = detail.gsub(/.*darcs-hash:.*/, '')
61
- detail.rstrip!
62
- out.puts "#{date} #{author}"
63
- out.puts " * #{desc.strip}"
64
- out.puts detail unless detail.empty?
65
- out.puts
66
- }
67
- }
68
- end
69
-
70
-
71
- desc "Generate RDox"
72
- task "RDOX" do
73
- sh "specrb -Ilib:test -a --rdox >RDOX"
74
- end
75
-
76
- desc "Generate Rack Specification"
77
- task "SPEC" do
78
- File.open("SPEC", "wb") { |file|
79
- IO.foreach("lib/rack/lint.rb") { |line|
80
- if line =~ /## (.*)/
81
- file.puts $1
82
- end
83
- }
84
- }
85
- end
86
-
87
- desc "Run all the fast tests"
88
- task :test do
89
- sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS'] || '-t "^(?!Rack::Handler|Rack::Adapter|Rack::Session::Memcache|Rack::Auth::OpenID)"'}"
90
- end
91
-
92
- desc "Run all the tests"
93
- task :fulltest => [:chmod] do
94
- sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS']}"
95
- end
96
-
97
- begin
98
- require 'rubygems'
99
-
100
- require 'rake'
101
- require 'rake/clean'
102
- require 'rake/packagetask'
103
- require 'rake/gempackagetask'
104
- require 'fileutils'
105
- rescue LoadError
106
- # Too bad.
107
- else
108
- spec = Gem::Specification.new do |s|
109
- s.name = "rack"
110
- s.version = gem_version
111
- s.platform = Gem::Platform::RUBY
112
- s.summary = "a modular Ruby webserver interface"
113
-
114
- s.description = <<-EOF
115
- Rack provides minimal, modular and adaptable interface for developing
116
- web applications in Ruby. By wrapping HTTP requests and responses in
117
- the simplest way possible, it unifies and distills the API for web
118
- servers, web frameworks, and software in between (the so-called
119
- middleware) into a single method call.
120
-
121
- Also see http://rack.rubyforge.org.
122
- EOF
123
-
124
- s.files = manifest + %w(SPEC RDOX)
125
- s.bindir = 'bin'
126
- s.executables << 'rackup'
127
- s.require_path = 'lib'
128
- s.has_rdoc = true
129
- s.extra_rdoc_files = ['README', 'SPEC', 'RDOX', 'KNOWN-ISSUES']
130
- s.test_files = Dir['test/{test,spec}_*.rb']
131
-
132
- s.author = 'Christian Neukirchen'
133
- s.email = 'chneukirchen@gmail.com'
134
- s.homepage = 'http://rack.rubyforge.org'
135
- s.rubyforge_project = 'rack'
136
-
137
- s.add_development_dependency 'test-spec'
138
-
139
- s.add_development_dependency 'camping'
140
- s.add_development_dependency 'fcgi'
141
- s.add_development_dependency 'memcache-client'
142
- s.add_development_dependency 'mongrel'
143
- s.add_development_dependency 'ruby-openid', '~> 2.0.0'
144
- s.add_development_dependency 'thin'
145
- end
146
-
147
- Rake::GemPackageTask.new(spec) do |p|
148
- p.gem_spec = spec
149
- p.need_tar = false
150
- p.need_zip = false
151
- end
152
- end
153
-
154
- desc "Generate RDoc documentation"
155
- Rake::RDocTask.new(:rdoc) do |rdoc|
156
- rdoc.options << '--line-numbers' << '--inline-source' <<
157
- '--main' << 'README' <<
158
- '--title' << 'Rack Documentation' <<
159
- '--charset' << 'utf-8'
160
- rdoc.rdoc_dir = "doc"
161
- rdoc.rdoc_files.include 'README'
162
- rdoc.rdoc_files.include 'KNOWN-ISSUES'
163
- rdoc.rdoc_files.include 'SPEC'
164
- rdoc.rdoc_files.include 'RDOX'
165
- rdoc.rdoc_files.include('lib/rack.rb')
166
- rdoc.rdoc_files.include('lib/rack/*.rb')
167
- rdoc.rdoc_files.include('lib/rack/*/*.rb')
168
- end
169
- task :rdoc => ["SPEC", "RDOX"]
170
-
171
- task :pushsite => [:rdoc] do
172
- sh "rsync -avz doc/ chneukirchen@rack.rubyforge.org:/var/www/gforge-projects/rack/doc/"
173
- sh "rsync -avz site/ chneukirchen@rack.rubyforge.org:/var/www/gforge-projects/rack/"
174
- end
175
-
176
- begin
177
- require 'rcov/rcovtask'
178
-
179
- Rcov::RcovTask.new do |t|
180
- t.test_files = FileList['test/{spec,test}_*.rb']
181
- t.verbose = true # uncomment to see the executed command
182
- t.rcov_opts = ["--text-report",
183
- "-Ilib:test",
184
- "--include-file", "^lib,^test",
185
- "--exclude-only", "^/usr,^/home/.*/src,active_"]
186
- end
187
- rescue LoadError
188
- end
@@ -1,129 +0,0 @@
1
- This specification aims to formalize the Rack protocol. You
2
- can (and should) use Rack::Lint to enforce it.
3
- When you develop middleware, be sure to add a Lint before and
4
- after to catch all mistakes.
5
- = Rack applications
6
- A Rack application is an Ruby object (not a class) that
7
- responds to +call+.
8
- It takes exactly one argument, the *environment*
9
- and returns an Array of exactly three values:
10
- The *status*,
11
- the *headers*,
12
- and the *body*.
13
- == The Environment
14
- The environment must be an true instance of Hash (no
15
- subclassing allowed) that includes CGI-like headers.
16
- The application is free to modify the environment.
17
- The environment is required to include these variables
18
- (adopted from PEP333), except when they'd be empty, but see
19
- below.
20
- <tt>REQUEST_METHOD</tt>:: The HTTP request method, such as
21
- "GET" or "POST". This cannot ever
22
- be an empty string, and so is
23
- always required.
24
- <tt>SCRIPT_NAME</tt>:: The initial portion of the request
25
- URL's "path" that corresponds to the
26
- application object, so that the
27
- application knows its virtual
28
- "location". This may be an empty
29
- string, if the application corresponds
30
- to the "root" of the server.
31
- <tt>PATH_INFO</tt>:: The remainder of the request URL's
32
- "path", designating the virtual
33
- "location" of the request's target
34
- within the application. This may be an
35
- empty string, if the request URL targets
36
- the application root and does not have a
37
- trailing slash.
38
- <tt>QUERY_STRING</tt>:: The portion of the request URL that
39
- follows the <tt>?</tt>, if any. May be
40
- empty, but is always required!
41
- <tt>SERVER_NAME</tt>, <tt>SERVER_PORT</tt>:: When combined with <tt>SCRIPT_NAME</tt> and <tt>PATH_INFO</tt>, these variables can be used to complete the URL. Note, however, that <tt>HTTP_HOST</tt>, if present, should be used in preference to <tt>SERVER_NAME</tt> for reconstructing the request URL. <tt>SERVER_NAME</tt> and <tt>SERVER_PORT</tt> can never be empty strings, and so are always required.
42
- <tt>HTTP_</tt> Variables:: Variables corresponding to the
43
- client-supplied HTTP request
44
- headers (i.e., variables whose
45
- names begin with <tt>HTTP_</tt>). The
46
- presence or absence of these
47
- variables should correspond with
48
- the presence or absence of the
49
- appropriate HTTP header in the
50
- request.
51
- In addition to this, the Rack environment must include these
52
- Rack-specific variables:
53
- <tt>rack.version</tt>:: The Array [0,1], representing this version of Rack.
54
- <tt>rack.url_scheme</tt>:: +http+ or +https+, depending on the request URL.
55
- <tt>rack.input</tt>:: See below, the input stream.
56
- <tt>rack.errors</tt>:: See below, the error stream.
57
- <tt>rack.multithread</tt>:: true if the application object may be simultaneously invoked by another thread in the same process, false otherwise.
58
- <tt>rack.multiprocess</tt>:: true if an equivalent application object may be simultaneously invoked by another process, false otherwise.
59
- <tt>rack.run_once</tt>:: true if the server expects (but does not guarantee!) that the application will only be invoked this one time during the life of its containing process. Normally, this will only be true for a server based on CGI (or something similar).
60
- The server or the application can store their own data in the
61
- environment, too. The keys must contain at least one dot,
62
- and should be prefixed uniquely. The prefix <tt>rack.</tt>
63
- is reserved for use with the Rack core distribution and must
64
- not be used otherwise.
65
- The environment must not contain the keys
66
- <tt>HTTP_CONTENT_TYPE</tt> or <tt>HTTP_CONTENT_LENGTH</tt>
67
- (use the versions without <tt>HTTP_</tt>).
68
- The CGI keys (named without a period) must have String values.
69
- There are the following restrictions:
70
- * <tt>rack.version</tt> must be an array of Integers.
71
- * <tt>rack.url_scheme</tt> must either be +http+ or +https+.
72
- * There must be a valid input stream in <tt>rack.input</tt>.
73
- * There must be a valid error stream in <tt>rack.errors</tt>.
74
- * The <tt>REQUEST_METHOD</tt> must be a valid token.
75
- * The <tt>SCRIPT_NAME</tt>, if non-empty, must start with <tt>/</tt>
76
- * The <tt>PATH_INFO</tt>, if non-empty, must start with <tt>/</tt>
77
- * The <tt>CONTENT_LENGTH</tt>, if given, must consist of digits only.
78
- * One of <tt>SCRIPT_NAME</tt> or <tt>PATH_INFO</tt> must be
79
- set. <tt>PATH_INFO</tt> should be <tt>/</tt> if
80
- <tt>SCRIPT_NAME</tt> is empty.
81
- <tt>SCRIPT_NAME</tt> never should be <tt>/</tt>, but instead be empty.
82
- === The Input Stream
83
- The input stream must respond to +gets+, +each+ and +read+.
84
- * +gets+ must be called without arguments and return a string,
85
- or +nil+ on EOF.
86
- * +read+ must be called without or with one integer argument
87
- and return a string, or +nil+ on EOF.
88
- * +each+ must be called without arguments and only yield Strings.
89
- * +close+ must never be called on the input stream.
90
- === The Error Stream
91
- The error stream must respond to +puts+, +write+ and +flush+.
92
- * +puts+ must be called with a single argument that responds to +to_s+.
93
- * +write+ must be called with a single argument that is a String.
94
- * +flush+ must be called without arguments and must be called
95
- in order to make the error appear for sure.
96
- * +close+ must never be called on the error stream.
97
- == The Response
98
- === The Status
99
- The status, if parsed as integer (+to_i+), must be greater than or equal to 100.
100
- === The Headers
101
- The header must respond to each, and yield values of key and value.
102
- The header keys must be Strings.
103
- The header must not contain a +Status+ key,
104
- contain keys with <tt>:</tt> or newlines in their name,
105
- contain keys names that end in <tt>-</tt> or <tt>_</tt>,
106
- but only contain keys that consist of
107
- letters, digits, <tt>_</tt> or <tt>-</tt> and start with a letter.
108
- The values of the header must respond to #each.
109
- The values passed on #each must be Strings
110
- and not contain characters below 037.
111
- === The Content-Type
112
- There must be a <tt>Content-Type</tt>, except when the
113
- +Status+ is 1xx, 204 or 304, in which case there must be none
114
- given.
115
- === The Content-Length
116
- There must be a <tt>Content-Length</tt>, except when the
117
- +Status+ is 1xx, 204 or 304, in which case there must be none
118
- given.
119
- === The Body
120
- The Body must respond to #each
121
- and must only yield String values.
122
- If the Body responds to #close, it will be called after iteration.
123
- The Body commonly is an Array of Strings, the application
124
- instance itself, or a File-like object.
125
- == Thanks
126
- Some parts of this specification are adopted from PEP333: Python
127
- Web Server Gateway Interface
128
- v1.0 (http://www.python.org/dev/peps/pep-0333/). I'd like to thank
129
- everyone involved in that effort.
@@ -1,28 +0,0 @@
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
@@ -1,438 +0,0 @@
1
- # AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
2
-
3
- gem 'ruby-openid', '~> 2' if defined? Gem
4
- require 'rack/auth/abstract/handler' #rack
5
- require 'uri' #std
6
- require 'pp' #std
7
- require 'openid' #gem
8
- require 'openid/extension' #gem
9
- require 'openid/store/memory' #gem
10
-
11
- module Rack
12
- module Auth
13
- # Rack::Auth::OpenID provides a simple method for permitting
14
- # openid based logins. It requires the ruby-openid library from
15
- # janrain to operate, as well as a rack method of session management.
16
- #
17
- # The ruby-openid home page is at http://openidenabled.com/ruby-openid/.
18
- #
19
- # The OpenID specifications can be found at
20
- # http://openid.net/specs/openid-authentication-1_1.html
21
- # and
22
- # http://openid.net/specs/openid-authentication-2_0.html. Documentation
23
- # for published OpenID extensions and related topics can be found at
24
- # http://openid.net/developers/specs/.
25
- #
26
- # It is recommended to read through the OpenID spec, as well as
27
- # ruby-openid's documentation, to understand what exactly goes on. However
28
- # a setup as simple as the presented examples is enough to provide
29
- # functionality.
30
- #
31
- # This library strongly intends to utilize the OpenID 2.0 features of the
32
- # ruby-openid library, while maintaining OpenID 1.0 compatiblity.
33
- #
34
- # All responses from this rack application will be 303 redirects unless an
35
- # error occurs, with the exception of an authentication request requiring
36
- # an HTML form submission.
37
- #
38
- # NOTE: Extensions are not currently supported by this implimentation of
39
- # the OpenID rack application due to the complexity of the current
40
- # ruby-openid extension handling.
41
- #
42
- # NOTE: Due to the amount of data that this library stores in the
43
- # session, Rack::Session::Cookie may fault.
44
- class OpenID < AbstractHandler
45
- class NoSession < RuntimeError; end
46
- # Required for ruby-openid
47
- OIDStore = ::OpenID::Store::Memory.new
48
- HTML = '<html><head><title>%s</title></head><body>%s</body></html>'
49
-
50
- # A Hash of options is taken as it's single initializing
51
- # argument. For example:
52
- #
53
- # simple_oid = OpenID.new('http://mysite.com/')
54
- #
55
- # return_oid = OpenID.new('http://mysite.com/', {
56
- # :return_to => 'http://mysite.com/openid'
57
- # })
58
- #
59
- # page_oid = OpenID.new('http://mysite.com/',
60
- # :login_good => 'http://mysite.com/auth_good'
61
- # )
62
- #
63
- # complex_oid = OpenID.new('http://mysite.com/',
64
- # :return_to => 'http://mysite.com/openid',
65
- # :login_good => 'http://mysite.com/user/preferences',
66
- # :auth_fail => [500, {'Content-Type'=>'text/plain'},
67
- # 'Unable to negotiate with foreign server.'],
68
- # :immediate => true,
69
- # :extensions => {
70
- # ::OpenID::SReg => [['email'],['nickname']]
71
- # }
72
- # )
73
- #
74
- # = Arguments
75
- #
76
- # The first argument is the realm, identifying the site they are trusting
77
- # with their identity. This is required.
78
- #
79
- # NOTE: In OpenID 1.x, the realm or trust_root is optional and the
80
- # return_to url is required. As this library strives tward ruby-openid
81
- # 2.0, and OpenID 2.0 compatibiliy, the realm is required and return_to
82
- # is optional. However, this implimentation is still backwards compatible
83
- # with OpenID 1.0 servers.
84
- #
85
- # The optional second argument is a hash of options.
86
- #
87
- # == Options
88
- #
89
- # <tt>:return_to</tt> defines the url to return to after the client
90
- # authenticates with the openid service provider. This url should point
91
- # to where Rack::Auth::OpenID is mounted. If <tt>:return_to</tt> is not
92
- # provided, :return_to will be the current url including all query
93
- # parameters.
94
- #
95
- # <tt>:session_key</tt> defines the key to the session hash in the env.
96
- # It defaults to 'rack.session'.
97
- #
98
- # <tt>:openid_param</tt> defines at what key in the request parameters to
99
- # find the identifier to resolve. As per the 2.0 spec, the default is
100
- # 'openid_identifier'.
101
- #
102
- # <tt>:immediate</tt> as true will make immediate type of requests the
103
- # default. See OpenID specification documentation.
104
- #
105
- # === URL options
106
- #
107
- # <tt>:login_good</tt> is the url to go to after the authentication
108
- # process has completed.
109
- #
110
- # <tt>:login_fail</tt> is the url to go to after the authentication
111
- # process has failed.
112
- #
113
- # <tt>:login_quit</tt> is the url to go to after the authentication
114
- # process
115
- # has been cancelled.
116
- #
117
- # === Response options
118
- #
119
- # <tt>:no_session</tt> should be a rack response to be returned if no or
120
- # an incompatible session is found.
121
- #
122
- # <tt>:auth_fail</tt> should be a rack response to be returned if an
123
- # OpenID::DiscoveryFailure occurs. This is typically due to being unable
124
- # to access the identity url or identity server.
125
- #
126
- # <tt>:error</tt> should be a rack response to return if any other
127
- # generic error would occur and <tt>options[:catch_errors]</tt> is true.
128
- #
129
- # === Extensions
130
- #
131
- # <tt>:extensions</tt> should be a hash of openid extension
132
- # implementations. The key should be the extension main module, the value
133
- # should be an array of arguments for extension::Request.new
134
- #
135
- # The hash is iterated over and passed to #add_extension for processing.
136
- # Please see #add_extension for further documentation.
137
- def initialize(realm, options={})
138
- @realm = realm
139
- realm = URI(realm)
140
- if realm.path.empty?
141
- raise ArgumentError, "Invalid realm path: '#{realm.path}'"
142
- elsif not realm.absolute?
143
- raise ArgumentError, "Realm '#{@realm}' not absolute"
144
- end
145
-
146
- [:return_to, :login_good, :login_fail, :login_quit].each do |key|
147
- if options.key? key and luri = URI(options[key])
148
- if !luri.absolute?
149
- raise ArgumentError, ":#{key} is not an absolute uri: '#{luri}'"
150
- end
151
- end
152
- end
153
-
154
- if options[:return_to] and ruri = URI(options[:return_to])
155
- if ruri.path.empty?
156
- raise ArgumentError, "Invalid return_to path: '#{ruri.path}'"
157
- elsif realm.path != ruri.path[0, realm.path.size]
158
- raise ArgumentError, 'return_to not within realm.' \
159
- end
160
- end
161
-
162
- # TODO: extension support
163
- if extensions = options.delete(:extensions)
164
- extensions.each do |ext, args|
165
- add_extension ext, *args
166
- end
167
- end
168
-
169
- @options = {
170
- :session_key => 'rack.session',
171
- :openid_param => 'openid_identifier',
172
- #:return_to, :login_good, :login_fail, :login_quit
173
- #:no_session, :auth_fail, :error
174
- :store => OIDStore,
175
- :immediate => false,
176
- :anonymous => false,
177
- :catch_errors => false
178
- }.merge(options)
179
- @extensions = {}
180
- end
181
-
182
- attr_reader :options, :extensions
183
-
184
- # It sets up and uses session data at <tt>:openid</tt> within the
185
- # session. It sets up the ::OpenID::Consumer using the store specified by
186
- # <tt>options[:store]</tt>.
187
- #
188
- # If the parameter specified by <tt>options[:openid_param]</tt> is
189
- # present, processing is passed to #check and the result is returned.
190
- #
191
- # If the parameter 'openid.mode' is set, implying a followup from the
192
- # openid server, processing is passed to #finish and the result is
193
- # returned.
194
- #
195
- # If neither of these conditions are met, a 400 error is returned.
196
- #
197
- # If an error is thrown and <tt>options[:catch_errors]</tt> is false, the
198
- # exception will be reraised. Otherwise a 500 error is returned.
199
- def call(env)
200
- env['rack.auth.openid'] = self
201
- session = env[@options[:session_key]]
202
- unless session and session.is_a? Hash
203
- raise(NoSession, 'No compatible session')
204
- end
205
- # let us work in our own namespace...
206
- session = (session[:openid] ||= {})
207
- unless session and session.is_a? Hash
208
- raise(NoSession, 'Incompatible session')
209
- end
210
-
211
- request = Rack::Request.new env
212
- consumer = ::OpenID::Consumer.new session, @options[:store]
213
-
214
- if request.params['openid.mode']
215
- finish consumer, session, request
216
- elsif request.params[@options[:openid_param]]
217
- check consumer, session, request
218
- else
219
- env['rack.errors'].puts "No valid params provided."
220
- bad_request
221
- end
222
- rescue NoSession
223
- env['rack.errors'].puts($!.message, *$@)
224
-
225
- @options. ### Missing or incompatible session
226
- fetch :no_session, [ 500,
227
- {'Content-Type'=>'text/plain'},
228
- $!.message ]
229
- rescue
230
- env['rack.errors'].puts($!.message, *$@)
231
-
232
- if not @options[:catch_error]
233
- raise($!)
234
- end
235
- @options.
236
- fetch :error, [ 500,
237
- {'Content-Type'=>'text/plain'},
238
- 'OpenID has encountered an error.' ]
239
- end
240
-
241
- # As the first part of OpenID consumer action, #check retrieves the data
242
- # required for completion.
243
- #
244
- # * <tt>session[:openid][:openid_param]</tt> is set to the submitted
245
- # identifier to be authenticated.
246
- # * <tt>session[:openid][:site_return]</tt> is set as the request's
247
- # HTTP_REFERER, unless already set.
248
- # * <tt>env['rack.auth.openid.request']</tt> is the openid checkid
249
- # request instance.
250
- def check(consumer, session, req)
251
- session[:openid_param] = req.params[@options[:openid_param]]
252
- oid = consumer.begin(session[:openid_param], @options[:anonymous])
253
- pp oid if $DEBUG
254
- req.env['rack.auth.openid.request'] = oid
255
-
256
- session[:site_return] ||= req.env['HTTP_REFERER']
257
-
258
- # SETUP_NEEDED check!
259
- # see OpenID::Consumer::CheckIDRequest docs
260
- query_args = [@realm, *@options.values_at(:return_to, :immediate)]
261
- query_args[1] ||= req.url
262
- query_args[2] = false if session.key? :setup_needed
263
- pp query_args if $DEBUG
264
-
265
- ## Extension support
266
- extensions.each do |ext,args|
267
- oid.add_extension ext::Request.new(*args)
268
- end
269
-
270
- if oid.send_redirect?(*query_args)
271
- redirect = oid.redirect_url(*query_args)
272
- if $DEBUG
273
- pp redirect
274
- pp Rack::Utils.parse_query(URI(redirect).query)
275
- end
276
- [ 303, {'Location'=>redirect}, [] ]
277
- else
278
- # check on 'action' option.
279
- formbody = oid.form_markup(*query_args)
280
- if $DEBUG
281
- pp formbody
282
- end
283
- body = HTML % ['Confirm...', formbody]
284
- [ 200, {'Content-Type'=>'text/html'}, body.to_a ]
285
- end
286
- rescue ::OpenID::DiscoveryFailure => e
287
- # thrown from inside OpenID::Consumer#begin by yadis stuff
288
- req.env['rack.errors'].puts($!.message, *$@)
289
-
290
- @options. ### Foreign server failed
291
- fetch :auth_fail, [ 503,
292
- {'Content-Type'=>'text/plain'},
293
- 'Foreign server failure.' ]
294
- end
295
-
296
- # This is the final portion of authentication. Unless any errors outside
297
- # of specification occur, a 303 redirect will be returned with Location
298
- # determined by the OpenID response type. If none of the response type
299
- # :login_* urls are set, the redirect will be set to
300
- # <tt>session[:openid][:site_return]</tt>. If
301
- # <tt>session[:openid][:site_return]</tt> is unset, the realm will be
302
- # used.
303
- #
304
- # Any messages from OpenID's response are appended to the 303 response
305
- # body.
306
- #
307
- # Data gathered from extensions are stored in session[:openid] with the
308
- # extension's namespace uri as the key.
309
- #
310
- # * <tt>env['rack.auth.openid.response']</tt> is the openid response.
311
- #
312
- # The four valid possible outcomes are:
313
- # * failure: <tt>options[:login_fail]</tt> or
314
- # <tt>session[:site_return]</tt> or the realm
315
- # * <tt>session[:openid]</tt> is cleared and any messages are send to
316
- # rack.errors
317
- # * <tt>session[:openid]['authenticated']</tt> is <tt>false</tt>
318
- # * success: <tt>options[:login_good]</tt> or
319
- # <tt>session[:site_return]</tt> or the realm
320
- # * <tt>session[:openid]</tt> is cleared
321
- # * <tt>session[:openid]['authenticated']</tt> is <tt>true</tt>
322
- # * <tt>session[:openid]['identity']</tt> is the actual identifier
323
- # * <tt>session[:openid]['identifier']</tt> is the pretty identifier
324
- # * cancel: <tt>options[:login_good]</tt> or
325
- # <tt>session[:site_return]</tt> or the realm
326
- # * <tt>session[:openid]</tt> is cleared
327
- # * <tt>session[:openid]['authenticated']</tt> is <tt>false</tt>
328
- # * setup_needed: resubmits the authentication request. A flag is set for
329
- # non-immediate handling.
330
- # * <tt>session[:openid][:setup_needed]</tt> is set to <tt>true</tt>,
331
- # which will prevent immediate style openid authentication.
332
- def finish(consumer, session, req)
333
- oid = consumer.complete(req.params, req.url)
334
- pp oid if $DEBUG
335
- req.env['rack.auth.openid.response'] = oid
336
-
337
- goto = session.fetch :site_return, @realm
338
- body = []
339
-
340
- case oid.status
341
- when ::OpenID::Consumer::FAILURE
342
- session.clear
343
- session['authenticated'] = false
344
- req.env['rack.errors'].puts oid.message
345
-
346
- goto = @options[:login_fail] if @options.key? :login_fail
347
- body << "Authentication unsuccessful.\n"
348
- when ::OpenID::Consumer::SUCCESS
349
- session.clear
350
-
351
- ## Extension support
352
- extensions.each do |ext, args|
353
- session[ext::NS_URI] = ext::Response.
354
- from_success_response(oid).
355
- get_extension_args
356
- end
357
-
358
- session['authenticated'] = true
359
- # Value for unique identification and such
360
- session['identity'] = oid.identity_url
361
- # Value for display and UI labels
362
- session['identifier'] = oid.display_identifier
363
-
364
- goto = @options[:login_good] if @options.key? :login_good
365
- body << "Authentication successful.\n"
366
- when ::OpenID::Consumer::CANCEL
367
- session.clear
368
- session['authenticated'] = false
369
-
370
- goto = @options[:login_fail] if @options.key? :login_fail
371
- body << "Authentication cancelled.\n"
372
- when ::OpenID::Consumer::SETUP_NEEDED
373
- session[:setup_needed] = true
374
- unless o_id = session[:openid_param]
375
- raise('Required values missing.')
376
- end
377
-
378
- goto = req.script_name+
379
- '?'+@options[:openid_param]+
380
- '='+o_id
381
- body << "Reauthentication required.\n"
382
- end
383
- body << oid.message if oid.message
384
- [ 303, {'Location'=>goto}, body]
385
- end
386
-
387
- # The first argument should be the main extension module.
388
- # The extension module should contain the constants:
389
- # * class Request, with OpenID::Extension as an ancestor
390
- # * class Response, with OpenID::Extension as an ancestor
391
- # * string NS_URI, which defines the namespace of the extension, should
392
- # be an absolute http uri
393
- #
394
- # All trailing arguments will be passed to extension::Request.new in
395
- # #check.
396
- # The openid response will be passed to
397
- # extension::Response#from_success_response, #get_extension_args will be
398
- # called on the result to attain the gathered data.
399
- #
400
- # This method returns the key at which the response data will be found in
401
- # the session, which is the namespace uri by default.
402
- def add_extension ext, *args
403
- if not ext.is_a? Module
404
- raise TypeError, "#{ext.inspect} is not a module"
405
- elsif !(m = %w'Request Response NS_URI' -
406
- ext.constants.map{ |c| c.to_s }).empty?
407
- raise ArgumentError, "#{ext.inspect} missing #{m*', '}"
408
- end
409
-
410
- consts = [ext::Request, ext::Response]
411
-
412
- if not consts.all?{|c| c.is_a? Class }
413
- raise TypeError, "#{ext.inspect}'s Request or Response is not a class"
414
- elsif not consts.all?{|c| ::OpenID::Extension > c }
415
- raise ArgumentError, "#{ext.inspect}'s Request or Response not a decendant of OpenID::Extension"
416
- end
417
-
418
- if not ext::NS_URI.is_a? String
419
- raise TypeError, "#{ext.inspect}'s NS_URI is not a string"
420
- elsif not uri = URI(ext::NS_URI)
421
- raise ArgumentError, "#{ext.inspect}'s NS_URI is not a valid uri"
422
- elsif not uri.scheme =~ /^https?$/
423
- raise ArgumentError, "#{ext.inspect}'s NS_URI is not an http uri"
424
- elsif not uri.absolute?
425
- raise ArgumentError, "#{ext.inspect}'s NS_URI is not and absolute uri"
426
- end
427
- @extensions[ext] = args
428
- return ext::NS_URI
429
- end
430
-
431
- # A conveniance method that returns the namespace of all current
432
- # extensions used by this instance.
433
- def extension_namespaces
434
- @extensions.keys.map{|e|e::NS_URI}
435
- end
436
- end
437
- end
438
- end