passenger 4.0.24 → 4.0.25

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 (37) hide show
  1. data.tar.gz.asc +7 -7
  2. data/INSTALL.md +2 -2
  3. data/NEWS +12 -0
  4. data/README.md +14 -6
  5. data/build/packaging.rb +3 -1
  6. data/doc/Users guide Apache.idmap.txt +19 -17
  7. data/doc/Users guide Apache.txt +146 -95
  8. data/doc/Users guide Nginx.txt +6 -6
  9. data/doc/Users guide Standalone.idmap.txt +19 -15
  10. data/doc/Users guide Standalone.txt +26 -1
  11. data/doc/Users guide.txt +9 -0
  12. data/doc/images/passenger_nodejs_architecture.svg +558 -0
  13. data/doc/users_guide_snippets/installation.txt +19 -16
  14. data/ext/common/AgentsStarter.h +1 -11
  15. data/ext/common/ApplicationPool2/AppTypes.cpp +5 -0
  16. data/ext/common/ApplicationPool2/AppTypes.h +1 -0
  17. data/ext/common/ApplicationPool2/Options.h +8 -4
  18. data/ext/common/ApplicationPool2/Spawner.h +1 -0
  19. data/ext/common/Constants.h +2 -2
  20. data/ext/common/ServerInstanceDir.h +9 -24
  21. data/ext/common/agents/HelperAgent/RequestHandler.h +1 -0
  22. data/ext/nginx/CacheLocationConfig.c +40 -0
  23. data/ext/nginx/ConfigurationCommands.c +30 -0
  24. data/ext/nginx/ConfigurationFields.h +6 -0
  25. data/ext/nginx/ContentHandler.c +40 -32
  26. data/ext/nginx/CreateLocationConfig.c +15 -0
  27. data/ext/nginx/MergeLocationConfig.c +18 -0
  28. data/helper-scripts/node-loader.js +2 -1
  29. data/lib/phusion_passenger.rb +3 -3
  30. data/lib/phusion_passenger/constants.rb +1 -1
  31. data/lib/phusion_passenger/nginx/config_options.rb +13 -0
  32. data/lib/phusion_passenger/standalone/start_command.rb +19 -2
  33. data/lib/phusion_passenger/utils/tmpdir.rb +0 -1
  34. data/resources/templates/standalone/config.erb +8 -1
  35. data/test/integration_tests/native_packaging_spec.rb +14 -4
  36. metadata +3 -2
  37. metadata.gz.asc +7 -7
@@ -124,6 +124,10 @@ sudo apt-get update
124
124
 
125
125
  ==== Installing packages
126
126
 
127
+ ifdef::nginx[]
128
+ NOTE: You should install `nginx-extras` even if you have already installed an Nginx package from the official Debian/Ubuntu repository. This is because the Nginx binary that our packages supply is compiled with the Passenger module.
129
+ endif::nginx[]
130
+
127
131
  **Open source**::
128
132
  +
129
133
  1. <<install_add_apt_repo,Add our APT repository.>>
@@ -131,8 +135,9 @@ ifdef::nginx[]
131
135
  2. Install the packages:
132
136
  +
133
137
  --------------------------------------------------------------
134
- sudo apt-get install nginx-full passenger
138
+ sudo apt-get install nginx-extras passenger
135
139
  --------------------------------------------------------------
140
+ +
136
141
  3. Edit `/etc/nginx/nginx.conf` and uncomment `passenger_root` and `passenger_ruby`.
137
142
  4. Restart Nginx:
138
143
  +
@@ -163,7 +168,7 @@ endif::[]
163
168
  +
164
169
  ifdef::nginx[]
165
170
  --------------------------------------------------------------
166
- sudo apt-get install nginx-full passenger-enterprise
171
+ sudo apt-get install nginx-extras passenger-enterprise
167
172
  --------------------------------------------------------------
168
173
  4. Edit `/etc/nginx/nginx.conf` and uncomment `passenger_root` and `passenger_ruby`.
169
174
  5. Restart Nginx:
@@ -721,21 +726,13 @@ endif::[]
721
726
  ifdef::nginx[]
722
727
  === Installing as a normal Nginx module without using the installer
723
728
 
724
- You can also install Phusion Passenger the way you install any other Nginx module, e.g. with `--add-module`. Run Nginx's configure script with `--add-module=/path-to-passenger-root/ext/nginx`.
729
+ You can also install Phusion Passenger the way you install any other Nginx module, e.g. with `--add-module`. This installation mode is useful if you already have an Nginx tarball somewhere, or if you're using link:http://nginx.com/products/[Nginx Plus].
725
730
 
