passenger 2.2.2 → 2.2.3

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 (254) hide show
  1. data/DEVELOPERS.TXT +13 -3
  2. data/Rakefile +42 -33
  3. data/bin/passenger-install-apache2-module +1 -2
  4. data/bin/passenger-install-nginx-module +7 -19
  5. data/bin/passenger-status +64 -15
  6. data/bin/passenger-stress-test +2 -2
  7. data/doc/ApplicationPool algorithm.txt +26 -22
  8. data/doc/Users guide Apache.html +374 -149
  9. data/doc/Users guide Apache.txt +318 -51
  10. data/doc/Users guide Nginx.html +13 -13
  11. data/doc/Users guide Nginx.txt +7 -2
  12. data/doc/cxxapi/Bucket_8h-source.html +62 -25
  13. data/doc/cxxapi/Configuration_8h-source.html +343 -326
  14. data/doc/cxxapi/DirectoryMapper_8h-source.html +12 -12
  15. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  16. data/doc/cxxapi/annotated.html +1 -1
  17. data/doc/cxxapi/classHooks-members.html +1 -1
  18. data/doc/cxxapi/classHooks.html +1 -1
  19. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -2
  20. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +9 -9
  21. data/doc/cxxapi/classes.html +1 -1
  22. data/doc/cxxapi/definitions_8h-source.html +1 -1
  23. data/doc/cxxapi/files.html +1 -1
  24. data/doc/cxxapi/functions.html +2 -2
  25. data/doc/cxxapi/functions_func.html +2 -2
  26. data/doc/cxxapi/graph_legend.html +1 -1
  27. data/doc/cxxapi/group__Configuration.html +1 -1
  28. data/doc/cxxapi/group__Core.html +1 -1
  29. data/doc/cxxapi/group__Hooks.html +1 -1
  30. data/doc/cxxapi/group__Support.html +1 -1
  31. data/doc/cxxapi/main.html +1 -1
  32. data/doc/cxxapi/modules.html +1 -1
  33. data/doc/rdoc/classes/ConditionVariable.html +194 -0
  34. data/doc/rdoc/classes/Exception.html +120 -0
  35. data/doc/rdoc/classes/GC.html +113 -0
  36. data/doc/rdoc/classes/IO.html +169 -0
  37. data/doc/rdoc/classes/PhusionPassenger.html +238 -0
  38. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +153 -0
  39. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +517 -0
  40. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +719 -0
  41. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +97 -0
  42. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +96 -0
  43. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +97 -0
  44. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +96 -0
  45. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
  46. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
  47. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +317 -0
  48. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
  49. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +154 -0
  50. data/doc/rdoc/classes/PhusionPassenger/Application.html +283 -0
  51. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +172 -0
  52. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +145 -0
  53. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +175 -0
  54. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +141 -0
  55. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  56. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +489 -0
  57. data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +350 -0
  58. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  59. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +188 -0
  60. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +194 -0
  61. data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
  62. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +442 -0
  63. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
  64. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
  65. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +436 -0
  66. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
  67. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +155 -0
  68. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +402 -0
  69. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +125 -0
  70. data/doc/rdoc/classes/PhusionPassenger/Utils.html +805 -0
  71. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +140 -0
  72. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  73. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
  74. data/doc/rdoc/classes/PlatformInfo.html +831 -0
  75. data/doc/rdoc/classes/RakeExtensions.html +197 -0
  76. data/doc/rdoc/classes/Signal.html +131 -0
  77. data/doc/rdoc/created.rid +1 -0
  78. data/doc/rdoc/files/DEVELOPERS_TXT.html +255 -0
  79. data/doc/rdoc/files/README.html +157 -0
  80. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +92 -0
  81. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +129 -0
  82. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +131 -0
  83. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +126 -0
  84. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +130 -0
  85. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +130 -0
  86. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +122 -0
  87. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +127 -0
  88. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +126 -0
  89. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +122 -0
  90. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +134 -0
  91. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +122 -0
  92. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +122 -0
  93. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +126 -0
  94. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +122 -0
  95. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
  96. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +127 -0
  97. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +133 -0
  98. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +127 -0
  99. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +143 -0
  100. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
  101. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +145 -0
  102. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +127 -0
  103. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +122 -0
  104. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +161 -0
  105. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +175 -0
  106. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +129 -0
  107. data/doc/rdoc/files/misc/rake/extensions_rb.html +130 -0
  108. data/doc/rdoc/fr_class_index.html +90 -0
  109. data/doc/rdoc/fr_file_index.html +76 -0
  110. data/doc/rdoc/fr_method_index.html +200 -0
  111. data/doc/rdoc/index.html +26 -0
  112. data/doc/rdoc/rdoc-style.css +187 -0
  113. data/doc/users_guide_snippets/rackup_specifications.txt +2 -8
  114. data/ext/apache2/Bucket.cpp +71 -38
  115. data/ext/apache2/Bucket.h +53 -16
  116. data/ext/apache2/Configuration.cpp +15 -0
  117. data/ext/apache2/Configuration.h +19 -2
  118. data/ext/apache2/DirectoryMapper.h +10 -10
  119. data/ext/apache2/Hooks.cpp +334 -74
  120. data/ext/boost/mpl/apply.hpp +5 -1
  121. data/ext/boost/mpl/apply_wrap.hpp +5 -2
  122. data/ext/boost/mpl/aux_/full_lambda.hpp +5 -1
  123. data/ext/boost/mpl/bind.hpp +5 -1
  124. data/ext/common/Application.h +11 -31
  125. data/ext/common/ApplicationPool.h +2 -1
  126. data/ext/common/ApplicationPoolServer.h +61 -20
  127. data/ext/common/ApplicationPoolServerExecutable.cpp +132 -4
  128. data/ext/common/ApplicationPoolStatusReporter.h +189 -65
  129. data/ext/common/Base64.cpp +143 -0
  130. data/ext/common/Base64.h +57 -0
  131. data/ext/common/CachedFileStat.cpp +25 -82
  132. data/ext/common/CachedFileStat.h +11 -125
  133. data/ext/common/CachedFileStat.hpp +243 -0
  134. data/ext/common/Exceptions.h +13 -0
  135. data/ext/common/FileChangeChecker.h +209 -0
  136. data/ext/common/Logging.h +3 -2
  137. data/ext/common/MessageChannel.h +10 -10
  138. data/ext/common/PoolOptions.h +72 -5
  139. data/ext/common/SpawnManager.h +11 -8
  140. data/ext/common/StandardApplicationPool.h +38 -39
  141. data/ext/common/StaticString.h +1 -0
  142. data/ext/common/StringListCreator.h +83 -0
  143. data/ext/common/SystemTime.h +3 -2
  144. data/ext/common/Timer.h +88 -0
  145. data/ext/common/Utils.cpp +161 -42
  146. data/ext/common/Utils.h +62 -31
  147. data/ext/common/Version.h +1 -1
  148. data/ext/nginx/Configuration.c +0 -4
  149. data/ext/nginx/ContentHandler.c +8 -6
  150. data/ext/nginx/HelperServer.cpp +45 -55
  151. data/ext/nginx/HttpStatusExtractor.h +4 -0
  152. data/ext/nginx/StaticContentHandler.c +25 -5
  153. data/ext/nginx/config +3 -0
  154. data/ext/nginx/ngx_http_passenger_module.c +72 -17
  155. data/ext/nginx/ngx_http_passenger_module.h +2 -2
  156. data/lib/phusion_passenger/abstract_request_handler.rb +15 -7
  157. data/lib/phusion_passenger/abstract_server.rb +16 -2
  158. data/lib/phusion_passenger/admin_tools/control_process.rb +36 -25
  159. data/lib/phusion_passenger/constants.rb +1 -1
  160. data/lib/phusion_passenger/dependencies.rb +10 -0
  161. data/lib/phusion_passenger/platform_info.rb +1 -1
  162. data/lib/phusion_passenger/rack/application_spawner.rb +21 -2
  163. data/lib/phusion_passenger/rack/request_handler.rb +10 -0
  164. data/lib/phusion_passenger/railz/application_spawner.rb +38 -2
  165. data/lib/phusion_passenger/railz/framework_spawner.rb +26 -28
  166. data/lib/phusion_passenger/railz/request_handler.rb +5 -1
  167. data/lib/phusion_passenger/spawn_manager.rb +6 -2
  168. data/lib/phusion_passenger/utils.rb +79 -27
  169. data/misc/rake/cplusplus.rb +5 -5
  170. data/test/ApplicationPoolServerTest.cpp +42 -0
  171. data/test/ApplicationPoolTest.cpp +255 -267
  172. data/test/Base64Test.cpp +48 -0
  173. data/test/CachedFileStatTest.cpp +243 -103
  174. data/test/FileChangeCheckerTest.cpp +331 -0
  175. data/test/PoolOptionsTest.cpp +80 -0
  176. data/test/UtilsTest.cpp +5 -17
  177. data/test/integration_tests/apache2_tests.rb +15 -4
  178. data/test/integration_tests/mycook_spec.rb +3 -4
  179. data/test/oxt/syscall_interruption_test.cpp +2 -14
  180. data/test/ruby/abstract_server_collection_spec.rb +1 -1
  181. data/test/ruby/abstract_server_spec.rb +35 -1
  182. data/test/ruby/rack/application_spawner_spec.rb +23 -6
  183. data/test/ruby/rails/application_spawner_spec.rb +6 -6
  184. data/test/ruby/rails/framework_spawner_spec.rb +6 -5
  185. data/test/ruby/rails/minimal_spawner_spec.rb +19 -0
  186. data/test/ruby/rails/spawner_error_handling_spec.rb +62 -7
  187. data/test/ruby/spawn_manager_spec.rb +10 -7
  188. data/test/ruby/spawn_server_spec.rb +1 -1
  189. data/test/ruby/utils_spec.rb +193 -20
  190. data/test/ruby/wsgi/application_spawner_spec.rb +3 -1
  191. data/test/stub/apache2/httpd.conf.erb +3 -0
  192. data/test/stub/rack/config.ru +1 -1
  193. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +8 -0
  194. data/test/support/Support.cpp +84 -0
  195. data/test/support/Support.h +66 -8
  196. data/test/support/config.rb +14 -2
  197. data/test/support/test_helper.rb +5 -0
  198. data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +123 -116
  199. data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +17 -12
  200. data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +34 -43
  201. data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +1 -1
  202. data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +1 -1
  203. data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +1 -1
  204. data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +1 -1
  205. data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +1 -1
  206. data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +1 -1
  207. data/vendor/rack-1.0.0-git/lib/rack/mock.rb +4 -17
  208. data/vendor/rack-1.0.0-git/lib/rack/request.rb +3 -9
  209. data/vendor/rack-1.0.0-git/lib/rack/rewindable_input.rb +2 -0
  210. data/vendor/rack-1.0.0-git/lib/rack/utils.rb +38 -12
  211. metadata +231 -186
  212. data/ext/common/FileChecker.h +0 -112
  213. data/test/FileCheckerTest.cpp +0 -79
  214. data/test/stub/minimal-railsapp/README +0 -3
  215. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  216. data/test/stub/minimal-railsapp/config/environment.rb +0 -3
  217. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  218. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -10
  219. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  220. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  221. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -7
  222. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  223. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -17
  224. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  225. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  226. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -8
  227. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -1
  228. data/test/stub/railsapp/app/controllers/application.rb +0 -12
  229. data/test/stub/railsapp/app/controllers/bar_controller.rb +0 -5
  230. data/test/stub/railsapp/app/controllers/bar_controller_1.txt +0 -5
  231. data/test/stub/railsapp/app/controllers/bar_controller_2.txt +0 -5
  232. data/test/stub/railsapp/app/controllers/foo_controller.rb +0 -9
  233. data/test/stub/railsapp/app/helpers/application_helper.rb +0 -3
  234. data/test/stub/railsapp/config/boot.rb +0 -108
  235. data/test/stub/railsapp/config/database.yml +0 -19
  236. data/test/stub/railsapp/config/environment.rb +0 -59
  237. data/test/stub/railsapp/config/environments/development.rb +0 -18
  238. data/test/stub/railsapp/config/environments/production.rb +0 -19
  239. data/test/stub/railsapp/config/initializers/inflections.rb +0 -10
  240. data/test/stub/railsapp/config/initializers/mime_types.rb +0 -5
  241. data/test/stub/railsapp/config/routes.rb +0 -35
  242. data/test/stub/railsapp/public/useless.txt +0 -1
  243. data/test/stub/railsapp2/app/controllers/application.rb +0 -12
  244. data/test/stub/railsapp2/app/controllers/foo_controller.rb +0 -5
  245. data/test/stub/railsapp2/app/helpers/application_helper.rb +0 -3
  246. data/test/stub/railsapp2/config/boot.rb +0 -108
  247. data/test/stub/railsapp2/config/database.yml +0 -19
  248. data/test/stub/railsapp2/config/environment.rb +0 -59
  249. data/test/stub/railsapp2/config/environments/development.rb +0 -18
  250. data/test/stub/railsapp2/config/environments/production.rb +0 -19
  251. data/test/stub/railsapp2/config/initializers/inflections.rb +0 -10
  252. data/test/stub/railsapp2/config/initializers/mime_types.rb +0 -5
  253. data/test/stub/railsapp2/config/routes.rb +0 -35
  254. data/test/stub/railsapp2/public/useless.txt +0 -1
