GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
Turn RailsEnv into a per-virtual host option.
Hongli Lai (Phusion) (author)
Wed May 07 10:29:13 -0700 2008
commit  fb13dec0d4885d77f201c8c4ba16ea709fc6d6dc
tree    778c9eab1269e9cf5f2f39f2179baf2ce2643076
parent  726d5ef8ace10ef0a7179851b67ba43217c5dcee
...
105
106
107
 
108
109
110
...
114
115
116
117
 
 
118
119
120
...
105
106
107
108
109
110
111
...
115
116
117
 
118
119
120
121
122
0
@@ -105,6 +105,7 @@ public:
0
    * directory, but does not have to be an absolute path.
0
    * @param lowerPrivilege Whether to lower the application's privileges.
0
    * @param lowestUser The user to fallback to if lowering privilege fails.
0
+ * @param environment The RAILS_ENV environment that should be used. May not be empty.
0
    * @return A session object.
0
    * @throw SpawnException An attempt was made to spawn a new application instance, but that attempt failed.
0
    * @throw IOException Something else went wrong.
0
@@ -114,7 +115,8 @@ public:
0
    * <tt>get("/home/../home/foo")</tt>, then ApplicationPool will think
0
    * they're 2 different applications, and thus will spawn 2 application instances.
0
    */
0
- virtual Application::SessionPtr get(const string &appRoot, bool lowerPrivilege = true, const string &lowestUser = "nobody") = 0;
0
+ virtual Application::SessionPtr get(const string &appRoot, bool lowerPrivilege = true,
0
+ const string &lowestUser = "nobody", const string &environment = "production") = 0;
0
   