726
- If you installed Phusion Passenger via the gem, then 'path-to-passenger-root' can be obtained with the command:
727
-
728
- --------------------------
729
- passenger-config --root
730
- --------------------------
731
+ You need to run Nginx's configure script with `--add-module=/path-to-passenger-nginx-addon-dir`. The right value for `/path-to-passenger-nginx-addon-dir` can be obtained with the command:
731
732
 
732
- This will probably output something along the lines of '/usr/lib/ruby/gems/1.8/gems/passenger-x.x.x',
733
- so you'll probably have to specify something like `--add-module=/usr/lib/ruby/gems/1.8/gems/passenger-x.x.x/ext/nginx`.
734
-
735
- If you installed Phusion Passenger via a source tarball, then 'path-to-passenger-root'
736
- is the directory which contains the Phusion Passenger source code. So if you
737
- extracted the Phusion Passenger source code to '/opt/passenger-x.x.x', then you'll
738
- have to specify `--add-module=/opt/passenger-x.x.x/ext/nginx`.
733
+ -------------------------------------
734
+ passenger-config --nginx-addon-dir
735
+ -------------------------------------
739
736
 
740
737
  After having installed Nginx with Phusion Passenger support, you must paste the following
741
738
  line into your Nginx configuration file:
@@ -744,7 +741,13 @@ line into your Nginx configuration file:
744
741
  passenger_root /path-to-passenger-root;
745
742
  ------------------------------------------
746
743
 
747
- After having done so, restart Nginx.
744
+ The right value for `/path-to-passenger-root` can be obtained by running the following command:
745
+
746
+ -------------------------------------
747
+ passenger-config --root
748
+ -------------------------------------
749
+
750
+ After having modified the Nginx configuration file, restart Nginx.
748
751
 
749
752
  [[nginx_init_script]]
750
753
  === Creating an Nginx init script
@@ -389,6 +389,7 @@ public:
389
389
  params
390
390
  .set ("web_server_type", type == AS_APACHE ? "apache" : "nginx")
391
391
  .setPid ("web_server_pid", getpid())
392
+ .set ("web_server_passenger_version", PASSENGER_VERSION)
392
393
  .set ("passenger_root", passengerRoot)
393
394
  .setInt ("log_level", getLogLevel())
394
395
  .set ("temp_dir", getSystemTempDir());
@@ -404,17 +405,6 @@ public:
404
405
  // .set ("default_ruby", defaultRubyCommand)
405
406
  // .setInt ("max_pool_size", maxPoolSize)
406
407
  // .setInt ("max_instances_per_app", maxInstancesPerApp)
407
- /*
408
- .setInt ("pool_idle_time", poolIdleTime)
409
- .set ("analytics_server", analyticsServer)
410
- .set ("analytics_log_user", analyticsLogUser)
411
- .set ("analytics_log_group", analyticsLogGroup)
412
- .set ("union_station_gateway_address", unionStationGatewayAddress)
413
- .setInt ("union_station_gateway_port", unionStationGatewayPort)
414
- .set ("union_station_gateway_cert", realUnionStationGatewayCert)
415
- .set ("union_station_proxy_address", unionStationProxyAddress)
416
- .set ("prestart_urls", serializePrestartURLs(prestartURLs));
417
- */
418
408
 
419
409
  fds = createUnixSocketPair();
420
410
  pid = syscalls::fork();
@@ -92,3 +92,8 @@ const char *
92
92
  pp_get_app_type_name(PassengerAppType type) {
93
93
  return getAppTypeName(type);
94
94
  }
95
+
96
+ PassengerAppType
97
+ pp_get_app_type2(const char *name, unsigned int len) {
98
+ return getAppType(StaticString(name, len));
99
+ }
@@ -61,6 +61,7 @@ PassengerAppType pp_app_type_detector_check_app_root(PP_AppTypeDetector *detecto
61
61
  const char *appRoot, unsigned int len, PP_Error *error);
62
62
 
63
63
  const char *pp_get_app_type_name(PassengerAppType type);
64
+ PassengerAppType pp_get_app_type2(const char *name, unsigned int len);
64
65
 
65
66
  #ifdef __cplusplus
66
67
  }
@@ -603,11 +603,15 @@ public:
603
603
  }
604
604
 