@@ -18,9 +18,21 @@ require 'phusion_passenger/utils'
18
18
  # Calculate location of the temp dir and cache it.
19
19
  PhusionPassenger::Utils.passenger_tmpdir
20
20
 
21
+ # Seed the pseudo-random number generator here
22
+ # so that it doesn't happen in the child processes.
23
+ srand
24
+
21
25
  Spec::Runner.configure do |config|
26
+ config.append_before do
27
+ # Create the temp directory.
28
+ PhusionPassenger::Utils.passenger_tmpdir
29
+ end
30
+
22
31
  config.append_after do
23
- FileUtils.chmod_R(0777, PhusionPassenger::Utils.passenger_tmpdir);
24
- FileUtils.rm_rf(PhusionPassenger::Utils.passenger_tmpdir)
32
+ tmpdir = PhusionPassenger::Utils.passenger_tmpdir(false)
33
+ if File.exist?(tmpdir)
34
+ FileUtils.chmod_R(0777, tmpdir)
35
+ FileUtils.rm_rf(tmpdir)
36
+ end
25
37
  end
26
38
  end
@@ -169,5 +169,10 @@ File.class_eval do
169
169
  f.write(content)
170
170
  end
171
171
  end
172
+
173
+ def self.touch(filename, timestamp = nil)
174
+ File.open(filename, 'w').close
175
+ File.utime(timestamp, timestamp, filename) if timestamp
176
+ end
172
177
  end
