Permalink
Browse files

Change the Spawner protocol so that everything must be prefixed by '!…

…> '.

This way command messages cannot be confused with normal messages. This is
necessary because loaders may not be able to prevent application
code from outputting warnings to stdout, which would confuse the spawn protocol.
  • Loading branch information...
1 parent 9cfa160 commit 0d526fdae6e276139d1d8e68cb8813b95c61edaa @FooBarWidget FooBarWidget committed Mar 7, 2012
View
1 build/common_library.rb
@@ -38,6 +38,7 @@ def define_common_library_task(namespace, output_dir, extra_compiler_flags = nil
Logging.h),
'ApplicationPool2/Implementation.o' => %w(
ApplicationPool2/Implementation.cpp
+ ApplicationPool2/Spawner.h
ApplicationPool2/Common.h
ApplicationPool2/Pool.h
ApplicationPool2/SuperGroup.h
View
6 ext/common/ApplicationPool2/Options.h
@@ -445,17 +445,15 @@ class Options {
* Append any spawning-relevant information in this Options object
* to the given string vector, except for environmentVariables.
*/
- void toVector(vector<string> &vec) const {
+ void toVector(vector<string> &vec, const ResourceLocator &resourceLocator) const {
if (vec.capacity() < vec.size() + 40) {
vec.reserve(vec.size() + 40);
}
appendKeyValue (vec, "app_root", appRoot);
appendKeyValue (vec, "app_group_name", getAppGroupName());
appendKeyValue (vec, "app_type", appType);
- if (appType.empty()) {
- appendKeyValue (vec, "start_command", startCommand);
- }
+ appendKeyValue (vec, "start_command", getStartCommand(resourceLocator));
appendKeyValue (vec, "process_title", getProcessTitle());
appendKeyValue3(vec, "start_timeout", startTimeout);
appendKeyValue (vec, "environment", environment);
View
247 ext/common/ApplicationPool2/Spawner.h
@@ -277,8 +277,10 @@ class Spawner {
shared_array<gid_t> gidset;
};
- // Structure to be passed to negotiateSpawn().
- // Contains arguments as well as working state.
+ /**
+ * Structure containing arguments and working state for negotiating
+ * the spawning protocol.
+ */
struct NegotiationDetails {
// Arguments.
SafeLibev *libev;
@@ -306,6 +308,29 @@ class Spawner {
timeout = 0;
}
};
+
+ /**
+ * Structure containing arguments and working state for negotiating
+ * the preloader startup protocol.
+ */
+ struct StartupDetails {
+ // Arguments.
+ FileDescriptor adminSocket;
+ BufferedIO io;
+ BackgroundIOCapturerPtr stderrCapturer;
+ DebugDirPtr debugDir;
+ const Options *options;
+ bool forwardStderr;
+
+ // Working state.
+ unsigned long long timeout;
+
+ StartupDetails() {
+ options = NULL;
+ forwardStderr = false;
+ timeout = 0;
+ }
+ };
private:
@@ -324,7 +349,7 @@ class Spawner {
output.append(value.data(), value.size());
output.append(1, '\0');
}
-
+
void sendSpawnRequest(NegotiationDetails &details) {
try {
writeExact(details.adminSocket,
@@ -339,7 +364,7 @@ class Spawner {
vector<string> args;
vector<string>::const_iterator it, end;
- details.options->toVector(args);
+ details.options->toVector(args, resourceLocator);
for (it = args.begin(); it != args.end(); it++) {
const string &key = *it;
it++;
@@ -360,14 +385,14 @@ class Spawner {
}
}
}
-
+
ProcessPtr handleSpawnResponse(NegotiationDetails &details) {
SocketListPtr sockets = make_shared<SocketList>();
while (true) {
string line;
try {
- line = details.io.readLine(1024 * 4, &details.timeout);
+ line = readMessageLine(details);
} catch (const SystemException &e) {
throwAppSpawnException("An error occurred while starting the "
"web application. There was an I/O error while reading its "
@@ -565,6 +590,23 @@ class Spawner {
e.addAnnotations(details.debugDir->readAll());
}
}
+
+ template<typename Details>
+ static string readMessageLine(Details &details) {
+ while (true) {
+ string result = details.io.readLine(1024 * 4, &details.timeout);
+ if (result.empty()) {
+ return result;
+ } else if (startsWith(result, "!> ")) {
+ result.erase(0, sizeof("!> ") - 1);
+ return result;
+ } else if (details.forwardStderr) {
+ // TODO: also capture data into a buffer so that the process's
+ // stdout data can be displayed if the process fails to spawn.
+ write(STDOUT_FILENO, result.data(), result.size());
+ }
+ }
+ }
SpawnPreparationInfo prepareSpawn(const Options &options) const {
SpawnPreparationInfo info;
@@ -770,23 +812,29 @@ class Spawner {
if (info.switchUser) {
if (setgroups(info.ngroups, info.gidset.get()) == -1) {
int e = errno;
- fprintf(stderr, "Error\n\n");
- fprintf(stderr, "setgroups() failed: %s (errno=%d)\n",
+ printf("!> Error\n");
+ printf("!> \n");
+ printf("setgroups() failed: %s (errno=%d)\n",
strerror(e), e);
+ fflush(stdout);
_exit(1);
}
if (setgid(info.gid) == -1) {
int e = errno;
- fprintf(stderr, "Error\n\n");
- fprintf(stderr, "setgid() failed: %s (errno=%d)\n",
+ printf("!> Error\n");
+ printf("!> \n");
+ printf("setgid() failed: %s (errno=%d)\n",
strerror(e), e);
+ fflush(stdout);
_exit(1);
}
if (setuid(info.uid) == -1) {
int e = errno;
- fprintf(stderr, "Error\n\n");
- fprintf(stderr, "setuid() failed: %s (errno=%d)\n",
+ printf("!> Error\n");
+ printf("!> \n");
+ printf("setuid() failed: %s (errno=%d)\n",
strerror(e), e);
+ fflush(stdout);
_exit(1);
}
@@ -829,12 +877,13 @@ class Spawner {
memcpy(parent, it->c_str(), end - it->c_str());
parent[end - it->c_str()] = '\0';
- printf("Error\n\n");
+ printf("!> Error\n");
+ printf("!> \n");
printf("This web application process is being run as user '%s' and group '%s' "
"and must be able to access its application root directory '%s'. "
"However, the parent directory '%s' has wrong permissions, thereby "
"preventing this process from accessing its application root directory. "
- "Please fix the permissions of the directory '%s' first.",
+ "Please fix the permissions of the directory '%s' first.\n",
info.username.c_str(),
info.groupname.c_str(),
info.appRootPaths.back().c_str(),
@@ -844,7 +893,8 @@ class Spawner {
_exit(1);
} else if (ret == -1) {
int e = errno;
- printf("Error\n\n");
+ printf("!> Error\n");
+ printf("!> \n");
printf("Unable to stat() directory '%s': %s (errno=%d)\n",
it->c_str(), strerror(e), e);
fflush(stdout);
@@ -856,19 +906,21 @@ class Spawner {
if (ret == 0) {
setenv("PWD", info.appRootPathsInsideChroot.back().c_str(), 1);
} else if (ret == -1 && errno == EACCES) {
- printf("Error\n\n");
+ printf("!> Error\n");
+ printf("!> \n");
printf("This web application process is being run as user '%s' and group '%s' "
"and must be able to access its application root directory '%s'. "
"However this directory is not accessible because it has wrong permissions. "
- "Please fix these permissions first.",
+ "Please fix these permissions first.\n",
info.username.c_str(),
info.groupname.c_str(),
info.appRootPaths.back().c_str());
fflush(stdout);
_exit(1);
} else {
int e = errno;
- printf("Error\n\n");
+ printf("!> Error\n");
+ printf("!> \n");
printf("Unable to change working directory to '%s': %s (errno=%d)\n",
info.appRootPathsInsideChroot.back().c_str(), strerror(e), e);
fflush(stdout);
@@ -885,7 +937,7 @@ class Spawner {
string result;
try {
- result = details.io.readLine(1024, &details.timeout);
+ result = readMessageLine(details);
} catch (const SystemException &e) {
throwAppSpawnException("An error occurred while starting the "
"web application. There was an I/O error while reading its "
@@ -902,7 +954,7 @@ class Spawner {
if (result == "I have control 1.0\n") {
sendSpawnRequest(details);
try {
- result = details.io.readLine(1024, &details.timeout);
+ result = readMessageLine(details);
} catch (const SystemException &e) {
throwAppSpawnException("An error occurred while starting the "
"web application. There was an I/O error while reading its "
@@ -936,7 +988,7 @@ class Spawner {
map<string, string> attributes;
while (true) {
- string line = details.io.readLine(1024 * 4, &details.timeout);
+ string line = readMessageLine(details);
if (line.empty()) {
throwAppSpawnException("An error occurred while starting the "
"web application. It unexpected closed the connection while "
@@ -1110,6 +1162,14 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
void throwPreloaderSpawnException(const string &msg,
SpawnException::ErrorKind errorKind,
+ StartupDetails &details)
+ {
+ throwPreloaderSpawnException(msg, errorKind, details.stderrCapturer,
+ details.debugDir);
+ }
+
+ void throwPreloaderSpawnException(const string &msg,
+ SpawnException::ErrorKind errorKind,
BackgroundIOCapturerPtr &stderrCapturer,
const DebugDirPtr &debugDir)
{
@@ -1197,7 +1257,8 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
execvp(command[0].c_str(), (char * const *) args.get());
int e = errno;
- printf("Error\n\n");
+ printf("!> Error\n");
+ printf("!> \n");
printf("Cannot execute \"%s\": %s (errno=%d)\n", command[0].c_str(),
strerror(e), e);
fprintf(stderr, "Cannot execute \"%s\": %s (errno=%d)\n",
@@ -1215,13 +1276,19 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
adminSocket.first.close();
errorPipe.second.close();
- BackgroundIOCapturerPtr stderrCapturer =
+ StartupDetails details;
+ details.adminSocket = adminSocket.second;
+ details.io = BufferedIO(adminSocket.second);
+ details.stderrCapturer =
make_shared<BackgroundIOCapturer>(
errorPipe.first,
forwardStderr ? STDERR_FILENO : -1);
+ details.debugDir = debugDir;
+ details.options = &options;
+ details.timeout = options.startTimeout * 1000;
+ details.forwardStderr = forwardStderr;
- this->socketAddress = negotiatePreloaderStartup(adminSocket.second,
- stderrCapturer, debugDir, options);
+ this->socketAddress = negotiatePreloaderStartup(details);
this->pid = pid;
this->adminSocket = adminSocket.second;
this->errorPipe = errorPipe.first;
@@ -1260,21 +1327,17 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
socketAddress.clear();
}
- void sendStartupRequest(int fd,
- BackgroundIOCapturerPtr &stderrCapturer,
- const DebugDirPtr &debugDir,
- unsigned long long &timeout)
- {
+ void sendStartupRequest(StartupDetails &details) {
try {
- writeExact(fd,
+ writeExact(details.adminSocket,
"You have control 1.0\n"
"passenger_root: " + resourceLocator.getRoot() + "\n"
"ruby_libdir: " + resourceLocator.getRubyLibDir() + "\n"
"passenger_version: " PASSENGER_VERSION "\n"
"generation_dir: " + generation->getPath() + "\n"
- "app_root: " + options.appRoot + "\n"
+ "app_root: " + details.options->appRoot + "\n"
"\n",
- &timeout);
+ &details.timeout);
} catch (const SystemException &e) {
if (e.code() == EPIPE) {
/* Ignore this. Process might have written an
@@ -1287,60 +1350,49 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
"sending the startup request message to it: " +
e.sys(),
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
}
} catch (const TimeoutException &) {
throwPreloaderSpawnException("An error occurred while starting up the "
"preloader: it did not read the startup request message in time.",
SpawnException::PRELOADER_STARTUP_TIMEOUT,
- stderrCapturer,
- debugDir);
+ details);
}
}
- string handleStartupResponse(BufferedIO &io,
- BackgroundIOCapturerPtr &stderrCapturer,
- const DebugDirPtr &debugDir,
- const Options &options,
- unsigned long long &timeout)
- {
+ string handleStartupResponse(StartupDetails &details) {
string socketAddress;
while (true) {
string line;
try {
- line = io.readLine(1024 * 4, &timeout);
+ line = readMessageLine(details);
} catch (const SystemException &e) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. There was an I/O error while reading its "
"startup response: " + e.sys(),
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} catch (const TimeoutException &) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader: it did not write a startup response in time.",
SpawnException::PRELOADER_STARTUP_TIMEOUT,
- stderrCapturer,
- debugDir);
+ details);
}
if (line.empty()) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. It unexpected closed the connection while "
"sending its startup response.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} else if (line[line.size() - 1] != '\n') {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. It sent a line without a newline character "
"in its startup response.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} else if (line == "\n") {
break;
}
@@ -1351,8 +1403,7 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
"the preloader. It sent a startup response line without "
"separator.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
}
string key = line.substr(0, pos);
@@ -1364,8 +1415,7 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
"the preloader. It sent an unknown startup response line "
"called '" + key + "'.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
}
}
@@ -1374,54 +1424,45 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
"the preloader. It did not report a socket address in its "
"startup response.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
}
return socketAddress;
}
- void handleErrorResponse(BufferedIO &io,
- BackgroundIOCapturerPtr &stderrCapturer,
- const DebugDirPtr &debugDir,
- unsigned long long &timeout)
- {
+ void handleErrorResponse(StartupDetails &details) {
map<string, string> attributes;
while (true) {
string line;
try {
- line = io.readLine(1024 * 4, &timeout);
+ line = readMessageLine(details);
} catch (const SystemException &e) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. There was an I/O error while reading its "
"startup response: " + e.sys(),
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} catch (const TimeoutException &) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader: it did not write a startup response in time.",
SpawnException::PRELOADER_STARTUP_TIMEOUT,
- stderrCapturer,
- debugDir);
+ details);
}
if (line.empty()) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. It unexpected closed the connection while "
"sending its startup response.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} else if (line[line.size() - 1] != '\n') {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. It sent a line without a newline character "
"in its startup response.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} else if (line == "\n") {
break;
}
@@ -1432,8 +1473,7 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
"the preloader. It sent a startup response line without "
"separator.",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
}
string key = line.substr(0, pos);
@@ -1442,99 +1482,83 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
}
try {
- string message = io.readAll(&timeout);
+ string message = details.io.readAll(&details.timeout);
SpawnException e("An error occured while starting up the preloader.",
message,
attributes["html"] == "true",
SpawnException::PRELOADER_STARTUP_EXPLAINABLE_ERROR);
e.setPreloaderCommand(getPreloaderCommandString());
- annotatePreloaderException(e, debugDir);
+ annotatePreloaderException(e, details.debugDir);
throw e;
} catch (const SystemException &e) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. It tried to report an error message, but "
"an I/O error occurred while reading this error message: " +
e.sys(),
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} catch (const TimeoutException &) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. It tried to report an error message, but "
"it took too much time doing that.",
SpawnException::PRELOADER_STARTUP_TIMEOUT,
- stderrCapturer,
- debugDir);
+ details);
}
}
- void handleInvalidResponseType(const string &line, BackgroundIOCapturerPtr &stderrCapturer,
- const DebugDirPtr &debugDir)
- {
+ void handleInvalidResponseType(StartupDetails &details, const string &line) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. It sent an unknown response type \"" +
cEscapeString(line) + "\".",
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
}
- string negotiatePreloaderStartup(FileDescriptor &fd,
- BackgroundIOCapturerPtr &stderrCapturer,
- const DebugDirPtr &debugDir,
- const Options &options)
- {
- BufferedIO io(fd);
- unsigned long long timeout = options.startTimeout * 1000;
-
+ string negotiatePreloaderStartup(StartupDetails &details) {
string result;
try {
- result = io.readLine(1024, &timeout);
+ result = readMessageLine(details);
} catch (const SystemException &e) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. There was an I/O error while reading its "
"handshake message: " + e.sys(),
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} catch (const TimeoutException &) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader: it did not write a handshake message in time.",
SpawnException::PRELOADER_STARTUP_TIMEOUT,
- stderrCapturer,
- debugDir);
+ details);
}
if (result == "I have control 1.0\n") {
- sendStartupRequest(fd, stderrCapturer, debugDir, timeout);
+ sendStartupRequest(details);
try {
- result = io.readLine(1024, &timeout);
+ result = readMessageLine(details);
} catch (const SystemException &e) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader. There was an I/O error while reading its "
"startup response: " + e.sys(),
SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
- stderrCapturer,
- debugDir);
+ details);
} catch (const TimeoutException &) {
throwPreloaderSpawnException("An error occurred while starting up "
"the preloader: it did not write a startup response in time.",
SpawnException::PRELOADER_STARTUP_TIMEOUT,
- stderrCapturer,
- debugDir);
+ details);
}
if (result == "Ready\n") {
- return handleStartupResponse(io, stderrCapturer, debugDir, options, timeout);
+ return handleStartupResponse(details);
} else if (result == "Error\n") {
- handleErrorResponse(io, stderrCapturer, debugDir, timeout);
+ handleErrorResponse(details);
} else {
- handleInvalidResponseType(result, stderrCapturer, debugDir);
+ handleInvalidResponseType(details, result);
}
} else {
if (result == "Error\n") {
- handleErrorResponse(io, stderrCapturer, debugDir, timeout);
+ handleErrorResponse(details);
} else {
- handleInvalidResponseType(result, stderrCapturer, debugDir);
+ handleInvalidResponseType(details, result);
}
}
@@ -1564,7 +1588,7 @@ class SmartSpawner: public Spawner, public enable_shared_from_this<SmartSpawner>
vector<string>::const_iterator it;
writeExact(fd, "spawn\n", &timeout);
- options.toVector(args);
+ options.toVector(args, resourceLocator);
for (it = args.begin(); it != args.end(); it++) {
const string &key = *it;
it++;
@@ -1903,7 +1927,8 @@ class DirectSpawner: public Spawner {
execvp(args[0], (char * const *) args.get());
int e = errno;
- printf("Error\n\n");
+ printf("!> Error\n");
+ printf("!> \n");
printf("Cannot execute \"%s\": %s (errno=%d)\n", command[0].c_str(),
strerror(e), e);
fprintf(stderr, "Cannot execute \"%s\": %s (errno=%d)\n",
View
14 helper-scripts/rack-loader.rb
@@ -29,7 +29,7 @@ def self.exit_code_for_exception(e)
def self.handshake_and_read_startup_request
STDOUT.sync = true
STDERR.sync = true
- puts "I have control 1.0"
+ puts "!> I have control 1.0"
abort "Invalid initialization header" if STDIN.readline != "You have control 1.0\n"
@@options = {}
@@ -54,8 +54,8 @@ def self.init_passenger
NativeSupport.disable_stdio_buffering
rescue Exception => e
LoaderSharedHelpers.about_to_abort(e) if defined?(LoaderSharedHelpers)
- puts "Error"
- puts
+ puts "!> Error"
+ puts "!> "
puts format_exception(e)
exit exit_code_for_exception(e)
end
@@ -77,8 +77,8 @@ def self.load_app
LoaderSharedHelpers.after_loading_app_code(options)
rescue Exception => e
LoaderSharedHelpers.about_to_abort(e)
- puts "Error"
- puts
+ puts "!> Error"
+ puts "!> "
puts format_exception(e)
exit exit_code_for_exception(e)
end
@@ -92,9 +92,9 @@ def self.load_app
load_app
handler = Rack::RequestHandler.new(STDIN, app, options)
LoaderSharedHelpers.before_handling_requests(false, options)
- puts "Ready"
+ puts "!> Ready"
LoaderSharedHelpers.advertise_sockets(STDOUT, handler)
- puts
+ puts "!> "
handler.main_loop
LoaderSharedHelpers.after_handling_requests
View
16 helper-scripts/rack-preloader.rb
@@ -31,7 +31,7 @@ def self.exit_code_for_exception(e)
def self.handshake_and_read_startup_request
STDOUT.sync = true
STDERR.sync = true
- puts "I have control 1.0"
+ puts "!> I have control 1.0"
abort "Invalid initialization header" if STDIN.readline != "You have control 1.0\n"
@@options = {}
@@ -57,8 +57,8 @@ def self.init_passenger
NativeSupport.disable_stdio_buffering
rescue Exception => e
LoaderSharedHelpers.about_to_abort(e) if defined?(LoaderSharedHelpers)
- puts "Error"
- puts
+ puts "!> Error"
+ puts "!> "
puts format_exception(e)
exit exit_code_for_exception(e)
end
@@ -80,14 +80,14 @@ def self.preload_app
LoaderSharedHelpers.after_loading_app_code(options)
rescue Exception => e
LoaderSharedHelpers.about_to_abort(e)
- puts "Error"
- puts
+ puts "!> Error"
+ puts "!> "
puts format_exception(e)
exit exit_code_for_exception(e)
end
def self.negotiate_spawn_command
- puts "I have control 1.0"
+ puts "!> I have control 1.0"
abort "Invalid initialization header" if STDIN.readline != "You have control 1.0\n"
while (line = STDIN.readline) != "\n"
@@ -98,9 +98,9 @@ def self.negotiate_spawn_command
handler = Rack::RequestHandler.new(STDIN, app, options)
LoaderSharedHelpers.before_handling_requests(true, options)
- puts "Ready"
+ puts "!> Ready"
LoaderSharedHelpers.advertise_sockets(STDOUT, handler)
- puts
+ puts "!> "
return handler
end
View
8 helper-scripts/wsgi-loader.py
@@ -41,7 +41,7 @@ def readline():
def handshake_and_read_startup_request():
global options
- print("I have control 1.0")
+ print("!> I have control 1.0")
if readline() != "You have control 1.0\n":
abort("Invalid initialization header")
@@ -70,8 +70,8 @@ def create_server_socket():
return (filename, s)
def advertise_sockets(socket_filename):
- print("socket: main;unix:%s;session;1" % socket_filename)
- print("")
+ print("!> socket: main;unix:%s;session;1" % socket_filename)
+ print("!> ")
class RequestHandler:
@@ -226,6 +226,6 @@ def process_ping(self, env, input_stream, output_stream):
app_module = load_app()
socket_filename, server_socket = create_server_socket()
handler = RequestHandler(server_socket, sys.stdin, app_module.application)
- print("Ready")
+ print("!> Ready")
advertise_sockets(socket_filename)
handler.main_loop()
View
4 lib/phusion_passenger/loader_shared_helpers.rb
@@ -215,8 +215,8 @@ def create_socket_address(protocol, address)
def advertise_sockets(output, request_handler)
sockets = request_handler.server_sockets
- output.puts "socket: main;#{create_socket_address(sockets[:main][1], sockets[:main][0])};session;1"
- output.puts "socket: http;#{create_socket_address(sockets[:http][1], sockets[:http][0])};http;1"
+ output.puts "!> socket: main;#{create_socket_address(sockets[:main][1], sockets[:main][0])};session;1"
+ output.puts "!> socket: http;#{create_socket_address(sockets[:http][1], sockets[:http][0])};http;1"
end
# To be called before the request handler main loop is entered, but after the app
View
6 lib/phusion_passenger/preloader_shared_helpers.rb
@@ -58,9 +58,9 @@ def run_main_loop(options)
# ready because the HelperAgent will read and memorize this information.
LoaderSharedHelpers.dump_all_information
- puts "Ready"
- puts "socket: unix:#{socket_filename}"
- puts
+ puts "!> Ready"
+ puts "!> socket: unix:#{socket_filename}"
+ puts "!> "
while true
ios = select([server, STDIN])[0]
View
16 test/cxx/ApplicationPool2/SpawnerTestCases.cpp
@@ -44,7 +44,7 @@
// in exceptions.
Options options = createOptions();
options.appRoot = "stub";
- options.startCommand = "echo\1" "hello world";
+ options.startCommand = "echo\1" "!> hello world";
options.startupFile = ".";
SpawnerPtr spawner = createSpawner(options);
try {
@@ -134,7 +134,7 @@
// Any raised SpawnExceptions take note of the process's environment variables.
Options options = createOptions();
options.appRoot = "stub";
- options.startCommand = "echo\1" "hello world";
+ options.startCommand = "echo\1" "!> hello world";
options.startupFile = ".";
options.environmentVariables.push_back(make_pair("PASSENGER_FOO", "foo"));
SpawnerPtr spawner = createSpawner(options);
@@ -146,7 +146,7 @@
}
}
- TEST_METHOD(9) {SHOW_EXCEPTION_BACKTRACE(
+ TEST_METHOD(9) {
// It raises an exception if the user does not have a access to one
// of the app root's parent directories, or the app root itself.
system("mkdir -p tmp.check/a/b/c");
@@ -171,7 +171,7 @@
spawner->spawn(options);
fail("SpawnException expected");
} catch (const SpawnException &e) {
- ensure(containsSubstring(e.getErrorPage(),
+ ensure("(1)", containsSubstring(e.getErrorPage(),
"the parent directory '" + cwd + "/tmp.check/a' has wrong permissions"));
}
@@ -180,7 +180,7 @@
spawner->spawn(options);
fail("SpawnException expected");
} catch (const SpawnException &e) {
- ensure(containsSubstring(e.getErrorPage(),
+ ensure("(2)", containsSubstring(e.getErrorPage(),
"the parent directory '" + cwd + "/tmp.check/a/b/c' has wrong permissions"));
}
@@ -189,14 +189,14 @@
spawner->spawn(options);
fail("SpawnException expected");
} catch (const SpawnException &e) {
- ensure(containsSubstring(e.getErrorPage(),
+ ensure("(3)", containsSubstring(e.getErrorPage(),
"However this directory is not accessible because it has wrong permissions."));
}
system("chmod 700 tmp.check/a/b/c/d");
- //spawner->spawn(options); // Should not throw.
+ spawner->spawn(options); // Should not throw.
}
- );}
+ }
// User switching works.
// It raises an exception if getStartupCommand() is empty.
View
8 test/stub/rack/start.rb
@@ -3,7 +3,7 @@
STDOUT.sync = true
STDERR.sync = true
-puts "I have control 1.0"
+puts "!> I have control 1.0"
abort "Invalid initialization header" if STDIN.readline != "You have control 1.0\n"
options = {}
@@ -13,9 +13,9 @@
end
server = TCPServer.new('127.0.0.1', 0)
-puts "Ready"
-puts "socket: main;tcp://127.0.0.1:#{server.addr[1]};session;1"
-puts
+puts "!> Ready"
+puts "!> socket: main;tcp://127.0.0.1:#{server.addr[1]};session;1"
+puts "!> "
while true
ios = select([server, STDIN])[0]
View
5 test/stub/start_error.pl
@@ -4,7 +4,7 @@
STDOUT->autoflush(1);
STDERR->autoflush(1);
-print("I have control 1.0\n");
+print("!> I have control 1.0\n");
die("Invalid initialization header") if (<STDIN> ne "You have control 1.0\n");
my %options = {};
@@ -14,7 +14,8 @@
$options{$name} = $value;
}
-print("Error\n\n");
+print("!> Error\n");
+print("!> \n");
if ($ARGV[0] eq 'freeze') {
sleep(1000);
} else {
View
8 test/support/placebo-preloader.rb
@@ -10,7 +10,7 @@
STDOUT.sync = true
STDERR.sync = true
-puts "I have control 1.0"
+puts "!> I have control 1.0"
abort "Invalid initialization header" if STDIN.readline != "You have control 1.0\n"
options = {}
@@ -21,9 +21,9 @@
socket_filename = "/tmp/placebo-preloader.sock.#{Process.pid}"
server = UNIXServer.new(socket_filename)
-puts "Ready"
-puts "socket: unix:#{socket_filename}"
-puts
+puts "!> Ready"
+puts "!> socket: unix:#{socket_filename}"
+puts "!> "
def process_client_command(server, client, command)
if command == "spawn\n"

0 comments on commit 0d526fd

Please sign in to comment.