0
   /**
0
    * Clear all application instances that are currently in the pool.
...
256
257
258
259
260
 
 
 
 
 
 
261
262
263
...
265
266
267
268
 
 
 
269
270
271
...
301
302
303
304
305
306
307
...
395
396
397
398
399
400
401
...
428
429
430
431
432
433
434
435
436
...
444
445
446
447
448
449
450
451
452
453
454
455
456
...
256
257
258
 
 
259
260
261
262
263
264
265
266
267
...
269
270
271
 
272
273
274
275
276
277
...
307
308
309
 
310
311
312
...
400
401
402
 
403
404
405
...
432
433
434
 
 
 
435
436
437
...
445
446
447
 
448
449
450
451
452
 
453
454
455
0
@@ -256,8 +256,12 @@ private:
0
       return atoi(args[0].c_str());
0
     }
0
     
0
- virtual Application::SessionPtr get(const string &appRoot, bool lowerPrivilege = true,
0
- const string &lowestUser = "nobody") {
0
+ virtual Application::SessionPtr get(
0
+ const string &appRoot,
0
+ bool lowerPrivilege = true,
0
+ const string &lowestUser = "nobody",
0
+ const string &environment = "production"
0
+ ) {
0
       MessageChannel channel(data->server);
0
       vector<string> args;
0
       int reader, writer;
0
@@ -265,7 +269,9 @@ private:
0
       try {
0
         channel.write("get", appRoot.c_str(),
0
           (lowerPrivilege) ? "true" : "false",
0
- lowestUser.c_str(), NULL);
0
+ lowestUser.c_str(),
0
+ environment.c_str(),
0
+ NULL);
0
       } catch (const SystemException &) {
0
         throw IOException("The ApplicationPool server exited unexpectedly.");
0
       }
0
@@ -301,7 +307,6 @@ private:
0
   string m_serverExecutable;
0
   string m_spawnServerCommand;
0
   string m_logFile;
0
- string m_environment;
0
   string m_rubyCommand;
0
   string m_user;
0
   
0
@@ -395,7 +400,6 @@ private:
0
         m_serverExecutable.c_str(),
0
         m_spawnServerCommand.c_str(),
0
         m_logFile.c_str(),
0
- m_environment.c_str(),
0
         m_rubyCommand.c_str(),
0
         m_user.c_str(),
0
         NULL);
0
@@ -428,9 +432,6 @@ public:
0
    * specified, no log file will be used, and the spawn server
0
    * will use the same standard output/error channels as the
0
    * current process.
0
- * @param environment The RAILS_ENV environment that all RoR applications
0
- * should use. If an empty string is specified, the current value
0
- * of the RAILS_ENV environment variable will be used.
0
    * @param rubyCommand The Ruby interpreter's command.
0
    * @param user The user that the spawn manager should run as. This
0
    * parameter only has effect if the current process is
0
@@ -444,13 +445,11 @@ public:
0
   ApplicationPoolServer(const string &serverExecutable,
0
    const string &spawnServerCommand,
0
    const string &logFile = "",
0
- const string &environment = "production",
0
    const string &rubyCommand = "ruby",
0
    const string &user = "")
0
   : m_serverExecutable(serverExecutable),
0
    m_spawnServerCommand(spawnServerCommand),
0
    m_logFile(logFile),
0
- m_environment(environment),
0
    m_rubyCommand(rubyCommand),
0
    m_user(user) {
0
     serverSocket = -1;
...
76
77
78
79
80
81
82
 
83
84
85
...
148
149
150
151
 
152
153
154
...
237
238
239
240
 
241
242
243
...
374
375
376
377
 
378
379
380
...
76
77
78
 
79
80
 
81
82
83
84
...
147
148
149
 
150
151
152
153
...
236
237
238
 
239
240
241
242
...
373
374
375
 
376
377
378
379
0
@@ -76,10 +76,9 @@ public:
0
   Server(int serverSocket,
0
    const string &spawnServerCommand,
0
    const string &logFile,
0
- const string &environment,
0
    const string &rubyCommand,
0
    const string &user)
0
- : pool(spawnServerCommand, logFile, environment, rubyCommand, user) {
0
+ : pool(spawnServerCommand, logFile, rubyCommand, user) {
0
     this->serverSocket = serverSocket;
0
   }
0
   
0
@@ -148,7 +147,7 @@ private:
0
     bool failed = false;
0
     
0
     try {
0
- session = server.pool.get(args[1], args[2] == "true", args[3]);
0
+ session = server.pool.get(args[1], args[2] == "true", args[3], args[4]);
0
       sessions[lastSessionID] = session;
0
       lastSessionID++;
0
     } catch (const SpawnException &e) {
0
@@ -237,7 +236,7 @@ private:
0
         
0
         P_TRACE(3, "Client " << this << ": received message: " <<
0
           toString(args));
0
- if (args[0] == "get" && args.size() == 4) {
0
+ if (args[0] == "get" && args.size() == 5) {
0
           processGet(args);
0
         } else if (args[0] == "close" && args.size() == 2) {
0
           processClose(args);
0
@@ -374,7 +373,7 @@ Server::start() {
0
 int
0
 main(int argc, char *argv[]) {
0
   try {
0
- Server server(SERVER_SOCKET_FD, argv[1], argv[2], argv[3], argv[4], argv[5]);
0
+ Server server(SERVER_SOCKET_FD, argv[1], argv[2], argv[3], argv[4]);
0
     return server.start();
0
   } catch (const exception &e) {
0
     fprintf(stderr, "*** An unexpected error occured in the Passenger "
...
56
57
58
 
59
60
61
...
72
73
74
 
75
76
77
...
79
80
81
82
83
84
85
...
98
99
100
101
102
103
104
...
118
119
120
121
122
123
124
...
173
174
175
176
177
 
178
179
180
...
56
57
58
59
60
61
62
...
73
74
75
76
77
78
79
...
81
82
83
 
84
85
86
...
99
100
101
 
102
103
104
...
118
119
120
 
121
122
123
...
172
173
174
 
 
175
176
177
178
0
@@ -56,6 +56,7 @@ passenger_config_create_dir(apr_pool_t *p, char *dirspec) {
0
   DirConfig *config = create_dir_config_struct(p);
0
   config->autoDetect = DirConfig::UNSET;
0
   config->allowModRewrite = DirConfig::UNSET;
0
+ config->env = NULL;
0
   return config;
0
 }
0
 
0
@@ -72,6 +73,7 @@ passenger_config_merge_dir(apr_pool_t *p, void *basev, void *addv) {
0
   
0
   config->autoDetect = (add->autoDetect == DirConfig::UNSET) ? base->autoDetect : add->autoDetect;
0
   config->allowModRewrite = (add->allowModRewrite == DirConfig::UNSET) ? base->allowModRewrite : add->allowModRewrite;
0
+ config->env = (add->env == NULL) ? base->env : add->env;
0
   return config;
0
 }
0
 
0
@@ -79,7 +81,6 @@ void *
0
 passenger_config_create_server(apr_pool_t *p, server_rec *s) {
0
   ServerConfig *config = create_server_config_struct(p);
0
   config->ruby = NULL;
0
- config->env = NULL;
0
   config->root = NULL;
0
   config->maxPoolSize = DEFAULT_MAX_POOL_SIZE;
0
   config->maxPoolSizeSpecified = false;
0
@@ -98,7 +99,6 @@ passenger_config_merge_server(apr_pool_t *p, void *basev, void *addv) {
0
   ServerConfig *add = (ServerConfig *) addv;
0
   
0
   config->ruby = (add->ruby == NULL) ? base->ruby : add->ruby;
0
- config->env = (add->env == NULL) ? base->env : add->env;
0
   config->root = (add->root == NULL) ? base->root : add->root;
0
   config->maxPoolSize = (add->maxPoolSizeSpecified) ? base->maxPoolSize : add->maxPoolSize;
0
   config->maxPoolSizeSpecified = base->maxPoolSizeSpecified || add->maxPoolSizeSpecified;
0
@@ -118,7 +118,6 @@ passenger_config_merge_all_servers(apr_pool_t *pool, server_rec *main_server) {
0
   for (s = main_server; s != NULL; s = s->next) {
0
     ServerConfig *config = (ServerConfig *) ap_get_module_config(s->module_config, &passenger_module);
0
     final->ruby = (final->ruby != NULL) ? final->ruby : config->ruby;
0
- final->env = (final->env != NULL) ? final->env : config->env;
0
     final->root = (final->root != NULL) ? final->root : config->root;
0
     final->maxPoolSize = (final->maxPoolSizeSpecified) ? final->maxPoolSize : config->maxPoolSize;
0
     final->maxPoolSizeSpecified = final->maxPoolSizeSpecified || config->maxPoolSizeSpecified;
0
@@ -173,8 +172,7 @@ cmd_rails_ruby(cmd_parms *cmd, void *pcfg, const char *arg) {
0
 
0
 static const char *
0
 cmd_rails_env(cmd_parms *cmd, void *pcfg, const char *arg) {
0
- ServerConfig *config = (ServerConfig *) ap_get_module_config(
0
- cmd->server->module_config, &passenger_module);
0
+ DirConfig *config = (DirConfig *) pcfg;
0
   config->env = arg;
0
   return NULL;
0
 }
...
48
49
50
 
 
 
 
51
52
53
54
 
55
56
57
58
59
60
61
62
63
64
65
66
...
48
49
50
51
52
53
54
55
56
57
 
58
59
60
61
62
63
 
 
 
 
64
65
66
0
@@ -48,19 +48,19 @@
0
       std::set<std::string> base_uris;
0
       Threeway autoDetect;
0
       Threeway allowModRewrite;
0
+
0
+ /** The environment (i.e. value for RAILS_ENV) under which the
0
+ * Rails application should operate. */
0
+ const char *env;
0
     };