173
178
 
@@ -1,13 +1,14 @@
1
- # AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
1
+ # AUTHOR: Scytrin dai Kinthra <scytrin@gmail.com>; blink#ruby-lang@irc.freenode.net
2
2
 
3
3
  gem 'ruby-openid', '~> 2' if defined? Gem
4
4
  require 'rack/request'
5
5
  require 'rack/utils'
6
6
  require 'rack/auth/abstract/handler'
7
+
7
8
  require 'uri'
8
- require 'openid' #gem
9
- require 'openid/extension' #gem
10
- require 'openid/store/memory' #gem
9
+ require 'openid'
10
+ require 'openid/extension'
11
+ require 'openid/store/memory'
11
12
 
12
13
  module Rack
13
14
  class Request
@@ -45,108 +46,111 @@ module Rack
45
46
  #
46
47
  # NOTE: Due to the amount of data that this library stores in the
47
48
  # session, Rack::Session::Cookie may fault.
49
+ #
50
+ # == Examples
51
+ #
52
+ # simple_oid = OpenID.new('http://mysite.com/')
53
+ #
54
+ # return_oid = OpenID.new('http://mysite.com/', {
55
+ # :return_to => 'http://mysite.com/openid'
56
+ # })
57
+ #
58
+ # complex_oid = OpenID.new('http://mysite.com/',
59
+ # :immediate => true,
60
+ # :extensions => {
61
+ # ::OpenID::SReg => [['email'],['nickname']]
62
+ # }
63
+ # )
64
+ #
65
+ # = Advanced
66
+ #
67
+ # Most of the functionality of this library is encapsulated such that
68
+ # expansion and overriding functions isn't difficult nor tricky.
69
+ # Alternately, to avoid opening up singleton objects or subclassing, a
70
+ # wrapper rack middleware can be composed to act upon Auth::OpenID's
71
+ # responses. See #check and #finish for locations of pertinent data.
72
+ #
73
+ # == Responses
74
+ #
75
+ # To change the responses that Auth::OpenID returns, override the methods
76
+ # #redirect, #bad_request, #unauthorized, #access_denied, and
77
+ # #foreign_server_failure.
78
+ #
79
+ # Additionally #confirm_post_params is used when the URI would exceed
80
+ # length limits on a GET request when doing the initial verification
81
+ # request.
82
+ #
83
+ # == Processing
84
+ #
85
+ # To change methods of processing completed transactions, override the
86
+ # methods #success, #setup_needed, #cancel, and #failure. Please ensure
87
+ # the returned object is a rack compatible response.
88
+ #
89
+ # The first argument is an OpenID::Response, the second is a
90
+ # Rack::Request of the current request, the last is the hash used in
91
+ # ruby-openid handling, which can be found manually at
92
+ # env['rack.session'][:openid].
93
+ #
94
+ # This is useful if you wanted to expand the processing done, such as
95
+ # setting up user accounts.
96
+ #
97
+ # oid_app = Rack::Auth::OpenID.new realm, :return_to => return_to
98
+ # def oid_app.success oid, request, session
99
+ # user = Models::User[oid.identity_url]
100
+ # user ||= Models::User.create_from_openid oid
101
+ # request['rack.session'][:user] = user.id
102
+ # redirect MyApp.site_home
103
+ # end
104
+ #
105
+ # site_map['/openid'] = oid_app
106
+ # map = Rack::URLMap.new site_map
107
+ # ...
48
108
 
