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.
- data/DEVELOPERS.TXT +13 -3
- data/Rakefile +42 -33
- data/bin/passenger-install-apache2-module +1 -2
- data/bin/passenger-install-nginx-module +7 -19
- data/bin/passenger-status +64 -15
- data/bin/passenger-stress-test +2 -2
- data/doc/ApplicationPool algorithm.txt +26 -22
- data/doc/Users guide Apache.html +374 -149
- data/doc/Users guide Apache.txt +318 -51
- data/doc/Users guide Nginx.html +13 -13
- data/doc/Users guide Nginx.txt +7 -2
- data/doc/cxxapi/Bucket_8h-source.html +62 -25
- data/doc/cxxapi/Configuration_8h-source.html +343 -326
- data/doc/cxxapi/DirectoryMapper_8h-source.html +12 -12
- data/doc/cxxapi/Hooks_8h-source.html +1 -1
- data/doc/cxxapi/annotated.html +1 -1
- data/doc/cxxapi/classHooks-members.html +1 -1
- data/doc/cxxapi/classHooks.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -2
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +9 -9
- data/doc/cxxapi/classes.html +1 -1
- data/doc/cxxapi/definitions_8h-source.html +1 -1
- data/doc/cxxapi/files.html +1 -1
- data/doc/cxxapi/functions.html +2 -2
- data/doc/cxxapi/functions_func.html +2 -2
- data/doc/cxxapi/graph_legend.html +1 -1
- data/doc/cxxapi/group__Configuration.html +1 -1
- data/doc/cxxapi/group__Core.html +1 -1
- data/doc/cxxapi/group__Hooks.html +1 -1
- data/doc/cxxapi/group__Support.html +1 -1
- data/doc/cxxapi/main.html +1 -1
- data/doc/cxxapi/modules.html +1 -1
- data/doc/rdoc/classes/ConditionVariable.html +194 -0
- data/doc/rdoc/classes/Exception.html +120 -0
- data/doc/rdoc/classes/GC.html +113 -0
- data/doc/rdoc/classes/IO.html +169 -0
- data/doc/rdoc/classes/PhusionPassenger.html +238 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +153 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +517 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +719 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +97 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +96 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +97 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +96 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +317 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +154 -0
- data/doc/rdoc/classes/PhusionPassenger/Application.html +283 -0
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +172 -0
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +145 -0
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +175 -0
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +141 -0
- data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +489 -0
- data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +350 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +188 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +194 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +442 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +436 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +155 -0
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +402 -0
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +125 -0
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +805 -0
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +140 -0
- data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
- data/doc/rdoc/classes/PlatformInfo.html +831 -0
- data/doc/rdoc/classes/RakeExtensions.html +197 -0
- data/doc/rdoc/classes/Signal.html +131 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/DEVELOPERS_TXT.html +255 -0
- data/doc/rdoc/files/README.html +157 -0
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +92 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +129 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +131 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +130 -0
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +130 -0
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +134 -0
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +133 -0
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +143 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +145 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +127 -0
- data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +161 -0
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +175 -0
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +129 -0
- data/doc/rdoc/files/misc/rake/extensions_rb.html +130 -0
- data/doc/rdoc/fr_class_index.html +90 -0
- data/doc/rdoc/fr_file_index.html +76 -0
- data/doc/rdoc/fr_method_index.html +200 -0
- data/doc/rdoc/index.html +26 -0
- data/doc/rdoc/rdoc-style.css +187 -0
- data/doc/users_guide_snippets/rackup_specifications.txt +2 -8
- data/ext/apache2/Bucket.cpp +71 -38
- data/ext/apache2/Bucket.h +53 -16
- data/ext/apache2/Configuration.cpp +15 -0
- data/ext/apache2/Configuration.h +19 -2
- data/ext/apache2/DirectoryMapper.h +10 -10
- data/ext/apache2/Hooks.cpp +334 -74
- data/ext/boost/mpl/apply.hpp +5 -1
- data/ext/boost/mpl/apply_wrap.hpp +5 -2
- data/ext/boost/mpl/aux_/full_lambda.hpp +5 -1
- data/ext/boost/mpl/bind.hpp +5 -1
- data/ext/common/Application.h +11 -31
- data/ext/common/ApplicationPool.h +2 -1
- data/ext/common/ApplicationPoolServer.h +61 -20
- data/ext/common/ApplicationPoolServerExecutable.cpp +132 -4
- data/ext/common/ApplicationPoolStatusReporter.h +189 -65
- data/ext/common/Base64.cpp +143 -0
- data/ext/common/Base64.h +57 -0
- data/ext/common/CachedFileStat.cpp +25 -82
- data/ext/common/CachedFileStat.h +11 -125
- data/ext/common/CachedFileStat.hpp +243 -0
- data/ext/common/Exceptions.h +13 -0
- data/ext/common/FileChangeChecker.h +209 -0
- data/ext/common/Logging.h +3 -2
- data/ext/common/MessageChannel.h +10 -10
- data/ext/common/PoolOptions.h +72 -5
- data/ext/common/SpawnManager.h +11 -8
- data/ext/common/StandardApplicationPool.h +38 -39
- data/ext/common/StaticString.h +1 -0
- data/ext/common/StringListCreator.h +83 -0
- data/ext/common/SystemTime.h +3 -2
- data/ext/common/Timer.h +88 -0
- data/ext/common/Utils.cpp +161 -42
- data/ext/common/Utils.h +62 -31
- data/ext/common/Version.h +1 -1
- data/ext/nginx/Configuration.c +0 -4
- data/ext/nginx/ContentHandler.c +8 -6
- data/ext/nginx/HelperServer.cpp +45 -55
- data/ext/nginx/HttpStatusExtractor.h +4 -0
- data/ext/nginx/StaticContentHandler.c +25 -5
- data/ext/nginx/config +3 -0
- data/ext/nginx/ngx_http_passenger_module.c +72 -17
- data/ext/nginx/ngx_http_passenger_module.h +2 -2
- data/lib/phusion_passenger/abstract_request_handler.rb +15 -7
- data/lib/phusion_passenger/abstract_server.rb +16 -2
- data/lib/phusion_passenger/admin_tools/control_process.rb +36 -25
- data/lib/phusion_passenger/constants.rb +1 -1
- data/lib/phusion_passenger/dependencies.rb +10 -0
- data/lib/phusion_passenger/platform_info.rb +1 -1
- data/lib/phusion_passenger/rack/application_spawner.rb +21 -2
- data/lib/phusion_passenger/rack/request_handler.rb +10 -0
- data/lib/phusion_passenger/railz/application_spawner.rb +38 -2
- data/lib/phusion_passenger/railz/framework_spawner.rb +26 -28
- data/lib/phusion_passenger/railz/request_handler.rb +5 -1
- data/lib/phusion_passenger/spawn_manager.rb +6 -2
- data/lib/phusion_passenger/utils.rb +79 -27
- data/misc/rake/cplusplus.rb +5 -5
- data/test/ApplicationPoolServerTest.cpp +42 -0
- data/test/ApplicationPoolTest.cpp +255 -267
- data/test/Base64Test.cpp +48 -0
- data/test/CachedFileStatTest.cpp +243 -103
- data/test/FileChangeCheckerTest.cpp +331 -0
- data/test/PoolOptionsTest.cpp +80 -0
- data/test/UtilsTest.cpp +5 -17
- data/test/integration_tests/apache2_tests.rb +15 -4
- data/test/integration_tests/mycook_spec.rb +3 -4
- data/test/oxt/syscall_interruption_test.cpp +2 -14
- data/test/ruby/abstract_server_collection_spec.rb +1 -1
- data/test/ruby/abstract_server_spec.rb +35 -1
- data/test/ruby/rack/application_spawner_spec.rb +23 -6
- data/test/ruby/rails/application_spawner_spec.rb +6 -6
- data/test/ruby/rails/framework_spawner_spec.rb +6 -5
- data/test/ruby/rails/minimal_spawner_spec.rb +19 -0
- data/test/ruby/rails/spawner_error_handling_spec.rb +62 -7
- data/test/ruby/spawn_manager_spec.rb +10 -7
- data/test/ruby/spawn_server_spec.rb +1 -1
- data/test/ruby/utils_spec.rb +193 -20
- data/test/ruby/wsgi/application_spawner_spec.rb +3 -1
- data/test/stub/apache2/httpd.conf.erb +3 -0
- data/test/stub/rack/config.ru +1 -1
- data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +8 -0
- data/test/support/Support.cpp +84 -0
- data/test/support/Support.h +66 -8
- data/test/support/config.rb +14 -2
- data/test/support/test_helper.rb +5 -0
- data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +123 -116
- data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +17 -12
- data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +34 -43
- data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +1 -1
- data/vendor/rack-1.0.0-git/lib/rack/mock.rb +4 -17
- data/vendor/rack-1.0.0-git/lib/rack/request.rb +3 -9
- data/vendor/rack-1.0.0-git/lib/rack/rewindable_input.rb +2 -0
- data/vendor/rack-1.0.0-git/lib/rack/utils.rb +38 -12
- metadata +231 -186
- data/ext/common/FileChecker.h +0 -112
- data/test/FileCheckerTest.cpp +0 -79
- data/test/stub/minimal-railsapp/README +0 -3
- data/test/stub/minimal-railsapp/config/application.rb +0 -0
- data/test/stub/minimal-railsapp/config/environment.rb +0 -3
- data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -10
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -7
- data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -17
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -8
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -1
- data/test/stub/railsapp/app/controllers/application.rb +0 -12
- data/test/stub/railsapp/app/controllers/bar_controller.rb +0 -5
- data/test/stub/railsapp/app/controllers/bar_controller_1.txt +0 -5
- data/test/stub/railsapp/app/controllers/bar_controller_2.txt +0 -5
- data/test/stub/railsapp/app/controllers/foo_controller.rb +0 -9
- data/test/stub/railsapp/app/helpers/application_helper.rb +0 -3
- data/test/stub/railsapp/config/boot.rb +0 -108
- data/test/stub/railsapp/config/database.yml +0 -19
- data/test/stub/railsapp/config/environment.rb +0 -59
- data/test/stub/railsapp/config/environments/development.rb +0 -18
- data/test/stub/railsapp/config/environments/production.rb +0 -19
- data/test/stub/railsapp/config/initializers/inflections.rb +0 -10
- data/test/stub/railsapp/config/initializers/mime_types.rb +0 -5
- data/test/stub/railsapp/config/routes.rb +0 -35
- data/test/stub/railsapp/public/useless.txt +0 -1
- data/test/stub/railsapp2/app/controllers/application.rb +0 -12
- data/test/stub/railsapp2/app/controllers/foo_controller.rb +0 -5
- data/test/stub/railsapp2/app/helpers/application_helper.rb +0 -3
- data/test/stub/railsapp2/config/boot.rb +0 -108
- data/test/stub/railsapp2/config/database.yml +0 -19
- data/test/stub/railsapp2/config/environment.rb +0 -59
- data/test/stub/railsapp2/config/environments/development.rb +0 -18
- data/test/stub/railsapp2/config/environments/production.rb +0 -19
- data/test/stub/railsapp2/config/initializers/inflections.rb +0 -10
- data/test/stub/railsapp2/config/initializers/mime_types.rb +0 -5
- data/test/stub/railsapp2/config/routes.rb +0 -35
- data/test/stub/railsapp2/public/useless.txt +0 -1
data/ext/common/Version.h
CHANGED
data/ext/nginx/Configuration.c
CHANGED
@@ -83,10 +83,6 @@ passenger_init_main_conf(ngx_conf_t *cf, void *conf_pointer)
|
|
83
83
|
conf = &passenger_main_conf;
|
84
84
|
*conf = *((passenger_main_conf_t *) conf_pointer);
|
85
85
|
|
86
|
-
if (conf->root_dir.len == 0) {
|
87
|
-
return "-- The 'passenger_root' directive must be set";
|
88
|
-
}
|
89
|
-
|
90
86
|
if (conf->ruby.len == 0) {
|
91
87
|
conf->ruby.data = (u_char *) "ruby";
|
92
88
|
conf->ruby.len = sizeof("ruby") - 1;
|
data/ext/nginx/ContentHandler.c
CHANGED
@@ -63,10 +63,10 @@ get_file_type(const u_char *filename, unsigned int throttle_rate) {
|
|
63
63
|
struct stat buf;
|
64
64
|
int ret;
|
65
65
|
|
66
|
-
ret =
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
ret = cached_file_stat_perform(passenger_stat_cache,
|
67
|
+
(const char *) filename,
|
68
|
+
&buf,
|
69
|
+
throttle_rate);
|
70
70
|
if (ret == 0) {
|
71
71
|
if (S_ISREG(buf.st_mode)) {
|
72
72
|
return FT_FILE;
|
@@ -105,7 +105,7 @@ detect_application_type(const ngx_str_t *public_dir) {
|
|
105
105
|
|
106
106
|
ngx_memzero(filename, sizeof(filename));
|
107
107
|
ngx_snprintf(filename, sizeof(filename), "%s/%s",
|
108
|
-
public_dir->data, "../
|
108
|
+
public_dir->data, "../passenger_wsgi.py");
|
109
109
|
if (file_exists(filename, 1)) {
|
110
110
|
return AP_WSGI;
|
111
111
|
}
|
@@ -1077,7 +1077,9 @@ passenger_content_handler(ngx_http_request_t *r)
|
|
1077
1077
|
ngx_str_t page_cache_file;
|
1078
1078
|
passenger_context_t *context;
|
1079
1079
|
|
1080
|
-
if (
|
1080
|
+
if (passenger_main_conf.root_dir.len == 0) {
|
1081
|
+
return NGX_DECLINED;
|
1082
|
+
} else if (r->subrequest_in_memory) {
|
1081
1083
|
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
1082
1084
|
"ngx_http_passenger_module does not support "
|
1083
1085
|
"subrequest in memory");
|
data/ext/nginx/HelperServer.cpp
CHANGED
@@ -122,6 +122,8 @@ public:
|
|
122
122
|
}
|
123
123
|
};
|
124
124
|
|
125
|
+
struct ClientDisconnectedException { };
|
126
|
+
|
125
127
|
/**
|
126
128
|
* A representation of a Client from the Server's point of view. This class
|
127
129
|
* contains the methods used to communicate from a server to a connected
|
@@ -311,7 +313,12 @@ private:
|
|
311
313
|
*
|
312
314
|
* @param session The Ruby on Rails session to read the response from.
|
313
315
|
* @param clientFd The client file descriptor to write the response to.
|
314
|
-
* @throws SystemException
|
316
|
+
* @throws SystemException Something went wrong while reading the response
|
317
|
+
* from the backend process or while writing to the
|
318
|
+
* response back to the web server.
|
319
|
+
* @throws ClientDisconnectedException The HTTP client closed the connection
|
320
|
+
* before we were able to send back the
|
321
|
+
* full response.
|
315
322
|
*/
|
316
323
|
void forwardResponse(Application::SessionPtr &session, FileDescriptor &clientFd) {
|
317
324
|
TRACE_POINT();
|
@@ -339,13 +346,21 @@ private:
|
|
339
346
|
* of the response data.
|
340
347
|
*/
|
341
348
|
UPDATE_TRACE_POINT();
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
+
try {
|
350
|
+
string statusLine("HTTP/1.1 ");
|
351
|
+
statusLine.append(ex.getStatusLine());
|
352
|
+
UPDATE_TRACE_POINT();
|
353
|
+
output.writeRaw(statusLine.c_str(), statusLine.size());
|
354
|
+
UPDATE_TRACE_POINT();
|
355
|
+
output.writeRaw(ex.getBuffer().c_str(), ex.getBuffer().size());
|
356
|
+
break;
|
357
|
+
} catch (const SystemException &e) {
|
358
|
+
if (e.code() == EPIPE) {
|
359
|
+
throw ClientDisconnectedException();
|
360
|
+
} else {
|
361
|
+
throw;
|
362
|
+
}
|
363
|
+
}
|
349
364
|
}
|
350
365
|
}
|
351
366
|
|
@@ -359,7 +374,15 @@ private:
|
|
359
374
|
throw SystemException("Cannot read response from backend process", errno);
|
360
375
|
} else {
|
361
376
|
UPDATE_TRACE_POINT();
|
362
|
-
|
377
|
+
try {
|
378
|
+
output.writeRaw(buf, size);
|
379
|
+
} catch (const SystemException &e) {
|
380
|
+
if (e.code() == EPIPE) {
|
381
|
+
throw ClientDisconnectedException();
|
382
|
+
} else {
|
383
|
+
throw;
|
384
|
+
}
|
385
|
+
}
|
363
386
|
}
|
364
387
|
}
|
365
388
|
}
|
@@ -399,10 +422,8 @@ private:
|
|
399
422
|
* Handles an SCGI request from a client whose identity is derived by the given <tt>clientFd</tt>.
|
400
423
|
*
|
401
424
|
* @param clientFd The file descriptor identifying the client to handle the request from.
|
402
|
-
* @return True if an error occurred while trying to handle the request of the client. False if
|
403
|
-
* the request was succesfully processed.
|
404
425
|
*/
|
405
|
-
|
426
|
+
void handleRequest(FileDescriptor &clientFd) {
|
406
427
|
TRACE_POINT();
|
407
428
|
ScgiRequestParser parser;
|
408
429
|
string partialRequestBody;
|
@@ -410,18 +431,19 @@ private:
|
|
410
431
|
|
411
432
|
if (!readAndCheckPassword(clientFd)) {
|
412
433
|
P_ERROR("Client did not send a correct password.");
|
413
|
-
return
|
434
|
+
return;
|
414
435
|
}
|
415
436
|
if (!readAndParseRequestHeaders(clientFd, parser, partialRequestBody)) {
|
416
|
-
return
|
437
|
+
return;
|
417
438
|
}
|
418
439
|
|
419
440
|
try {
|
420
441
|
PoolOptions options;
|
421
|
-
if (parser.getHeader("
|
442
|
+
if (parser.getHeader("SCRIPT_NAME").empty()) {
|
422
443
|
options.appRoot = extractDirName(parser.getHeader("DOCUMENT_ROOT"));
|
423
444
|
} else {
|
424
445
|
options.appRoot = extractDirName(resolveSymlink(parser.getHeader("DOCUMENT_ROOT")));
|
446
|
+
options.baseURI = parser.getHeader("SCRIPT_NAME");
|
425
447
|
}
|
426
448
|
options.useGlobalQueue = parser.getHeader("PASSENGER_USE_GLOBAL_QUEUE") == "true";
|
427
449
|
options.environment = parser.getHeader("PASSENGER_ENVIRONMENT");
|
@@ -450,23 +472,23 @@ private:
|
|
450
472
|
forwardResponse(session, clientFd);
|
451
473
|
} catch (const SpawnException &e) {
|
452
474
|
handleSpawnException(clientFd, e);
|
475
|
+
} catch (const ClientDisconnectedException &) {
|
476
|
+
P_WARN("Couldn't forward the HTTP response back to the HTTP client: "
|
477
|
+
"It seems the user clicked on the 'Stop' button in his "
|
478
|
+
"browser.");
|
453
479
|
}
|
454
|
-
return false;
|
455
480
|
} catch (const boost::thread_interrupted &) {
|
456
481
|
throw;
|
457
482
|
} catch (const tracable_exception &e) {
|
458
483
|
P_ERROR("Uncaught exception in PassengerServer client thread:\n"
|
459
484
|
<< " exception: " << e.what() << "\n"
|
460
485
|
<< " backtrace:\n" << e.backtrace());
|
461
|
-
return true;
|
462
486
|
} catch (const exception &e) {
|
463
487
|
P_ERROR("Uncaught exception in PassengerServer client thread:\n"
|
464
488
|
<< " exception: " << e.what() << "\n"
|
465
489
|
<< " backtrace: not available");
|
466
|
-
return true;
|
467
490
|
} catch (...) {
|
468
491
|
P_ERROR("Uncaught unknown exception in PassengerServer client thread.");
|
469
|
-
return true;
|
470
492
|
}
|
471
493
|
}
|
472
494
|
|
@@ -555,8 +577,6 @@ typedef shared_ptr<Client> ClientPtr;
|
|
555
577
|
*/
|
556
578
|
class Server {
|
557
579
|
private:
|
558
|
-
static const unsigned int BACKLOG_SIZE = 50;
|
559
|
-
|
560
580
|
string password;
|
561
581
|
int adminPipe;
|
562
582
|
int serverSocket;
|
@@ -573,45 +593,15 @@ private:
|
|
573
593
|
* attempt to bind on. Once it is bound, it will start listening for incoming client
|
574
594
|
* activity.
|
575
595
|
*
|
576
|
-
* @throws SystemException
|
596
|
+
* @throws SystemException Something went wrong while trying to create and bind to the Unix socket.
|
597
|
+
* @throws RuntimeException Something went wrong.
|
577
598
|
*/
|
578
599
|
void startListening() {
|
579
600
|
this_thread::disable_syscall_interruption dsi;
|
580
601
|
string socketName = getPassengerTempDir() + "/master/helper_server.sock";
|
581
|
-
|
582
|
-
int ret;
|
583
|
-
|
584
|
-
serverSocket = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
|
585
|
-
if (serverSocket == -1) {
|
586
|
-
throw SystemException("Cannot create an unconnected Unix socket", errno);
|
587
|
-
}
|
588
|
-
|
589
|
-
addr.sun_family = AF_UNIX;
|
590
|
-
strncpy(addr.sun_path, socketName.c_str(), sizeof(addr.sun_path));
|
591
|
-
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
592
|
-
|
593
|
-
ret = syscalls::bind(serverSocket, (const struct sockaddr *) &addr, sizeof(addr));
|
594
|
-
if (ret == -1) {
|
595
|
-
int e = errno;
|
596
|
-
syscalls::close(serverSocket);
|
597
|
-
|
598
|
-
string message("Cannot bind on Unix socket '");
|
599
|
-
message.append(socketName);
|
600
|
-
message.append("'");
|
601
|
-
throw SystemException(message, e);
|
602
|
-
}
|
603
|
-
|
604
|
-
ret = syscalls::listen(serverSocket, BACKLOG_SIZE);
|
605
|
-
if (ret == -1) {
|
606
|
-
int e = errno;
|
607
|
-
syscalls::close(serverSocket);
|
608
|
-
|
609
|
-
string message("Cannot bind on Unix socket '");
|
610
|
-
message.append(socketName);
|
611
|
-
message.append("'");
|
612
|
-
throw SystemException(message, e);
|
613
|
-
}
|
602
|
+
serverSocket = createUnixServer(socketName.c_str());
|
614
603
|
|
604
|
+
int ret;
|
615
605
|
do {
|
616
606
|
ret = chmod(socketName.c_str(), S_ISVTX |
|
617
607
|
S_IRUSR | S_IWUSR | S_IXUSR |
|
@@ -159,6 +159,10 @@ private:
|
|
159
159
|
case 307:
|
160
160
|
statusLine = "307 Temporary Redirect\x0D\x0A";
|
161
161
|
break;
|
162
|
+
case 308:
|
163
|
+
// Google Gears: http://code.google.com/p/gears/wiki/ResumableHttpRequestsProposal
|
164
|
+
statusLine = "308 Resume Incomplete\x0D\x0A";
|
165
|
+
break;
|
162
166
|
case 400:
|
163
167
|
statusLine = "400 Bad Request\x0D\x0A";
|
164
168
|
break;
|
@@ -26,6 +26,25 @@
|
|
26
26
|
|
27
27
|
#include "StaticContentHandler.h"
|
28
28
|
|
29
|
+
static void
|
30
|
+
set_request_extension(ngx_http_request_t *r, ngx_str_t *filename) {
|
31
|
+
u_char *tmp;
|
32
|
+
|
33
|
+
/* Scan filename from the right until we've found a slash or a dot. */
|
34
|
+
tmp = filename->data + filename->len - 1;
|
35
|
+
while (tmp >= filename->data && *tmp != '/' && *tmp != '.') {
|
36
|
+
tmp--;
|
37
|
+
}
|
38
|
+
if (tmp >= filename->data && *tmp == '.') {
|
39
|
+
/* We found a dot, and until now we haven't seen any slashes.
|
40
|
+
* So we know that this is the filename's extension.
|
41
|
+
*/
|
42
|
+
tmp++;
|
43
|
+
r->exten.data = tmp;
|
44
|
+
r->exten.len = filename->len - (tmp - filename->data);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
29
48
|
ngx_int_t
|
30
49
|
passenger_static_content_handler(ngx_http_request_t *r, ngx_str_t *filename)
|
31
50
|
{
|
@@ -58,10 +77,10 @@ passenger_static_content_handler(ngx_http_request_t *r, ngx_str_t *filename)
|
|
58
77
|
|
59
78
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
60
79
|
|
61
|
-
|
80
|
+
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
81
|
+
#if NGINX_VERSION_NUM < 7000
|
62
82
|
of.test_dir = 0;
|
63
83
|
#else
|
64
|
-
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
65
84
|
of.directio = clcf->directio;
|
66
85
|
#endif
|
67
86
|
of.valid = clcf->open_file_cache_valid;
|
@@ -106,7 +125,7 @@ passenger_static_content_handler(ngx_http_request_t *r, ngx_str_t *filename)
|
|
106
125
|
return rc;
|
107
126
|
}
|
108
127
|
|
109
|
-
#if
|
128
|
+
#if NGINX_VERSION_NUM >= 7000
|
110
129
|
r->root_tested = !r->error_page;
|
111
130
|
#endif
|
112
131
|
|
@@ -131,7 +150,7 @@ passenger_static_content_handler(ngx_http_request_t *r, ngx_str_t *filename)
|
|
131
150
|
len += r->args.len + 1;
|
132
151
|
}
|
133
152
|
|
134
|
-
#if
|
153
|
+
#if NGINX_VERSION_NUM < 7000
|
135
154
|
location = ngx_palloc(r->pool, len);
|
136
155
|
#else
|
137
156
|
location = ngx_pnalloc(r->pool, len);
|
@@ -188,6 +207,7 @@ passenger_static_content_handler(ngx_http_request_t *r, ngx_str_t *filename)
|
|
188
207
|
r->headers_out.content_length_n = of.size;
|
189
208
|
r->headers_out.last_modified_time = of.mtime;
|
190
209
|
|
210
|
+
set_request_extension(r, filename);
|
191
211
|
if (ngx_http_set_content_type(r) != NGX_OK) {
|
192
212
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
193
213
|
}
|
@@ -226,7 +246,7 @@ passenger_static_content_handler(ngx_http_request_t *r, ngx_str_t *filename)
|
|
226
246
|
b->file->fd = of.fd;
|
227
247
|
b->file->name = *filename;
|
228
248
|
b->file->log = log;
|
229
|
-
#if
|
249
|
+
#if NGINX_VERSION_NUM >= 7000
|
230
250
|
b->file->directio = of.is_directio;
|
231
251
|
#endif
|
232
252
|
|
data/ext/nginx/config
CHANGED
@@ -26,6 +26,9 @@ CORE_LIBS="$CORE_LIBS \
|
|
26
26
|
${ngx_addon_dir}/libpassenger_common.a \
|
27
27
|
${ngx_addon_dir}/libboost_oxt.a \
|
28
28
|
-lstdc++ -lpthread"
|
29
|
+
if test x`uname` = xOpenBSD; then
|
30
|
+
CORE_LIBS="$CORE_LIBS -lm"
|
31
|
+
fi
|
29
32
|
|
30
33
|
nginx_version=`grep 'NGINX_VERSION ' src/core/nginx.h | awk '{ print $3 }' | sed 's/"//g'`
|
31
34
|
|
@@ -54,11 +54,18 @@ static ngx_str_t ngx_http_scgi_script_name = ngx_string("scgi_script_name");
|
|
54
54
|
static pid_t helper_server_pid = 0;
|
55
55
|
static int helper_server_admin_pipe;
|
56
56
|
static u_char helper_server_password_data[HELPER_SERVER_PASSWORD_SIZE];
|
57
|
+
/** perl_module destroys the original environment variables for some reason,
|
58
|
+
* so when we get a SIGHUP (for restarting Nginx) $TMPDIR might not have the
|
59
|
+
* same value as it had during Nginx startup. We need the original $TMPDIR
|
60
|
+
* value for calculating the Passenger temp dir location, so here we cache
|
61
|
+
* the original value instead of getenv()'ing it every time.
|
62
|
+
*/
|
63
|
+
const char *system_temp_dir = NULL;
|
57
64
|
const char passenger_temp_dir[NGX_MAX_PATH];
|
58
65
|
ngx_str_t passenger_schema_string;
|
59
66
|
ngx_str_t passenger_helper_server_password;
|
60
67
|
const char passenger_helper_server_socket[NGX_MAX_PATH];
|
61
|
-
|
68
|
+
CachedFileStat *passenger_stat_cache;
|
62
69
|
|
63
70
|
static void shutdown_helper_server(ngx_cycle_t *cycle);
|
64
71
|
|
@@ -122,10 +129,17 @@ start_helper_server(ngx_cycle_t *cycle)
|
|
122
129
|
long i;
|
123
130
|
ssize_t ret;
|
124
131
|
char buf;
|
125
|
-
|
132
|
+
ngx_str_t *log_filename;
|
133
|
+
FILE *f, *log_file;
|
134
|
+
|
135
|
+
shutdown_helper_server(cycle);
|
126
136
|
|
127
|
-
if (
|
128
|
-
|
137
|
+
if (main_conf->root_dir.len == 0) {
|
138
|
+
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
139
|
+
"Phusion Passenger is disabled because the "
|
140
|
+
"'passenger_root' option is not set. Please set "
|
141
|
+
"this option if you want to enable Phusion Passenger.");
|
142
|
+
return NGX_OK;
|
129
143
|
}
|
130
144
|
|
131
145
|
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
@@ -219,10 +233,35 @@ start_helper_server(ngx_cycle_t *cycle)
|
|
219
233
|
close(admin_pipe[1]);
|
220
234
|
close(feedback_pipe[0]);
|
221
235
|
|
222
|
-
/*
|
223
|
-
*
|
236
|
+
/* At this point, stdout and stderr may still point to the console.
|
237
|
+
* Make sure that they're both redirected to the log file.
|
224
238
|
*/
|
225
|
-
|
239
|
+
log_file = NULL;
|
240
|
+
#if NGINX_VERSION_NUM < 7000
|
241
|
+
log_filename = &cycle->new_log->file->name;
|
242
|
+
#else
|
243
|
+
log_filename = &cycle->new_log.file->name;
|
244
|
+
#endif
|
245
|
+
if (log_filename->len > 0) {
|
246
|
+
log_file = fopen((const char *) log_filename->data, "a");
|
247
|
+
if (log_file == NULL) {
|
248
|
+
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
249
|
+
"could not open the error log file for writing");
|
250
|
+
}
|
251
|
+
}
|
252
|
+
if (log_file == NULL) {
|
253
|
+
/* If the log file cannot be opened then we redirect stdout
|
254
|
+
* and stderr to /dev/null, because if the user disconnects
|
255
|
+
* from the console on which Nginx is started, then on Linux
|
256
|
+
* any writes to stdout or stderr will result in an EIO error.
|
257
|
+
*/
|
258
|
+
log_file = fopen("/dev/null", "w");
|
259
|
+
}
|
260
|
+
if (log_file != NULL) {
|
261
|
+
dup2(fileno(log_file), 1);
|
262
|
+
dup2(fileno(log_file), 2);
|
263
|
+
fclose(log_file);
|
264
|
+
}
|
226
265
|
|
227
266
|
/* Close all file descriptors except stdin, stdout, stderr and
|
228
267
|
* the reader part of the pipe we just created.
|
@@ -241,6 +280,8 @@ start_helper_server(ngx_cycle_t *cycle)
|
|
241
280
|
close(i);
|
242
281
|
}
|
243
282
|
|
283
|
+
setenv("SERVER_SOFTWARE", NGINX_VER, 1);
|
284
|
+
|
244
285
|
execlp((const char *) helper_server_filename,
|
245
286
|
"PassengerNginxHelperServer",
|
246
287
|
main_conf->root_dir.data,
|
@@ -256,7 +297,7 @@ start_helper_server(ngx_cycle_t *cycle)
|
|
256
297
|
worker_uid_string,
|
257
298
|
worker_gid_string,
|
258
299
|
passenger_temp_dir,
|
259
|
-
|
300
|
+
(char *) 0);
|
260
301
|
e = errno;
|
261
302
|
fprintf(stderr, "*** Could not start the Passenger helper server (%s): "
|
262
303
|
"exec() failed: %s (%d)\n",
|
@@ -357,6 +398,10 @@ save_master_process_pid(ngx_cycle_t *cycle) {
|
|
357
398
|
u_char *last;
|
358
399
|
FILE *f;
|
359
400
|
|
401
|
+
if (passenger_main_conf.root_dir.len == 0) {
|
402
|
+
return NGX_OK;
|
403
|
+
}
|
404
|
+
|
360
405
|
last = ngx_snprintf(filename, sizeof(filename) - 1,
|
361
406
|
"%s/control_process.pid", passenger_temp_dir);
|
362
407
|
*last = (u_char) '\0';
|
@@ -380,6 +425,10 @@ shutdown_helper_server(ngx_cycle_t *cycle)
|
|
380
425
|
int helper_server_exited, ret;
|
381
426
|
u_char command[NGX_MAX_PATH + 10];
|
382
427
|
|
428
|
+
if (helper_server_pid == 0) {
|
429
|
+
return;
|
430
|
+
}
|
431
|
+
|
383
432
|
/* We write one byte to the admin pipe, doesn't matter what the byte is.
|
384
433
|
* The helper server will detect this as an exit command.
|
385
434
|
*/
|
@@ -442,7 +491,6 @@ shutdown_helper_server(ngx_cycle_t *cycle)
|
|
442
491
|
passenger_temp_dir);
|
443
492
|
}
|
444
493
|
}
|
445
|
-
|
446
494
|
helper_server_pid = 0;
|
447
495
|
}
|
448
496
|
|
@@ -509,15 +557,15 @@ static ngx_int_t
|
|
509
557
|
pre_config_init(ngx_conf_t *cf)
|
510
558
|
{
|
511
559
|
ngx_int_t ret;
|
512
|
-
const char *system_temp_dir;
|
513
560
|
u_char command[NGX_MAX_PATH + 30];
|
561
|
+
u_char *last;
|
514
562
|
|
515
563
|
ngx_memzero(&passenger_main_conf, sizeof(passenger_main_conf_t));
|
516
564
|
|
517
565
|
passenger_schema_string.data = (u_char *) "passenger://";
|
518
566
|
passenger_schema_string.len = sizeof("passenger://") - 1;
|
519
567
|
|
520
|
-
passenger_stat_cache =
|
568
|
+
passenger_stat_cache = cached_file_stat_new(1024);
|
521
569
|
|
522
570
|
ret = add_variables(cf);
|
523
571
|
if (ret != NGX_OK) {
|
@@ -526,9 +574,13 @@ pre_config_init(ngx_conf_t *cf)
|
|
526
574
|
|
527
575
|
/* Setup Passenger temp folder. */
|
528
576
|
|
529
|
-
system_temp_dir
|
530
|
-
|
531
|
-
|
577
|
+
if (system_temp_dir == NULL) {
|
578
|
+
const char *tmp = getenv("TMPDIR");
|
579
|
+
if (tmp == NULL || *tmp == '\0') {
|
580
|
+
system_temp_dir = "/tmp";
|
581
|
+
} else {
|
582
|
+
system_temp_dir = strdup(tmp);
|
583
|
+
}
|
532
584
|
}
|
533
585
|
|
534
586
|
ngx_memzero(&passenger_temp_dir, sizeof(passenger_temp_dir));
|
@@ -554,13 +606,16 @@ pre_config_init(ngx_conf_t *cf)
|
|
554
606
|
|
555
607
|
/* Build helper server socket filename string. */
|
556
608
|
|
557
|
-
|
558
|
-
|
559
|
-
|
609
|
+
last = ngx_snprintf((u_char *) passenger_helper_server_socket, NGX_MAX_PATH,
|
610
|
+
"unix:%s/master/helper_server.sock",
|
611
|
+
passenger_temp_dir);
|
612
|
+
if (last == NULL) {
|
560
613
|
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
|
561
614
|
"could not create Passenger helper server "
|
562
615
|
"socket filename string");
|
563
616
|
return NGX_ERROR;
|
617
|
+
} else {
|
618
|
+
*last = (u_char) '\0';
|
564
619
|
}
|
565
620
|
|
566
621
|
return NGX_OK;
|