0
     
0
     /**
0
- * Server-wide configuration information.
0
+ * Server-wide (global, not per-virtual host) configuration information.
0
      */
0
     struct ServerConfig {
0
       /** The filename of the Ruby interpreter to use. */
0
       const char *ruby;
0
       
0
- /** The environment (i.e. value for RAILS_ENV) under which the
0
- * Rails application should operate. */
0
- const char *env;
0
-
0
       /** The Passenger root folder. */
0
       const char *root;
0
       
...
315
316
317
318
 
319
320
321
322
323
324
325
...
355
356
357
358
 
359
360
361
...
413
414
415
 
416
417
418
...
420
421
422
 
 
 
 
 
423
424
 
425
426
427
...
315
316
317
 
318
319
320
321
 
322
323
324
...
354
355
356
 
357
358
359
360
...
412
413
414
415
416
417
418
...
420
421
422
423
424
425
426
427
428
 
429
430
431
432
0
@@ -315,11 +315,10 @@ public:
0
     passenger_config_merge_all_servers(pconf, s);
0
     
0
     ServerConfig *config = getServerConfig(s);
0
- const char *ruby, *environment, *user;
0
+ const char *ruby, *user;
0
     string applicationPoolServerExe, spawnServer;
0
     
0
     ruby = (config->ruby != NULL) ? config->ruby : DEFAULT_RUBY_COMMAND;
0
- environment = (config->env != NULL) ? config->env : DEFAULT_RAILS_ENV;
0
     if (config->userSwitching) {
0
       user = "";
0
     } else if (config->defaultUser != NULL) {
0
@@ -355,7 +354,7 @@ public:
0
     applicationPoolServer = ptr(
0
       new ApplicationPoolServer(
0
         applicationPoolServerExe, spawnServer, "",
0
- environment, ruby, user)
0
+ ruby, user)
0
     );
0
   }
