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
@@ -49,7 +49,7 @@ public:
49
49
  * Returns the time since the Epoch, measured in seconds. Or, if a time
50
50
  * was forced, then the forced time is returned instead.
51
51
  *
52
- * @throws SystemException Something went wrong while retrieving the time.
52
+ * @throws TimeRetrievalException Something went wrong while retrieving the time.
53
53
  * @throws boost::thread_interrupted
54
54
  */
55
55
  static time_t get() {
@@ -58,7 +58,8 @@ public:
58
58
  } else {
59
59
  time_t ret = syscalls::time(NULL);
60
60
  if (ret == -1) {
61
- throw SystemException("Unable to retrieve the system time",
61
+ throw TimeRetrievalException(
62
+ "Unable to retrieve the system time",
62
63
  errno);
63
64
  }
64
65
  return ret;
@@ -0,0 +1,88 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2008, 2009 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_TIMER_H_
26
+ #define _PASSENGER_TIMER_H_
27
+
28
+ #include <sys/time.h>
29
+
30
+ namespace Passenger {
31
+
32
+ /**
33
+ * A Timer which one can use to check how much time has elapsed since the timer started.
34
+ * This timer support microseconds-resolution, but the exact resolution depends on the OS
35
+ * and the hardware.
36
+ *
37
+ * @code
38
+ * Timer timer;
39
+ * sleep(10);
40
+ * timer.elapsed(); // => about 10000 (msec)
41
+ * @endcode
42
+ */
43
+ class Timer {
44
+ private:
45
+ struct timeval startTime;
46
+ public:
47
+ /**
48
+ * Creates a new Timer object.
49
+ *
50
+ * @param startNow Whether the timer should be started immediately.
51
+ */
52
+ Timer(bool startNow = true) {
53
+ if (startNow) {
54
+ start();
55
+ } else {
56
+ startTime.tv_sec = 0;
57
+ startTime.tv_usec = 0;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Start the timer. If the timer was already started, then this will
63
+ * restart the timer.
64
+ */
65
+ void start() {
66
+ gettimeofday(&startTime, NULL);
67
+ }
68
+
69
+ /**
70
+ * Checks how much time has elapsed since the timer was last started.
71
+ *
72
+ * @pre The timer must have been started.
73
+ * @return The elapsed time, in miliseconds.
74
+ */
75
+ unsigned long long elapsed() const {
76
+ struct timeval t;
77
+ unsigned long long now, beginning;
78
+
79
+ gettimeofday(&t, NULL);
80
+ now = (unsigned long long) t.tv_sec * 1000 + t.tv_usec / 1000;
81
+ beginning = (unsigned long long) startTime.tv_sec * 1000 + startTime.tv_usec / 1000;
82
+ return now - beginning;
83
+ }
84
+ };
85
+
86
+ } // namespace Passenger
87
+
88
+ #endif /* _PASSENGER_TIMER_H_ */
data/ext/common/Utils.cpp CHANGED
@@ -23,10 +23,16 @@
23
23
  * THE SOFTWARE.
24
24
  */
25
25
 
26
+ #include <oxt/system_calls.hpp>
27
+
28
+ #include <sys/socket.h>
29
+ #include <sys/types.h>
30
+ #include <sys/un.h>
26
31
  #include <cassert>
27
32
  #include <libgen.h>
28
33
  #include <pwd.h>
29
- #include "CachedFileStat.h"
34
+ #include "CachedFileStat.hpp"
35
+ #include "Exceptions.h"
30
36
  #include "Utils.h"
31
37
 
32
38
  #define SPAWN_SERVER_SCRIPT_NAME "passenger-spawn-server"
@@ -58,17 +64,17 @@ split(const string &str, char sep, vector<string> &output) {
58
64
  }
59
65
 
60
66
  bool
61
- fileExists(const char *filename, CachedMultiFileStat *mstat, unsigned int throttleRate) {
62
- return getFileType(filename, mstat, throttleRate) == FT_REGULAR;
67
+ fileExists(const char *filename, CachedFileStat *cstat, unsigned int throttleRate) {
68
+ return getFileType(filename, cstat, throttleRate) == FT_REGULAR;
63
69
  }
64
70
 
65
71
  FileType
66
- getFileType(const char *filename, CachedMultiFileStat *mstat, unsigned int throttleRate) {
72
+ getFileType(const char *filename, CachedFileStat *cstat, unsigned int throttleRate) {
67
73
  struct stat buf;
68
74
  int ret;
69
75
 
70
- if (mstat != NULL) {
71
- ret = cached_multi_file_stat_perform(mstat, filename, &buf, throttleRate);
76
+ if (cstat != NULL) {
77
+ ret = cstat->stat(filename, &buf, throttleRate);
72
78
  } else {
73
79
  ret = stat(filename, &buf);
74
80
  }
@@ -267,6 +273,29 @@ escapeForXml(const string &input) {
267
273
  return result;
268
274
  }
269
275
 
276
+ string
277
+ getProcessUsername() {
278
+ struct passwd pwd, *result;
279
+ char strings[1024];
280
+ int ret;
281
+
282
+ result = (struct passwd *) NULL;
283
+ do {
284
+ ret = getpwuid_r(getuid(), &pwd, strings, sizeof(strings), &result);
285
+ } while (ret == -1 && errno == EINTR);
286
+ if (ret == -1) {
287
+ result = (struct passwd *) NULL;
288
+ }
289
+
290
+ if (result == (struct passwd *) NULL) {
291
+ snprintf(strings, sizeof(strings), "UID %lld", (long long) getuid());
292
+ strings[sizeof(strings) - 1] = '\0';
293
+ return strings;
294
+ } else {
295
+ return result->pw_name;
296
+ }
297
+ }
298
+
270
299
  void
271
300
  determineLowestUserAndGroup(const string &user, uid_t &uid, gid_t &gid) {
272
301
  struct passwd *ent;
@@ -407,36 +436,6 @@ createPassengerTempDir(const string &parentDir, bool userSwitching,
407
436
  */
408
437
  makeDirTree(tmpDir + "/backends", "u=wxs,g=,o=");
409
438
  }
410
-
411
- if (geteuid() == 0) {
412
- if (userSwitching) {
413
- /* If user switching is possible and is on, then each backend
414
- * process may be running as a different user. So make the var
415
- * directory world-writable.
416
- *
417
- * The directory is not readable as a security precaution.
418
- */
419
- makeDirTree(tmpDir + "/var", "u=wxs,g=wx,o=wx");
420
- } else {
421
- /* If user switching is off then all backend processes
422
- * will be running as lowestUser, so make lowestUser the
423
- * owner of the var directory. Only lowestUser may access
424
- * the directory.
425
- *
426
- * The directory is not readble as a security precaution.
427
- */
428
- makeDirTree(tmpDir + "/var", "u=wxs,g=,o=", lowestUid, lowestGid);
429
- }
430
- } else {
431
- /* If user switching is not possible then all backend processes will
432
- * be running as the same user as the web server. So we'll make the
433
- * var subdirectory only accessible by this user. Nobody else
434
- * (except root) may access this subdirectory.
435
- *
436
- * The directory is not readble as a security precaution.
437
- */
438
- makeDirTree(tmpDir + "/var", "u=wxs,g=,o=");
439
- }
440
439
  }
441
440
 
442
441
  void
@@ -513,24 +512,144 @@ removeDirTree(const string &path) {
513
512
  }
514
513
 
515
514
  bool
516
- verifyRailsDir(const string &dir, CachedMultiFileStat *mstat, unsigned int throttleRate) {
515
+ verifyRailsDir(const string &dir, CachedFileStat *cstat, unsigned int throttleRate) {
517
516
  string temp(dir);
518
517
  temp.append("/config/environment.rb");
519
- return fileExists(temp.c_str(), mstat, throttleRate);
518
+ return fileExists(temp.c_str(), cstat, throttleRate);
520
519
  }
521
520
 
522
521
  bool
523
- verifyRackDir(const string &dir, CachedMultiFileStat *mstat, unsigned int throttleRate) {
522
+ verifyRackDir(const string &dir, CachedFileStat *cstat, unsigned int throttleRate) {
524
523
  string temp(dir);
525
524
  temp.append("/config.ru");
526
- return fileExists(temp.c_str(), mstat, throttleRate);
525
+ return fileExists(temp.c_str(), cstat, throttleRate);
527
526
  }
528
527
 
529
528
  bool
530
- verifyWSGIDir(const string &dir, CachedMultiFileStat *mstat, unsigned int throttleRate) {
529
+ verifyWSGIDir(const string &dir, CachedFileStat *cstat, unsigned int throttleRate) {
531
530
  string temp(dir);
532
531
  temp.append("/passenger_wsgi.py");
533
- return fileExists(temp.c_str(), mstat, throttleRate);
532
+ return fileExists(temp.c_str(), cstat, throttleRate);
533
+ }
534
+
535
+ int
536
+ createUnixServer(const char *filename, unsigned int backlogSize, bool autoDelete) {
537
+ struct sockaddr_un addr;
538
+ int fd, ret;
539
+
540
+ if (strlen(filename) > sizeof(addr.sun_path) - 1) {
541
+ string message = "Cannot create Unix socket '";
542
+ message.append(filename);
543
+ message.append("': filename is too long.");
544
+ throw RuntimeException(message);
545
+ }
546
+
547
+ fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
548
+ if (fd == -1) {
549
+ throw SystemException("Cannot create a Unix socket file descriptor", errno);
550
+ }
551
+
552
+ addr.sun_family = AF_UNIX;
553
+ strncpy(addr.sun_path, filename, sizeof(addr.sun_path));
554
+ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
555
+
556
+ if (autoDelete) {
557
+ do {
558
+ ret = unlink(filename);
559
+ } while (ret == -1 && errno == EINTR);
560
+ }
561
+
562
+ try {
563
+ ret = syscalls::bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
564
+ } catch (...) {
565
+ do {
566
+ ret = close(fd);
567
+ } while (ret == -1 && errno == EINTR);
568
+ throw;
569
+ }
570
+ if (ret == -1) {
571
+ int e = errno;
572
+ string message = "Cannot bind Unix socket '";
573
+ message.append(filename);
574
+ message.append("'");
575
+ do {
576
+ ret = close(fd);
577
+ } while (ret == -1 && errno == EINTR);
578
+ throw SystemException(message, e);
579
+ }
580
+
581
+ if (backlogSize == 0) {
582
+ #ifdef SOMAXCONN
583
+ backlogSize = SOMAXCONN;
584
+ #else
585
+ backlogSize = 128;
586
+ #endif
587
+ }
588
+ try {
589
+ ret = syscalls::listen(fd, backlogSize);
590
+ } catch (...) {
591
+ do {
592
+ ret = close(fd);
593
+ } while (ret == -1 && errno == EINTR);
594
+ throw;
595
+ }
596
+ if (ret == -1) {
597
+ int e = errno;
598
+ string message = "Cannot listen on Unix socket '";
599
+ message.append(filename);
600
+ message.append("'");
601
+ do {
602
+ ret = close(fd);
603
+ } while (ret == -1 && errno == EINTR);
604
+ throw SystemException(message, e);
605
+ }
606
+
607
+ return fd;
608
+ }
609
+
610
+ int
611
+ connectToUnixServer(const char *filename) {
612
+ int fd, ret;
613
+ struct sockaddr_un addr;
614
+
615
+ if (strlen(filename) > sizeof(addr.sun_path) - 1) {
616
+ string message = "Cannot connect to Unix socket '";
617
+ message.append(filename);
618
+ message.append("': filename is too long.");
619
+ throw RuntimeException(message);
620
+ }
621
+
622
+ do {
623
+ fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
624
+ } while (fd == -1 && errno == EINTR);
625
+ if (fd == -1) {
626
+ throw SystemException("Cannot create a Unix socket file descriptor", errno);
627
+ }
628
+
629
+ addr.sun_family = AF_UNIX;
630
+ strncpy(addr.sun_path, filename, sizeof(addr.sun_path));
631
+ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
632
+
633
+ try {
634
+ ret = syscalls::connect(fd, (const sockaddr *) &addr, sizeof(addr));
635
+ } catch (...) {
636
+ do {
637
+ ret = close(fd);
638
+ } while (ret == -1 && errno == EINTR);
639
+ throw;
640
+ }
641
+ if (ret == -1) {
642
+ int e = errno;
643
+ string message("Cannot connect to Unix socket '");
644
+ message.append(filename);
645
+ message.append("'");
646
+ do {
647
+ ret = close(fd);
648
+ } while (ret == -1 && errno == EINTR);
649
+ throw SystemException(message, e);
650
+ }
651
+
652
+ return fd;
534
653
  }
535
654
 
536
655
  } // namespace Passenger
data/ext/common/Utils.h CHANGED
@@ -40,13 +40,13 @@
40
40
  #include <unistd.h>
41
41
  #include "Exceptions.h"
42
42
 
43
- typedef struct CachedMultiFileStat CachedMultiFileStat;
44
-
45
43
  namespace Passenger {
46
44
 
47
45
  using namespace std;
48
46
  using namespace boost;
49
47
 
48
+ typedef struct CachedFileStat CachedFileStat;
49
+
50
50
  /** Enumeration which indicates what kind of file a file is. */
51
51
  typedef enum {
52
52
  /** The file doesn't exist. */
@@ -158,31 +158,34 @@ void split(const string &str, char sep, vector<string> &output);
158
158
  * Check whether the specified file exists.
159
159
  *
160
160
  * @param filename The filename to check.
161
- * @param mstat A CachedMultiFileStat object, if you want to use cached statting.
162
- * @param throttleRate A throttle rate for mstat. Only applicable if mstat is not NULL.
161
+ * @param cstat A CachedFileStat object, if you want to use cached statting.
162
+ * @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
163
163
  * @return Whether the file exists.
164
164
  * @throws FileSystemException Unable to check because of a filesystem error.
165
+ * @throws TimeRetrievalException
166
+ * @throws boost::thread_interrupted
165
167
  * @ingroup Support
166
168
  */
167
- bool fileExists(const char *filename, CachedMultiFileStat *mstat = 0,
169
+ bool fileExists(const char *filename, CachedFileStat *cstat = 0,
168
170
  unsigned int throttleRate = 0);
169
171
 
170
172
  /**
171
173
  * Check whether 'filename' exists and what kind of file it is.
172
174
  *
173
175
  * @param filename The filename to check.
174
- * @param mstat A CachedMultiFileStat object, if you want to use cached statting.
175
- * @param throttleRate A throttle rate for mstat. Only applicable if mstat is not NULL.
176
+ * @param mstat A CachedFileStat object, if you want to use cached statting.
177
+ * @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
176
178
  * @return The file type.
177
179
  * @throws FileSystemException Unable to check because of a filesystem error.
180
+ * @throws TimeRetrievalException
181
+ * @throws boost::thread_interrupted
178
182
  * @ingroup Support
179
183
  */
180
- FileType getFileType(const char *filename, CachedMultiFileStat *mstat = 0,
184
+ FileType getFileType(const char *filename, CachedFileStat *cstat = 0,
181
185
  unsigned int throttleRate = 0);
182
186
 
183
187
  /**
184
188
  * Find the location of the Passenger spawn server script.
185
- * If passengerRoot is given, t T
186
189
  *
187
190
  * @param passengerRoot The Passenger root folder. If NULL is given, then
188
191
  * the spawn server is found by scanning $PATH. For security reasons,
@@ -246,6 +249,13 @@ string extractDirName(const string &path);
246
249
  */
247
250
  string escapeForXml(const string &input);
248
251
 
252
+ /**
253
+ * Returns the username of the user that the current process is running as.
254
+ * If the user has no associated username, then the "UID xxxx" is returned,
255
+ * where xxxx is the current UID.
256
+ */
257
+ string getProcessUsername();
258
+
249
259
  /**
250
260
  * Given a username that's supposed to be the "lowest user" in the user switching mechanism,
251
261
  * checks whether this username exists. If so, this users's UID and GID will be stored into
@@ -308,8 +318,6 @@ void setPassengerTempDir(const string &dir);
308
318
  * about a running Phusion Passenger instance.
309
319
  * - backends - for storing Unix sockets created by backend processes.
310
320
  * - master - for storing files such as the Passenger HelperServer socket.
311
- * - var - for storing all other kinds of temp files that the backend processes
312
- * create.
313
321
  *
314
322
  * If a (sub)directory already exists, then it will not result in an error.
315
323
  *
@@ -359,7 +367,7 @@ void createPassengerTempDir(const string &parentDir, bool userSwitching,
359
367
  * @throws SystemException Something went wrong.
360
368
  * @throws FileSystemException Something went wrong.
361
369
  */
362
- void makeDirTree(const string &path, const char *mode = "u=rwx,g=,o=", uid_t owner = -1, gid_t group = -1);
370
+ void makeDirTree(const string &path, const char *mode = "u=rwx,g=,o=", uid_t owner = (uid_t) -1, gid_t group = (gid_t) -1);
363
371
 
364
372
  /**
365
373
  * Remove an entire directory tree recursively.
@@ -372,38 +380,69 @@ void removeDirTree(const string &path);
372
380
  * Check whether the specified directory is a valid Ruby on Rails
373
381
  * application root directory.
374
382
  *
375
- * @param mstat A CachedMultiFileStat object, if you want to use cached statting.
376
- * @param throttleRate A throttle rate for mstat. Only applicable if mstat is not NULL.
383
+ * @param cstat A CachedFileStat object, if you want to use cached statting.
384
+ * @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
377
385
  * @throws FileSystemException Unable to check because of a system error.
386
+ * @throws TimeRetrievalException
387
+ * @throws boost::thread_interrupted
378
388
  * @ingroup Support
379
389
  */
380
- bool verifyRailsDir(const string &dir, CachedMultiFileStat *mstat = 0,
390
+ bool verifyRailsDir(const string &dir, CachedFileStat *cstat = 0,
381
391
  unsigned int throttleRate = 0);
382
392
 
383
393
  /**
384
394
  * Check whether the specified directory is a valid Rack application
385
395
  * root directory.
386
396
  *
387
- * @param mstat A CachedMultiFileStat object, if you want to use cached statting.
388
- * @param throttleRate A throttle rate for mstat. Only applicable if mstat is not NULL.
397
+ * @param cstat A CachedFileStat object, if you want to use cached statting.
398
+ * @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
389
399
  * @throws FileSystemException Unable to check because of a filesystem error.
400
+ * @throws TimeRetrievalException
401
+ * @throws boost::thread_interrupted
390
402
  * @ingroup Support
391
403
  */
392
- bool verifyRackDir(const string &dir, CachedMultiFileStat *mstat = 0,
404
+ bool verifyRackDir(const string &dir, CachedFileStat *cstat = 0,
393
405
  unsigned int throttleRate = 0);
394
406
 
395
407
  /**
396
408
  * Check whether the specified directory is a valid WSGI application
397
409
  * root directory.
398
410
  *
399
- * @param mstat A CachedMultiFileStat object, if you want to use cached statting.
400
- * @param throttleRate A throttle rate for mstat. Only applicable if mstat is not NULL.
411
+ * @param cstat A CachedFileStat object, if you want to use cached statting.
412
+ * @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL.
401
413
  * @throws FileSystemException Unable to check because of a filesystem error.
414
+ * @throws TimeRetrievalException
415
+ * @throws boost::thread_interrupted
402
416
  * @ingroup Support
403
417
  */
404
- bool verifyWSGIDir(const string &dir, CachedMultiFileStat *mstat = 0,
418
+ bool verifyWSGIDir(const string &dir, CachedFileStat *cstat = 0,
405
419
  unsigned int throttleRate = 0);
406
420
 
421
+ /**
422
+ * Create a new Unix server socket which is bounded to <tt>filename</tt>.
423
+ *
424
+ * @param filename The filename to bind the socket to.
425
+ * @param backlogSize The size of the socket's backlog. Specify 0 to use the
426
+ * platform's maximum allowed backlog size.
427
+ * @param autoDelete Whether <tt>filename</tt> should be deleted, if it already exists.
428
+ * @return The file descriptor of the newly created Unix server socket.
429
+ * @throws RuntimeException Something went wrong.
430
+ * @throws SystemException Something went wrong while creating the Unix server socket.
431
+ * @throws boost::thread_interrupted A system call has been interrupted.
432
+ */
433
+ int createUnixServer(const char *filename, unsigned int backlogSize = 0, bool autoDelete = true);
434
+
435
+ /**
436
+ * Connect to a Unix server socket at <tt>filename</tt>.
437
+ *
438
+ * @param filename The filename of the socket to connect to.
439
+ * @return The file descriptor of the connected client socket.
440
+ * @throws RuntimeException Something went wrong.
441
+ * @throws SystemException Something went wrong while connecting to the Unix server.
442
+ * @throws boost::thread_interrupted A system call has been interrupted.
443
+ */
444
+ int connectToUnixServer(const char *filename);
445
+
407
446
  /**
408
447
  * Represents a buffered upload file.
409
448
  *
@@ -419,11 +458,11 @@ public:
419
458
  *
420
459
  * @throws SystemException Something went wrong.
421
460
  */
422
- BufferedUpload(const char *identifier = "temp") {
461
+ BufferedUpload(const string &dir, const char *identifier = "temp") {
423
462
  char templ[PATH_MAX];
424
463
  int fd;
425
464
 
426
- snprintf(templ, sizeof(templ), "%s/%s.XXXXXX", getDir().c_str(), identifier);
465
+ snprintf(templ, sizeof(templ), "%s/%s.XXXXXX", dir.c_str(), identifier);
427
466
  templ[sizeof(templ) - 1] = '\0';
428
467
  fd = mkstemp(templ);
429
468
  if (fd == -1) {
@@ -450,14 +489,6 @@ public:
450
489
  ~BufferedUpload() {
451
490
  fclose(handle);
452
491
  }
453
-
454
- /**
455
- * Returns the directory in which upload buffer files are stored.
456
- * This is a subdirectory of the directory returned by getPassengerTempDir().
457
- */
458
- static string getDir() {
459
- return getPassengerTempDir() + "/webserver_private";
460
- }
461
492
  };
462
493
 
463
494
  } // namespace Passenger