49
109
  class OpenID
50
-
110
+ # Raised if an incompatible session is being used.
51
111
  class NoSession < RuntimeError; end
112
+ # Raised if an extension not matching specifications is provided.
52
113
  class BadExtension < RuntimeError; end
53
- # Required for ruby-openid
54
- ValidStatus = [:success, :setup_needed, :cancel, :failure]
114
+ # Possible statuses returned from consumer responses. See definitions
115
+ # in the ruby-openid library.
116
+ ValidStatus = [
117
+ ::OpenID::Consumer::SUCCESS,
118
+ ::OpenID::Consumer::FAILURE,
119
+ ::OpenID::Consumer::CANCEL,
120
+ ::OpenID::Consumer::SETUP_NEEDED
121
+ ]
55
122
 
56
- # = Arguments
57
- #
58
123
  # The first argument is the realm, identifying the site they are trusting
59
124
  # with their identity. This is required, also treated as the trust_root
60
125
  # in OpenID 1.x exchanges.
61
126
  #
62
- # The optional second argument is a hash of options.
63
- #
64
- # == Options
127
+ # The lits of acceptable options include :return_to, :session_key,
128
+ # :openid_param, :store, :immediate, :extensions.
65
129
  #
66
130
  # <tt>:return_to</tt> defines the url to return to after the client