0
   
0
@@ -413,6 +412,7 @@ public:
0
       try {
0
         const char *defaultUser;
0
         ServerConfig *sconfig;
0
+ const char *environment;
0
         
0
         sconfig = getServerConfig(r->server);
0
         if (sconfig->defaultUser != NULL) {
0
@@ -420,8 +420,13 @@ public:
0
         } else {
0
           defaultUser = "nobody";
0
         }
0
+ if (config->env == NULL) {
0
+ environment = DEFAULT_RAILS_ENV;
0
+ } else {
0
+ environment = config->env;
0
+ }
0
         session = applicationPool->get(canonicalizePath(railsDir + "/.."),
0
- true, defaultUser);
0
+ true, defaultUser, environment);
0
       } catch (const SpawnException &e) {
0
         if (e.hasErrorPage()) {
0
           ap_set_content_type(r, "text/html; charset=utf-8");
...
83
84
85
86
87
88
89
...
155
156
157
158
159
160
161
162
163
...
240
241
242
 
243
244
245
246
 
 
 
 
 
 
247
248
249
...
252
253
254
 
255
256
257
...
316
317
318
319
 
 
320
321
322
...
331
332
333
334
 
335
336
337
...
396
397
398
399
400
401
402
403
404
...
410
411
412
413
414
415
416
417
418
419
420
421
...
470
471
472
 
473
474
475
476
477
478
 
 
 
 
 
 
479
480
481
 
482
483
484
485
486
 
 
487
488
489
...
83
84
85
 
86
87
88
...
154
155
156
 
 
 
157
158
159
...
236
237
238
239
240
241
242
 
243
244
245
246
247
248
249
250
251
...
254
255
256
257
258
259
260
...
319
320
321
 
322
323
324
325
326
...
335
336
337
 
338
339
340
341
...
400
401
402
 
 
 
403
404
405
...
411
412
413
 
414
415
416
417
 
418
419
420
...
469
470
471
472
473
474
475
476
477
 
478
479
480
481
482
483
484
485
 
486
487
488
489
490
 
491
492
493
494
495
0
@@ -83,7 +83,6 @@ private:
0
 
0
   string spawnServerCommand;
0
   string logFile;
0
- string environment;
0
   string rubyCommand;
0
   string user;
0
   
0
@@ -155,9 +154,6 @@ private:
0
         fclose(logFileHandle);
0
       }
0
       dup2(STDERR_FILENO, STDOUT_FILENO);
0
- if (!environment.empty()) {
0
- setenv("RAILS_ENV", environment.c_str(), true);
0
- }
0
       dup2(fds[1], SPAWN_SERVER_INPUT_FD);
0
       
0
       // Close all unnecessary file descriptors
0
@@ -240,10 +236,16 @@ private:
0
    * @param appRoot The application root of the application to spawn.
0
    * @param lowerPrivilege Whether to lower the application's privileges.
0
    * @param lowestUser The user to fallback to if lowering privilege fails.
0
+ * @param environment The RAILS_ENV environment that should be used.
0
    * @return An Application smart pointer, representing the spawned application.
0
    * @throws SpawnException Something went wrong.
0
    */
0
- ApplicationPtr sendSpawnCommand(const string &appRoot, bool lowerPrivilege, const string &lowestUser) {
0
+ ApplicationPtr sendSpawnCommand(
0
+ const string &appRoot,
0
+ bool lowerPrivilege,
0
+ const string &lowestUser,
0
+ const string &environment
0
+ ) {
0
     vector<string> args;
0
     int ownerPipe;
0
     
0
@@ -252,6 +254,7 @@ private:
0
         appRoot.c_str(),
0
         (lowerPrivilege) ? "true" : "false",
0
         lowestUser.c_str(),
0
+ environment.c_str(),
0
         NULL);
0
     } catch (const SystemException &e) {
0
       throw SpawnException(string("Could not write 'spawn_application' "
0
@@ -316,7 +319,8 @@ private:
0
   
0
   ApplicationPtr
0
   handleSpawnException(const SpawnException &e, const string &appRoot,
0
- bool lowerPrivilege, const string &lowestUser) {
0
+ bool lowerPrivilege, const string &lowestUser,
0
+ const string &environment) {
0
     bool restarted;
0
     try {
0
       P_DEBUG("Spawn server died. Attempting to restart it...");
0
@@ -331,7 +335,7 @@ private:
0
       restarted = false;
0
     }
0
     if (restarted) {
0
- return sendSpawnCommand(appRoot, lowerPrivilege, lowestUser);
0
+ return sendSpawnCommand(appRoot, lowerPrivilege, lowestUser, environment);
0
     } else {
0
       throw SpawnException("The spawn server died unexpectedly, and restarting it failed.");
0
     }
0
@@ -396,9 +400,6 @@ public:
0
    * specified, no log file will be used, and the spawn server
0
    * will use the same standard output/error channels as the
0
    * current process.
0
- * @param environment The RAILS_ENV environment that all RoR applications
0
- * should use. If an empty string is specified, the current value
0
- * of the RAILS_ENV environment variable will be used.
0
    * @param rubyCommand The Ruby interpreter's command.
0
    * @param user The user that the spawn manager should run as. This
0
    * parameter only has effect if the current process is
0
@@ -410,12 +411,10 @@ public:
0
    */
0
   SpawnManager(const string &spawnServerCommand,
0
    const string &logFile = "",
0
- const string &environment = "production",
0
    const string &rubyCommand = "ruby",
0
    const string &user = "") {
0
     this->spawnServerCommand = spawnServerCommand;
0
     this->logFile = logFile;
0
- this->environment = environment;
0
     this->rubyCommand = rubyCommand;
0
     this->user = user;
0
     pid = 0;
0
@@ -470,20 +469,27 @@ public:
0
    * but the path does not have to be absolute.
0
    * @param lowerPrivilege Whether to lower the application's privileges.
0
    * @param lowestUser The user to fallback to if lowering privilege fails.
0
+ * @param environment The RAILS_ENV environment that should be used. May not be empty.
0
    * @return A smart pointer to an Application object, which represents the application
0
    * instance that has been spawned. Use this object to communicate with the
0
    * spawned application.
0
    * @throws SpawnException Something went wrong.
0
    */
0
- ApplicationPtr spawn(const string &appRoot, bool lowerPrivilege = true, const string &lowestUser = "nobody") {
0
+ ApplicationPtr spawn(
0
+ const string &appRoot,
0
+ bool lowerPrivilege = true,
0
+ const string &lowestUser = "nobody",
0
+ const string &environment = "production"
0
+ ) {
0
     mutex::scoped_lock l(lock);
0
     try {
0
- return sendSpawnCommand(appRoot, lowerPrivilege, lowestUser);
0
+ return sendSpawnCommand(appRoot, lowerPrivilege, lowestUser, environment);
0
     } catch (const SpawnException &e) {
0
       if (e.hasErrorPage()) {
0
         throw;
0
       } else {
0
- return handleSpawnException(e, appRoot, lowerPrivilege, lowestUser);
0
+ return handleSpawnException(e, appRoot, lowerPrivilege,
0
+ lowestUser, environment);
0
       }
0
     }
0
   }
...
269
270
271
272
273
 
 
 
 
 
 
 
274
275
276
...
312
313
314
315
 
316
317
318
...
337
338
339
340
 
 
341
342
343
...
400
401
402
403
404
405
406
407
408
 
409
410
411
...
441
442
443
444
445
 
 
 
 
 
 
446
447
448
...
452
453
454
455
 
456
457
458
...
269
270
271
 
 
272
273
274
275
276
277
278
279
280
281
...
317
318
319
 
320
321
322
323
...
342
343
344
 
345
346
347
348
349
...
406
407
408
 
409
410
411
412
 
413
414
415
416
...
446
447
448
 
 
449
450
451
452
453
454
455
456
457
...
461
462
463
 
464
465
466
467
0
@@ -269,8 +269,13 @@ private:
0
   }
0
   
0
   pair<AppContainerPtr, AppContainerList *>
0
- spawnOrUseExisting(mutex::scoped_lock &l, const string &appRoot,
0
- bool lowerPrivilege, const string &lowestUser) {
0
+ spawnOrUseExisting(
0
+ mutex::scoped_lock &l,
0
+ const string &appRoot,
0
+ bool lowerPrivilege,
0
+ const string &lowestUser,
0
+ const string &environment
0
+ ) {
0
     AppContainerPtr container;
0
     AppContainerList *list;
0
     
0
@@ -312,7 +317,7 @@ private:
0
         } else {
0
           container = ptr(new AppContainer());
0
           container->app = spawnManager.spawn(appRoot,
0
- lowerPrivilege, lowestUser);
0
+ lowerPrivilege, lowestUser, environment);
0
           container->sessions = 0;
0
           list->push_back(container);
0
           container->iterator = list->end();
0
@@ -337,7 +342,8 @@ private:
0
           count--;
0
         }
0
         container = ptr(new AppContainer());
0
- container->app = spawnManager.spawn(appRoot, lowerPrivilege, lowestUser);
0
+ container->app = spawnManager.spawn(appRoot, lowerPrivilege, lowestUser,
0
+ environment);
0
         container->sessions = 0;
0
         it = apps.find(appRoot);
0
         if (it == apps.end()) {
0
@@ -400,12 +406,11 @@ public:
0
    */
0
   StandardApplicationPool(const string &spawnServerCommand,
0
    const string &logFile = "",
0
- const string &environment = "production",
0
    const string &rubyCommand = "ruby",
0
    const string &user = "")
0
    :
0
     #ifndef PASSENGER_USE_DUMMY_SPAWN_MANAGER
0
- spawnManager(spawnServerCommand, logFile, environment, rubyCommand, user),
0
+ spawnManager(spawnServerCommand, logFile, rubyCommand, user),
0
     #endif
0
     data(new SharedData()),
0
     lock(data->lock),
0
@@ -441,8 +446,12 @@ public:
0
     delete cleanerThread;
0
   }
0
   
0
- virtual Application::SessionPtr
0
- get(const string &appRoot, bool lowerPrivilege = true, const string &lowestUser = "nobody") {
0
+ virtual Application::SessionPtr get(
0
+ const string &appRoot,
0
+ bool lowerPrivilege = true,
0
+ const string &lowestUser = "nobody",
0
+ const string &environment = "production"
0
+ ) {
0
     unsigned int attempt;
0
     const unsigned int MAX_ATTEMPTS = 5;
0
     
0
@@ -452,7 +461,7 @@ public:
0
       
0
       mutex::scoped_lock l(lock);
0
       pair<AppContainerPtr, AppContainerList *> p(
0
- spawnOrUseExisting(l, appRoot, lowerPrivilege, lowestUser)
0
+ spawnOrUseExisting(l, appRoot, lowerPrivilege, lowestUser, environment)
0
       );
0
       AppContainerPtr &container(p.first);
0
       AppContainerList &list(*p.second);
...
102
103
104
105
 
 
 
106
107
108
...
113
114
115
 
116
117
118
...
144
145
146
 
 
 
147
148
149
...
157
158
159
 
160
161
162
...
221
222
223
 
 
 
 
 
224
225
226
...
102
103
104
 
105
106
107
108
109
110
...
115
116
117
118
119
120
121
...
147
148
149
150
151
152
153
154
155
...
163
164
165
166
167
168
169
...
228
229
230
231
232
233
234
235
236
237
238
0
@@ -102,7 +102,9 @@ class ApplicationSpawner < AbstractServer
0
   # If +lowest_user+ doesn't exist either, or if switching user failed
0
   # (because the current process does not have the privilege to do so),
0
   # then ApplicationSpawner will continue without reporting an error.
0
- def initialize(app_root, lower_privilege = true, lowest_user = "nobody")
0
+ #
0
+ # The +environment+ argument allows one to specify the RAILS_ENV environment to use.
0
+ def initialize(app_root, lower_privilege = true, lowest_user = "nobody", environment = "production")
0
     super()
0
     begin
0
       @app_root = normalize_path(app_root)
0
@@ -113,6 +115,7 @@ class ApplicationSpawner < AbstractServer
0
     end
0
     @lower_privilege = lower_privilege
0
     @lowest_user = lowest_user
0
+ @environment = environment
0
     self.time = Time.now
0
     assert_valid_app_root(@app_root)
0
     define_message_handler(:spawn_application, :handle_spawn_application)
0
@@ -144,6 +147,9 @@ class ApplicationSpawner < AbstractServer
0
   # server isn't started. This allows one to spawn a RoR application without preloading
0
   # any source files.
0
   #
0
+ # This method may only be called if no Rails framework has been loaded in the current
0
+ # Ruby VM.
0
+ #
0
   # Raises:
0
   # - AppInitError: The Ruby on Rails application raised an exception
0
   # or called exit() during startup.
0
@@ -157,6 +163,7 @@ class ApplicationSpawner < AbstractServer
0
           a.close
0
           channel = MessageChannel.new(b)
0
           success = report_app_init_status(channel) do
0
+ ENV['RAILS_ENV'] = @environment
0
             Dir.chdir(@app_root)
0
             lower_privilege! if @lower_privilege
0
             require 'config/environment'
0
@@ -221,6 +228,11 @@ protected
0
   def initialize_server # :nodoc:
0
     report_app_init_status(client) do
0
       $0 = "Passenger ApplicationSpawner: #{@app_root}"
0
+ ENV['RAILS_ENV'] = @environment
0
+ if defined?(RAILS_ENV)
0
+ Object.send(:remove_const, :RAILS_ENV)
0
+ Object.const_set(:RAILS_ENV, ENV['RAILS_ENV'])
0
+ end
0
       Dir.chdir(@app_root)
0
       lower_privilege! if @lower_privilege
0
       preload_application
...
128
129
130
131
132
 
 
133
134
135
...
143
144
145
146
 
147
148
149
150
151
 
152
153
154
...
270
271
272
273
 
274
275
276
277
278
279
 
 
 
280
281
282
...
128
129
130
 
 
131
132
133
134
135
...
143
144
145
 
146
147
148
149
150
 
151
152
153
154
...
270
271
272
 
273
274
275
276
277
278
 
279
280
281
282
283
284
0
@@ -128,8 +128,8 @@ class FrameworkSpawner < AbstractServer
0
   # When successful, an Application object will be returned, which represents
0
   # the spawned RoR application.
0
   #
0
- # See ApplicationSpawner.new for an explanation of the +lower_privilege+
0
- # and +lowest_user+ parameters.
0
+ # See ApplicationSpawner.new for an explanation of the +lower_privilege+,
0
+ # +lowest_user+ and +environment+ parameters.
0
   #
0
   # FrameworkSpawner will internally cache the code of applications, in order to
0
   # speed up future spawning attempts. This implies that, if you've changed
0
@@ -143,12 +143,12 @@ class FrameworkSpawner < AbstractServer
0
   # - AppInitError: The application raised an exception or called exit() during startup.
0
   # - ApplicationSpawner::Error: The ApplicationSpawner server exited unexpectedly.
0
   # - FrameworkSpawner::Error: The FrameworkSpawner server exited unexpectedly.
0
- def spawn_application(app_root, lower_privilege = true, lowest_user = "nobody")
0
+ def spawn_application(app_root, lower_privilege = true, lowest_user = "nobody", environment = "production")
0
     app_root = normalize_path(app_root)
0
     assert_valid_app_root(app_root)
0
     exception_to_propagate = nil
0
     begin
0
- server.write("spawn_application", app_root, lower_privilege, lowest_user)
0
+ server.write("spawn_application", app_root, lower_privilege, lowest_user, environment)
0
       result = server.read
0
       if result.nil?
0
         raise IOError, "Connection closed"
0
@@ -270,13 +270,15 @@ private
0
     Object.send(:remove_const, :RAILS_ROOT)
0
   end
0
 
0
- def handle_spawn_application(app_root, lower_privilege, lowest_user)
0
+ def handle_spawn_application(app_root, lower_privilege, lowest_user, environment)
0
     lower_privilege = lower_privilege == "true"
0
     @spawners_lock.synchronize do
0
       spawner = @spawners[app_root]
0
       if spawner.nil?
0
         begin
0
- spawner = ApplicationSpawner.new(app_root, lower_privilege, lowest_user)
0
+ spawner = ApplicationSpawner.new(app_root,
0
+ lower_privilege, lowest_user,
0
+ environment)
0
           spawner.start
0
         rescue ArgumentError, AppInitError, ApplicationSpawner::Error => e
0
           client.write('exception')