605
605
  StaticString getStartupFile() const {
606
- const char *result = getAppTypeStartupFile(getAppType(appType));
607
- if (result == NULL) {
608
- return startupFile;
606
+ if (startupFile.empty()) {
607
+ const char *result = getAppTypeStartupFile(getAppType(appType));
608
+ if (result == NULL) {
609
+ return "";
610
+ } else {
611
+ return result;
612
+ }
609
613
  } else {
610
- return result;
614
+ return startupFile;
611
615
  }
612
616
  }
613
617
 
@@ -1004,6 +1004,7 @@ protected:
1004
1004
  appendNullTerminatedKeyValue(result, "RAILS_ENV", options.environment);
1005
1005
  appendNullTerminatedKeyValue(result, "RACK_ENV", options.environment);
1006
1006
  appendNullTerminatedKeyValue(result, "WSGI_ENV", options.environment);
1007
+ appendNullTerminatedKeyValue(result, "NODE_ENV", options.environment);
1007
1008
  appendNullTerminatedKeyValue(result, "PASSENGER_ENV", options.environment);
1008
1009
  if (!options.baseURI.empty() && options.baseURI != "/") {
1009
1010
  appendNullTerminatedKeyValue(result,
@@ -80,7 +80,7 @@
80
80
 
81
81
  #define NGINX_DOC_URL "http://www.modrails.com/documentation/Users%20guide%20Nginx.html"
82
82
 
83
- #define PASSENGER_VERSION "4.0.24"
83
+ #define PASSENGER_VERSION "4.0.25"
84
84
 
85
85
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
86
86
 
@@ -90,7 +90,7 @@
90
90
 
91
91
  #define PROGRAM_NAME "Phusion Passenger"
92
92
 
93
- #define SERVER_INSTANCE_DIR_GENERATION_STRUCTURE_MAJOR_VERSION 2
93
+ #define SERVER_INSTANCE_DIR_GENERATION_STRUCTURE_MAJOR_VERSION 3
94
94
 
95
95
  #define SERVER_INSTANCE_DIR_GENERATION_STRUCTURE_MINOR_VERSION 0
96
96
 
@@ -110,6 +110,11 @@ public:
110
110
  toString(SERVER_INSTANCE_DIR_GENERATION_STRUCTURE_MINOR_VERSION),
111
111
  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
112
112
 
113
+ string passengerVersionFile = path + "/passenger_version.txt";
114
+ createFile(passengerVersionFile,
115
+ PASSENGER_VERSION "\n",
116
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
117
+
113
118
 
114
119
  /* We want the upload buffer directory to be only writable by the web
115
120
  * server's worker processs. Other users may not have any access to this
@@ -122,17 +127,17 @@ public:
122
127
  makeDirTree(path + "/buffered_uploads", "u=rwx,g=,o=");
123
128
  }
124
129
 
125
- /* The web server must be able to directly connect to a backend. */
130
+ /* The HelperAgent must be able to connect to an application. */
126
131
  if (runningAsRoot) {
127
132
  if (userSwitching) {
128
- /* Each backend process may be running as a different user,
133
+ /* Each application process may be running as a different user,
129
134
  * so the backends subdirectory must be world-writable.
130
135
  * However we don't want everybody to be able to know the
131
136
  * sockets' filenames, so the directory is not readable.
132
137
  */
133
138
  makeDirTree(path + "/backends", "u=rwx,g=wx,o=wx,+t");
134
139
  } else {
135
- /* All backend processes are running as defaultUser/defaultGroup,
140
+ /* All application processes are running as defaultUser/defaultGroup,
136
141
  * so make defaultUser/defaultGroup the owner and group of the
137
142
  * subdirecory.
138
143
  *
@@ -143,32 +148,12 @@ public:
143
148
  makeDirTree(path + "/backends", "u=rwx,g=x,o=x", defaultUid, defaultGid);
144
149
  }
145
150
  } else {
146
- /* All backend processes are running as the same user as the web server,
151
+ /* All application processes are running as the same user as the web server,
147
152
  * so only allow access for this user.
148
153
  */
149
154
  makeDirTree(path + "/backends", "u=rwx,g=,o=");
150
155
  }
151
156
 
152
- /* The helper server (containing the application pool) must be able to access
153
- * the spawn server's socket.
154
- */
155
- if (runningAsRoot) {
156
- if (userSwitching) {
157
- /* Both the helper server and the spawn server are
158
- * running as root.
159
- */
160
- makeDirTree(path + "/spawn-server", "u=rwx,g=,o=");
161
- } else {
162
- /* Both the helper server and the spawn server are
163
- * running as defaultUser/defaultGroup.
164
- */
165
- makeDirTree(path + "/spawn-server", "u=rwx,g=,o=",
166
- defaultUid, defaultGid);
167
- }
168
- } else {
169
- makeDirTree(path + "/spawn-server", "u=rwx,g=,o=");
170
- }
171
-
172
157
  owner = true;
173
158
  }
174
159
 
@@ -1730,6 +1730,7 @@ private:
1730
1730
  fillPoolOption(client, options.maxRequestQueueSize, "PASSENGER_MAX_REQUEST_QUEUE_SIZE");
1731
1731
  fillPoolOption(client, options.statThrottleRate, "PASSENGER_STAT_THROTTLE_RATE");
1732
1732
  fillPoolOption(client, options.restartDir, "PASSENGER_RESTART_DIR");
1733
+ fillPoolOption(client, options.startupFile, "PASSENGER_STARTUP_FILE");
1733
1734
  fillPoolOption(client, options.loadShellEnvvars, "PASSENGER_LOAD_SHELL_ENVVARS");
1734
1735
  fillPoolOption(client, options.debugger, "PASSENGER_DEBUGGER");
1735
1736
  fillPoolOption(client, options.raiseInternalError, "PASSENGER_RAISE_INTERNAL_ERROR");
@@ -221,6 +221,20 @@ u_char int_buf[32], *end, *buf, *pos;
221
221
  }
222
222
 
223
223
 
224
+
225
+ if (conf->restart_dir.data != NULL) {
226
+ len += 22;
227
+ len += conf->restart_dir.len + 1;
228
+ }
229
+
230
+
231
+
232
+ if (conf->startup_file.data != NULL) {
233
+ len += 23;
234
+ len += conf->startup_file.len + 1;
235
+ }
236
+
237
+
224
238
 
225
239
  /* Create string */
226
240
  buf = pos = ngx_pnalloc(cf->pool, len);
@@ -536,6 +550,32 @@ buf = pos = ngx_pnalloc(cf->pool, len);
536
550
  }
537
551
 
538
552
 
553
+
554
+ if (conf->restart_dir.data != NULL) {
555
+ pos = ngx_copy(pos,
556
+ "PASSENGER_RESTART_DIR",
557
+ 22);
558
+ pos = ngx_copy(pos,
559
+ conf->restart_dir.data,
560
+ conf->restart_dir.len);
561
+ *pos = '\0';
562
+ pos++;
563
+ }
564
+
565
+
566
+
567
+ if (conf->startup_file.data != NULL) {
568
+ pos = ngx_copy(pos,
569
+ "PASSENGER_STARTUP_FILE",
570
+ 23);
571
+ pos = ngx_copy(pos,
572
+ conf->startup_file.data,
573
+ conf->startup_file.len);
574
+ *pos = '\0';
575
+ pos++;
576
+ }
577
+
578
+
539
579
 
540
580
  conf->options_cache.data = buf;
541
581
  conf->options_cache.len = pos - buf;
@@ -379,6 +379,36 @@
379
379
  NULL
380
380
  },
381
381
 
382
+ {
383
+
384
+ ngx_string("passenger_restart_dir"),
385
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
386
+ ngx_conf_set_str_slot,
387
+ NGX_HTTP_LOC_CONF_OFFSET,
388
+ offsetof(passenger_loc_conf_t, restart_dir),
389
+ NULL
390
+ },
391
+
392
+ {
393
+
394
+ ngx_string("passenger_app_type"),
395
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
396
+ ngx_conf_set_str_slot,
397
+ NGX_HTTP_LOC_CONF_OFFSET,
398
+ offsetof(passenger_loc_conf_t, app_type),
399
+ NULL
400
+ },
401
+
402
+ {
403
+
404
+ ngx_string("passenger_startup_file"),
405
+ NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
406
+ ngx_conf_set_str_slot,
407
+ NGX_HTTP_LOC_CONF_OFFSET,
408
+ offsetof(passenger_loc_conf_t, startup_file),
409
+ NULL
410
+ },
411
+
382
412
  {
383
413
 
384
414
  ngx_string("passenger_fly_with"),
@@ -75,6 +75,8 @@
75
75
 
76
76
  ngx_str_t app_root;
77
77
 
78
+ ngx_str_t app_type;
79
+
78
80
  ngx_str_t environment;
79
81
 
80
82
  ngx_str_t group;
@@ -83,10 +85,14 @@
83
85
 
84
86
  ngx_str_t python;
85
87
 
88
+ ngx_str_t restart_dir;
89
+
86
90
  ngx_str_t ruby;
87
91
 
88
92
  ngx_str_t spawn_method;
89
93
 
94
+ ngx_str_t startup_file;
95
+
90
96
  ngx_str_t union_station_key;
91
97
 
92
98
  ngx_str_t user;
@@ -1304,40 +1304,48 @@ passenger_content_handler(ngx_http_request_t *r)
1304
1304
  return passenger_static_content_handler(r, &page_cache_file);
1305
1305
  }
1306
1306
 
1307
- pp_error_init(&error);
1308
- if (slcf->app_root.data == NULL) {
1309
- context->app_type = pp_app_type_detector_check_document_root(
1310
- pp_app_type_detector,
1311
- (const char *) context->public_dir.data, context->public_dir.len,
1312
- context->base_uri.len != 0,
1313
- &error);
1314
- } else {
1315
- context->app_type = pp_app_type_detector_check_app_root(
1316
- pp_app_type_detector,
1317
- (const char *) slcf->app_root.data, slcf->app_root.len,
1318
- &error);
1319
- }
1320
- if (context->app_type == PAT_NONE) {
1321
- return NGX_DECLINED;
1322
- } else if (context->app_type == PAT_ERROR) {
1323
- if (error.errnoCode == EACCES) {
1324
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1325
- "%s; This error means that the Nginx worker process (PID %d, "
1326
- "running as UID %d) does not have permission to access this file. "
1327
- "Please read the manual to learn how to fix this problem: "
1328
- "section 'Troubleshooting' -> 'Upon accessing the web app, Nginx "
1329
- "reports a \"Permission denied\" error'; Extra info",
1330
- error.message,
1331
- (int) getpid(),
1332
- (int) getuid());
1307
+ if (slcf->app_type.data == NULL) {
1308
+ pp_error_init(&error);
1309
+ if (slcf->app_root.data == NULL) {
1310
+ context->app_type = pp_app_type_detector_check_document_root(
1311
+ pp_app_type_detector,
1312
+ (const char *) context->public_dir.data, context->public_dir.len,
1313
+ context->base_uri.len != 0,
1314
+ &error);
1333
1315
  } else {
1334
- ngx_log_error(NGX_LOG_ALERT, r->connection->log,
1335
- (error.errnoCode == PP_NO_ERRNO) ? 0 : error.errnoCode,
1336
- "%s",
1337
- error.message);
1316
+ context->app_type = pp_app_type_detector_check_app_root(
1317
+ pp_app_type_detector,
1318
+ (const char *) slcf->app_root.data, slcf->app_root.len,
1319
+ &error);
1320
+ }
1321
+ if (context->app_type == PAT_NONE) {
1322
+ return NGX_DECLINED;
1323
+ } else if (context->app_type == PAT_ERROR) {
1324
+ if (error.errnoCode == EACCES) {
1325
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1326
+ "%s; This error means that the Nginx worker process (PID %d, "
1327
+ "running as UID %d) does not have permission to access this file. "
1328
+ "Please read the manual to learn how to fix this problem: "
1329
+ "section 'Troubleshooting' -> 'Upon accessing the web app, Nginx "
1330
+ "reports a \"Permission denied\" error'; Extra info",
1331
+ error.message,
1332
+ (int) getpid(),
1333
+ (int) getuid());
1334
+ } else {
1335
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log,
1336
+ (error.errnoCode == PP_NO_ERRNO) ? 0 : error.errnoCode,
1337
+ "%s",
1338
+ error.message);
1339
+ }
1340
+ pp_error_destroy(&error);
1341
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
1342
+ }
1343
+ } else {
1344
+ context->app_type = pp_get_app_type2((const char *) slcf->app_type.data,
1345
+ slcf->app_type.len);
1346
+ if (context->app_type == PAT_NONE) {
1347
+ return NGX_DECLINED;
1338
1348
  }
1339
- pp_error_destroy(&error);
1340
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
1341
1349
  }
1342
1350
 
1343
1351
 
@@ -154,3 +154,18 @@
154
154
  conf->request_queue_overflow_status_code = NGX_CONF_UNSET;
155
155
 
156
156
 
157
+
158
+ conf->restart_dir.data = NULL;
159
+ conf->restart_dir.len = 0;
160
+
161
+
162
+
163
+ conf->app_type.data = NULL;
164
+ conf->app_type.len = 0;
165
+
166
+
167
+
168
+ conf->startup_file.data = NULL;
169
+ conf->startup_file.len = 0;
170
+
171
+