67
131
  # authenticates with the openid service provider. This url should point
68
- # to where Rack::Auth::OpenID is mounted. If <tt>:return_to</tt> is not
69
- # provided, return_to will be the current url which allows flexibility
70
- # with caveats.
132
+ # to where Rack::Auth::OpenID is mounted. If unprovided, the url of
133
+ # the current request is used.
71
134
  #
72
135
  # <tt>:session_key</tt> defines the key to the session hash in the env.
73
- # It defaults to 'rack.session'.
136
+ # The default is 'rack.session'.
74
137
  #
75
138
  # <tt>:openid_param</tt> defines at what key in the request parameters to
76
139
  # find the identifier to resolve. As per the 2.0 spec, the default is
77
140
  # 'openid_identifier'.
78
141
  #
79
142
  # <tt>:store</tt> defined what OpenID Store to use for persistant
80
- # information. By default a Store::Memory will be used.
143
+ # information. By default a Store::Memory is used.
81
144
  #
82
145
  # <tt>:immediate</tt> as true will make initial requests to be of an
83
146
  # immediate type. This is false by default. See OpenID specification
84
147
  # documentation.
85
148
  #
86
149
  # <tt>:extensions</tt> should be a hash of openid extension
87
- # implementations. The key should be the extension main module, the value
88
- # should be an array of arguments for extension::Request.new.
150
+ # implementations. The key should be the extension module, the value
151
+ # should be an array of arguments for extension::Request.new().
89
152
  # The hash is iterated over and passed to #add_extension for processing.
90
153
  # Please see #add_extension for further documentation.
91
- #
92
- # == Examples
93
- #
94
- # simple_oid = OpenID.new('http://mysite.com/')
95
- #
96
- # return_oid = OpenID.new('http://mysite.com/', {
97
- # :return_to => 'http://mysite.com/openid'
98
- # })
99
- #
100
- # complex_oid = OpenID.new('http://mysite.com/',
101
- # :immediate => true,
102
- # :extensions => {
103
- # ::OpenID::SReg => [['email'],['nickname']]
104
- # }
105
- # )
106
- #
107
- # = Advanced
108
- #
109
- # Most of the functionality of this library is encapsulated such that
110
- # expansion and overriding functions isn't difficult nor tricky.
111
- # Alternately, to avoid opening up singleton objects or subclassing, a
112
- # wrapper rack middleware can be composed to act upon Auth::OpenID's
113
- # responses. See #check and #finish for locations of pertinent data.
114
- #
115
- # == Responses
116
- #
117
- # To change the responses that Auth::OpenID returns, override the methods
118
- # #redirect, #bad_request, #unauthorized, #access_denied, and
119
- # #foreign_server_failure.
120
- #
121
- # Additionally #confirm_post_params is used when the URI would exceed
122
- # length limits on a GET request when doing the initial verification
123
- # request.
124
- #
125
- # == Processing
126
- #
127
- # To change methods of processing completed transactions, override the
128
- # methods #success, #setup_needed, #cancel, and #failure. Please ensure
129
- # the returned object is a rack compatible response.
130
- #
131
- # The first argument is an OpenID::Response, the second is a
132
- # Rack::Request of the current request, the last is the hash used in
133
- # ruby-openid handling, which can be found manually at
134
- # env['rack.session'][:openid].
135
- #
136
- # This is useful if you wanted to expand the processing done, such as
137
- # setting up user accounts.
138
- #
139
- # oid_app = Rack::Auth::OpenID.new realm, :return_to => return_to
140
- # def oid_app.success oid, request, session
141
- # user = Models::User[oid.identity_url]
142
- # user ||= Models::User.create_from_openid oid
143
- # request['rack.session'][:user] = user.id
144
- # redirect MyApp.site_home
145
- # end
146
- #
147
- # site_map['/openid'] = oid_app
148
- # map = Rack::URLMap.new site_map
149
- # ...
150
154
 
151
155
  def initialize(realm, options={})
152
156
  realm = URI(realm)
@@ -162,7 +166,7 @@ module Rack
162
166
  ruri = URI(ruri)
163
167
  raise ArgumentError, "Invalid return_to: #{ruri}" \
164
168
  unless ruri.absolute? \
165
- and ruri.scheme =~ /^https?$/ \
169
+ and ruri.scheme =~ /^https?$/ \
166
170
  and ruri.fragment.nil?
167
171
  raise ArgumentError, "return_to #{ruri} not within realm #{realm}" \
168
172
  unless self.within_realm?(ruri)
@@ -174,10 +178,10 @@ module Rack
174
178
  @store = options[:store] || ::OpenID::Store::Memory.new
175
179
  @immediate = !!options[:immediate]
176
180
 
177
- @extensions = {}
178
- if extensions = options.delete(:extensions)
181
+ @extensions = {}
182
+ if extensions = options[:extensions]
179
183
  extensions.each do |ext, args|
180
- add_extension ext, *args
184
+ add_extension(ext, *args)
181
185
  end
182
186
  end
183
187
 
@@ -199,33 +203,29 @@ module Rack
199
203
  # If the parameter specified by <tt>options[:openid_param]</tt> is
200
204
  # present, processing is passed to #check and the result is returned.
201
205
  #
202
- # If neither of these conditions are met, #unauthorized is called.
206
+ # If neither of these conditions are met, #bad_request is called.
203
207
 
204
208
  def call(env)
205
209
  env['rack.auth.openid'] = self
206
210
  env_session = env[@session_key]
207
211
  unless env_session and env_session.is_a?(Hash)
208
- raise NoSession, 'No compatible session'
212
+ raise NoSession, 'No compatible session.'
209
213
  end
210
214
  # let us work in our own namespace...
211
215
  session = (env_session[:openid] ||= {})
212
216
  unless session and session.is_a?(Hash)
213
- raise NoSession, 'Incompatible openid session'
217
+ raise NoSession, 'Incompatible openid session.'
214
218
  end
215
219
 
216
220
  request = Rack::Request.new(env)
217
221
  consumer = ::OpenID::Consumer.new(session, @store)
218
222
 
219
223
  if mode = request.GET['openid.mode']
220
- if session.key?(:openid_param)
221
- finish(consumer, session, request)
222
- else
223
- bad_request
224
- end
224
+ finish(consumer, session, request)
225
225
  elsif request.GET[@openid_param]
226
226
  check(consumer, session, request)
227
227
  else
228
- unauthorized
228
+ bad_request
229
229
  end
230
230
  end
231
231
 
@@ -263,14 +263,13 @@ module Rack
263
263
  immediate = session.key?(:setup_needed) ? false : immediate
264
264
 
265
265
  if oid.send_redirect?(realm, return_to_uri, immediate)
266
- uri = oid.redirect_url(realm, return_to_uri, immediate)
267
- redirect(uri)
266
+ redirect(oid.redirect_url(realm, return_to_uri, immediate))
268
267
  else
269
268
  confirm_post_params(oid, realm, return_to_uri, immediate)
270
269
  end
271
270
  rescue ::OpenID::DiscoveryFailure => e
272
271
  # thrown from inside OpenID::Consumer#begin by yadis stuff
273
- req.env['rack.errors'].puts([e.message, *e.backtrace]*"\n")
272
+ req.env['rack.errors'].puts( [e.message, *e.backtrace]*"\n" )
274
273
  return foreign_server_failure
275
274
  end
276
275
 
@@ -290,21 +289,24 @@ module Rack
290
289
  req.env['rack.errors'].puts(oid.message)
291
290
  p oid if $DEBUG
292
291
 
293
- raise unless ValidStatus.include?(oid.status)
294
- __send__(oid.status, oid, req, session)
292
+ if ValidStatus.include?(oid.status)
293
+ __send__(oid.status, oid, req, session)
294
+ else
295
+ invalid_status(oid, req, session)
296
+ end
295
297
  end
296
298
 
297
299
  # The first argument should be the main extension module.
298
300
  # The extension module should contain the constants:
299
- # * class Request, should have OpenID::Extension as an ancestor
300
- # * class Response, should have OpenID::Extension as an ancestor
301
- # * string NS_URI, which defining the namespace of the extension
301
+ # * class Request, should have OpenID::Extension as an ancestor
302
+ # * class Response, should have OpenID::Extension as an ancestor
303
+ # * string NS_URI, which defining the namespace of the extension
302
304
  #
303
305
  # All trailing arguments will be passed to extension::Request.new in
304
306
  # #check.
305
307
  # The openid response will be passed to
306
- # extension::Response#from_success_response, #get_extension_args will be
307
- # called on the result to attain the gathered data.
308
+ # extension::Response#from_success_response, oid#get_extension_args will
309
+ # be called on the result to attain the gathered data.
308
310
  #
309
311
  # This method returns the key at which the response data will be found in
310
312
  # the session, which is the namespace uri by default.
@@ -344,28 +346,27 @@ module Rack
344
346
  return false unless uri.host.match(realm_match)
345
347
  return true
346
348
  end
349
+
347
350
  alias_method :include?, :within_realm?
348
351
 
349
352
  protected
350
353
 
351
- ### These methods define some of the boilerplate responses.
352
-
353
354
  # Returns an html form page for posting to an Identity Provider if the
354
355
  # GET request would exceed the upper URI length limit.
355
356
 
356
357
  def confirm_post_params(oid, realm, return_to, immediate)
357
- Rack::Response.new.finish do |r|
358
- r.write '<html><head><title>Confirm...</title></head><body>'
359
- r.write oid.form_markup(realm, return_to, immediate)
360
- r.write '</body></html>'
361
- end
358
+ response = Rack::Response.new '<html>'+
359
+ '<head><title>Confirm...</title></head>'+
360
+ '<body>'+oid.form_markup(realm, return_to, immediate)+'</body>'+
361
+ '</html>'
362
+ response.finish
362
363
  end
363
364
 
364
365
  # Returns a 303 redirect with the destination of that provided by the
365
366
  # argument.
366
367
 
367
368
  def redirect(uri)
368
- [ 303, {'Content-Length'=>'0', 'Content-Type'=>'text/plain',
369
+ [ 303, {'Content-Type'=>'text/plain', 'Content-Length'=>'0',
369
370
  'Location' => uri},
370
371
  [] ]
371
372
  end
@@ -401,10 +402,6 @@ module Rack
401
402
 
402
403
  private
403
404
 
404
- ### These methods are called after a transaction is completed, depending
405
- # on its outcome. These should all return a rack compatible response.
406
- # You'd want to override these to provide additional functionality.
407
-
408
405
  # Called to complete processing on a successful transaction.
409
406
  # Within the openid session, :openid_identity and :openid_identifier are
410
407
  # set to the user friendly and the standard representation of the
@@ -430,7 +427,7 @@ module Rack
430
427
  def setup_needed(oid, request, session)
431
428
  identifier = session[:openid_param]
432
429
  session[:setup_needed] = true
433
- redirect req.script_name + '?' + openid_param + '=' + identifier
430
+ redirect(req.script_name + '?' + openid_param + '=' + identifier)
434
431
  end
435
432
 
436
433
  # Called if the user indicates they wish to cancel identification.
@@ -448,6 +445,16 @@ module Rack
448
445
  def failure(oid, request, session)
449
446
  unauthorized
450
447
  end
448
+
449
+ # To be called if there is no method for handling the OpenID response
450
+ # status.
451
+
452
+ def invalid_status(oid, request, session)
453
+ msg = 'Invalid status returned by the OpenID authorization reponse.'
454
+ [ 500,
455
+ {'Content-Type'=>'text/plain','Content-Length'=>msg.length.to_s},
456
+ [msg] ]
457
+ end
451
458
  end
452
459
 
453
460
  # A class developed out of the request to use OpenID as an authentication
@@ -472,8 +479,8 @@ module Rack
472
479
  end
473
480
 
474
481
  def call(env)
475
- to = auth.call(env) ? @app : @oid
476
- to.call env
482
+ to = @authenticator.call(env) ? @app : @oid
483
+ to.call(env)
477
484
  end
478
485
  end
479
486
  end
@@ -4,31 +4,36 @@ module Rack
4
4
  # status codes).
5
5
 
6
6
  class Cascade
7
+ NotFound = [404, {}, []]
8
+
7
9
  attr_reader :apps
8
10
 
9
11
  def initialize(apps, catch=404)
10
- @apps = apps
11
- @catch = [*catch]
12
+ @apps = []; @has_app = {}
13
+ apps.each { |app| add app }
14
+
15
+ @catch = {}
16
+ [*catch].each { |status| @catch[status] = true }
12
17
  end
13
18
 
14
19
  def call(env)
15
- status = headers = body = nil
16
- raise ArgumentError, "empty cascade" if @apps.empty?
17
- @apps.each { |app|
18
- begin
19
- status, headers, body = app.call(env)
20
- break unless @catch.include?(status.to_i)
21
- end
22
- }
23
- [status, headers, body]
20
+ result = NotFound
21
+
22
+ @apps.each do |app|
23
+ result = app.call(env)
24
+ break unless @catch.include?(result[0].to_i)
25
+ end
26
+
27
+ result
24
28
  end
25
29
 
26
30
  def add app
31
+ @has_app[app] = true
27
32
  @apps << app
28
33
  end
29
34
 
30
35
  def include? app
31
- @apps.include? app
36
+ @has_app.include? app
32
37
  end
33
38
 
34
39
  alias_method :<<, :add