passenger 4.0.3 → 4.0.4

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 (46) hide show
  1. data.tar.gz.asc +7 -7
  2. data/NEWS +30 -0
  3. data/build/agents.rb +3 -0
  4. data/build/apache2.rb +2 -3
  5. data/build/basics.rb +20 -0
  6. data/build/common_library.rb +15 -0
  7. data/build/cxx_tests.rb +4 -1
  8. data/build/packaging.rb +22 -32
  9. data/doc/Packaging.html +792 -0
  10. data/doc/Users guide Nginx.html +2 -2
  11. data/doc/Users guide Nginx.txt +2 -2
  12. data/ext/apache2/Configuration.cpp +34 -62
  13. data/ext/apache2/Configuration.hpp +1 -14
  14. data/ext/apache2/DirectoryMapper.h +134 -104
  15. data/ext/apache2/Hooks.cpp +33 -19
  16. data/ext/common/AgentsStarter.cpp +22 -22
  17. data/ext/common/AgentsStarter.h +25 -25
  18. data/ext/common/ApplicationPool2/AppTypes.cpp +6 -6
  19. data/ext/common/ApplicationPool2/AppTypes.h +61 -9
  20. data/ext/common/ApplicationPool2/Implementation.cpp +14 -2
  21. data/ext/common/Constants.h +54 -23
  22. data/ext/common/Constants.h.erb +42 -0
  23. data/ext/common/ServerInstanceDir.h +6 -11
  24. data/ext/common/Utils/CachedFileStat.cpp +10 -9
  25. data/ext/common/Utils/CachedFileStat.h +8 -8
  26. data/ext/common/Utils/LargeFiles.cpp +12 -4
  27. data/ext/common/agents/HelperAgent/RequestHandler.h +1 -0
  28. data/ext/common/agents/Watchdog/Main.cpp +2 -2
  29. data/ext/nginx/Configuration.c +1 -1
  30. data/ext/nginx/Configuration.h +0 -1
  31. data/ext/nginx/ContentHandler.c +15 -15
  32. data/ext/nginx/ngx_http_passenger_module.c +48 -48
  33. data/ext/nginx/ngx_http_passenger_module.h +7 -9
  34. data/helper-scripts/wsgi-loader.py +2 -2
  35. data/lib/phusion_passenger.rb +1 -3
  36. data/lib/phusion_passenger/admin_tools/server_instance.rb +5 -11
  37. data/lib/phusion_passenger/constants.rb +42 -0
  38. data/lib/phusion_passenger/packaging.rb +8 -6
  39. data/lib/phusion_passenger/platform_info.rb +11 -6
  40. data/lib/phusion_passenger/standalone/command.rb +4 -2
  41. data/lib/phusion_passenger/standalone/runtime_installer.rb +1 -1
  42. data/resources/templates/standalone/config.erb +14 -2
  43. data/test/ruby/admin_tools_spec.rb +14 -16
  44. metadata +4 -3
  45. metadata.gz.asc +7 -7
  46. data/lib/phusion_passenger/wsgi/request_handler.py +0 -199
@@ -4181,7 +4181,7 @@ passenger_pre_start http://bar.com:3500/; # &lt;--- added</pre>
4181
4181
  listen 80;
4182
4182
  server_name myblog.com;
4183
4183
  root /webapps/wordpress;
4184
- rails_base_uri /store;
4184
+ passenger_base_uri /store;
4185
4185
  }</pre>
4186
4186
  </div>
4187
4187
  </div>
@@ -4192,7 +4192,7 @@ passenger_pre_start http://bar.com:3500/; # &lt;--- added</pre>
4192
4192
  listen 80;
4193
4193
  server_name myblog.com;
4194
4194
  root /webapps/wordpress;
4195
- rails_base_uri /store;
4195
+ passenger_base_uri /store;
4196
4196
  }
4197
4197
 
4198
4198
  passenger_pre_start http://myblog.com/store; # &lt;----- added</pre>
@@ -1381,7 +1381,7 @@ server {
1381
1381
  listen 80;
1382
1382
  server_name myblog.com;
1383
1383
  root /webapps/wordpress;
1384
- rails_base_uri /store;
1384
+ passenger_base_uri /store;
1385
1385
  }
1386
1386
  ---------------------------
1387
1387
 
@@ -1392,7 +1392,7 @@ server {
1392
1392
  listen 80;
1393
1393
  server_name myblog.com;
1394
1394
  root /webapps/wordpress;
1395
- rails_base_uri /store;
1395
+ passenger_base_uri /store;
1396
1396
  }
1397
1397
 
1398
1398
  passenger_pre_start http://myblog.com/store; # <----- added
@@ -220,13 +220,9 @@ passenger_config_merge_dir(apr_pool_t *p, void *basev, void *addv) {
220
220
 
221
221
  config->enabled = (add->enabled == DirConfig::UNSET) ? base->enabled : add->enabled;
222
222
 
223
- config->railsBaseURIs = base->railsBaseURIs;
224
- for (set<string>::const_iterator it(add->railsBaseURIs.begin()); it != add->railsBaseURIs.end(); it++) {
225
- config->railsBaseURIs.insert(*it);
226
- }
227
- config->rackBaseURIs = base->rackBaseURIs;
228
- for (set<string>::const_iterator it(add->rackBaseURIs.begin()); it != add->rackBaseURIs.end(); it++) {
229
- config->rackBaseURIs.insert(*it);
223
+ config->baseURIs = base->baseURIs;
224
+ for (set<string>::const_iterator it(add->baseURIs.begin()); it != add->baseURIs.end(); it++) {
225
+ config->baseURIs.insert(*it);
230
226
  }
231
227
 
232
228
  MERGE_STR_CONFIG(ruby);
@@ -338,6 +334,21 @@ cmd_passenger_spawn_method(cmd_parms *cmd, void *pcfg, const char *arg) {
338
334
  return NULL;
339
335
  }
340
336
 
337
+ static const char *
338
+ cmd_passenger_base_uri(cmd_parms *cmd, void *pcfg, const char *arg) {
339
+ DirConfig *config = (DirConfig *) pcfg;
340
+ if (strlen(arg) == 0) {
341
+ return "PassengerBaseURI may not be set to the empty string";
342
+ } else if (arg[0] != '/') {
343
+ return "PassengerBaseURI must start with a slash (/)";
344
+ } else if (strlen(arg) > 1 && arg[strlen(arg) - 1] == '/') {
345
+ return "PassengerBaseURI must not end with a slash (/)";
346
+ } else {
347
+ config->baseURIs.insert(arg);
348
+ return NULL;
349
+ }
350
+ }
351
+
341
352
  static const char *
342
353
  cmd_union_station_filter(cmd_parms *cmd, void *pcfg, const char *arg) {
343
354
  DirConfig *config = (DirConfig *) pcfg;
@@ -358,26 +369,9 @@ cmd_union_station_filter(cmd_parms *cmd, void *pcfg, const char *arg) {
358
369
 
359
370
 
360
371
  /*************************************************
361
- * Rails-specific settings
372
+ * Rack-specific settings
362
373
  *************************************************/
363
374
 
364
- static const char *
365
- cmd_rails_base_uri(cmd_parms *cmd, void *pcfg, const char *arg) {
366
- DirConfig *config = (DirConfig *) pcfg;
367
- if (strlen(arg) == 0) {
368
- return "RailsBaseURI may not be set to the empty string";
369
- } else if (arg[0] != '/') {
370
- return "RailsBaseURI must start with a slash (/)";
371
- } else if (strlen(arg) > 1 && arg[strlen(arg) - 1] == '/') {
372
- return "RailsBaseURI must not end with a slash (/)";
373
- } else {
374
- config->railsBaseURIs.insert(arg);
375
- return NULL;
376
- }
377
- }
378
-
379
-
380
-
381
375
  static const char *
382
376
  cmd_passenger_max_preloader_idle_time(cmd_parms *cmd, void *pcfg, const char *arg) {
383
377
  DirConfig *config = (DirConfig *) pcfg;
@@ -396,33 +390,6 @@ cmd_passenger_max_preloader_idle_time(cmd_parms *cmd, void *pcfg, const char *ar
396
390
  }
397
391
 
398
392
 
399
- /*************************************************
400
- * Rack-specific settings
401
- *************************************************/
402
-
403
- static const char *
404
- cmd_rack_base_uri(cmd_parms *cmd, void *pcfg, const char *arg) {
405
- DirConfig *config = (DirConfig *) pcfg;
406
- if (strlen(arg) == 0) {
407
- return "RackBaseURI may not be set to the empty string";
408
- } else if (arg[0] != '/') {
409
- return "RackBaseURI must start with a slash (/)";
410
- } else if (strlen(arg) > 1 && arg[strlen(arg) - 1] == '/') {
411
- return "RackBaseURI must not end with a slash (/)";
412
- } else {
413
- config->rackBaseURIs.insert(arg);
414
- return NULL;
415
- }
416
- }
417
-
418
-
419
- /*************************************************
420
- * WSGI-specific settings
421
- *************************************************/
422
-
423
- // none
424
-
425
-
426
393
  /*************************************************
427
394
  * Obsolete settings
428
395
  *************************************************/
@@ -624,6 +591,11 @@ const command_rec passenger_commands[] = {
624
591
  NULL,
625
592
  RSRC_CONF,
626
593
  "The spawn method to use."),
594
+ AP_INIT_TAKE1("PassengerBaseURI",
595
+ (Take1Func) cmd_passenger_base_uri,
596
+ NULL,
597
+ OR_OPTIONS | ACCESS_CONF | RSRC_CONF,
598
+ "Declare the given base URI as belonging to an application."),
627
599
  AP_INIT_TAKE1("PassengerMaxPreloaderIdleTime",
628
600
  (Take1Func) cmd_passenger_max_preloader_idle_time,
629
601
  NULL,
@@ -713,11 +685,6 @@ const command_rec passenger_commands[] = {
713
685
  "The number of threads that Phusion Passenger should spawn per application."),
714
686
 
715
687
  // Rails-specific settings.
716
- AP_INIT_TAKE1("RailsBaseURI",
717
- (Take1Func) cmd_rails_base_uri,
718
- NULL,
719
- OR_OPTIONS | ACCESS_CONF | RSRC_CONF,
720
- "Reserve the given URI to a Rails application."),
721
688
  AP_INIT_TAKE1("RailsEnv",
722
689
  (Take1Func) cmd_environment,
723
690
  NULL,
@@ -725,11 +692,6 @@ const command_rec passenger_commands[] = {
725
692
  "The environment under which a Rails app must run."),
726
693
 
727
694
  // Rack-specific settings.
728
- AP_INIT_TAKE1("RackBaseURI",
729
- (Take1Func) cmd_rack_base_uri,
730
- NULL,
731
- OR_OPTIONS | ACCESS_CONF | RSRC_CONF,
732
- "Reserve the given URI to a Rack application."),
733
695
  AP_INIT_TAKE1("RackEnv",
734
696
  (Take1Func) cmd_environment,
735
697
  NULL,
@@ -784,6 +746,16 @@ const command_rec passenger_commands[] = {
784
746
  NULL,
785
747
  RSRC_CONF,
786
748
  "Deprecated option."),
749
+ AP_INIT_TAKE1("RailsBaseURI",
750
+ (Take1Func) cmd_passenger_base_uri,
751
+ NULL,
752
+ OR_OPTIONS | ACCESS_CONF | RSRC_CONF,
753
+ "Deprecated option."),
754
+ AP_INIT_TAKE1("RackBaseURI",
755
+ (Take1Func) cmd_passenger_base_uri,
756
+ NULL,
757
+ OR_OPTIONS | ACCESS_CONF | RSRC_CONF,
758
+ "Deprecated option."),
787
759
 
788
760
  // Obsolete options.
789
761
  AP_INIT_TAKE1("RailsSpawnServer",
@@ -66,8 +66,7 @@ struct DirConfig {
66
66
 
67
67
  Threeway enabled;
68
68
 
69
- std::set<std::string> railsBaseURIs;
70
- std::set<std::string> rackBaseURIs;
69
+ std::set<std::string> baseURIs;
71
70
 
72
71
  /** The Ruby interpreter to use. */
73
72
  const char *ruby;
@@ -189,18 +188,6 @@ struct DirConfig {
189
188
  return enabled != DISABLED;
190
189
  }
191
190
 
192
- string getAppRoot(const StaticString &documentRoot) const {
193
- if (appRoot == NULL) {
194
- if (resolveSymlinksInDocRoot == DirConfig::ENABLED) {
195
- return extractDirName(resolveSymlink(documentRoot));
196
- } else {
197
- return extractDirName(documentRoot);
198
- }
199
- } else {
200
- return appRoot;
201
- }
202
- }
203
-
204
191
  StaticString getUser() const {
205
192
  if (user != NULL) {
206
193
  return user;
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010-2013 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -47,6 +47,17 @@ using namespace std;
47
47
  using namespace oxt;
48
48
  using namespace Passenger::ApplicationPool2;
49
49
 
50
+
51
+ class DocumentRootDeterminationError: public oxt::tracable_exception {
52
+ private:
53
+ string msg;
54
+ public:
55
+ DocumentRootDeterminationError(const string &message): msg(message) {}
56
+ virtual ~DocumentRootDeterminationError() throw() {}
57
+ virtual const char *what() const throw() { return msg.c_str(); }
58
+ };
59
+
60
+
50
61
  /**
51
62
  * Utility class for determining URI-to-application directory mappings.
52
63
  * Given a URI, it will determine whether that URI belongs to a Phusion
@@ -61,11 +72,94 @@ private:
61
72
  DirConfig *config;
62
73
  request_rec *r;
63
74
  CachedFileStat *cstat;
64
- unsigned int throttleRate;
65
- bool baseURIKnown;
66
75
  const char *baseURI;
67
- PassengerAppType appType;
76
+ string publicDir;
77
+ string appRoot;
78
+ unsigned int throttleRate;
79
+ PassengerAppType appType: 7;
80
+ bool autoDetectionDone: 1;
68
81
 
82
+ const char *findBaseURI() const {
83
+ set<string>::const_iterator it, end = config->baseURIs.end();
84
+ const char *uri = r->uri;
85
+ size_t uri_len = strlen(uri);
86
+
87
+ for (it = config->baseURIs.begin(); it != end; it++) {
88
+ const string &base = *it;
89
+
90
+ if (base == "/") {
91
+ /* Ignore 'PassengerBaseURI /' options. Users usually
92
+ * specify this out of ignorance.
93
+ */
94
+ continue;
95
+ }
96
+
97
+ if ( base == "/"
98
+ || ( uri_len == base.size() && memcmp(uri, base.c_str(), uri_len) == 0 )
99
+ || ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0
100
+ && uri[base.size()] == '/' )
101
+ ) {
102
+ return base.c_str();
103
+ }
104
+ }
105
+ return NULL;
106
+ }
107
+
108
+ /**
109
+ * @throws FileSystemException An error occured while examening the filesystem.
110
+ * @throws DocumentRootDeterminationError Unable to query the location of the document root.
111
+ * @throws TimeRetrievalException
112
+ * @throws boost::thread_interrupted
113
+ */
114
+ void autoDetect() {
115
+ if (autoDetectionDone) {
116
+ return;
117
+ }
118
+
119
+ TRACE_POINT();
120
+
121
+ /* Determine the document root without trailing slashes. */
122
+ StaticString docRoot = ap_document_root(r);
123
+ if (docRoot.size() > 1 && docRoot[docRoot.size() - 1] == '/') {
124
+ docRoot = docRoot.substr(0, docRoot.size() - 1);
125
+ }
126
+ if (docRoot.empty()) {
127
+ throw DocumentRootDeterminationError("Cannot determine the document root");
128
+ }
129
+
130
+ /* Find the base URI for this web application, if any. */
131
+ const char *baseURI = findBaseURI();
132
+ if (baseURI != NULL) {
133
+ /* We infer that the 'public' directory of the web application
134
+ * is document root + base URI.
135
+ */
136
+ publicDir = docRoot + baseURI;
137
+ } else {
138
+ /* No base URI directives are applicable for this request. So assume that
139
+ * the web application's public directory is the document root.
140
+ */
141
+ publicDir = docRoot;
142
+ }
143
+
144
+ UPDATE_TRACE_POINT();
145
+ AppTypeDetector detector(cstat, throttleRate);
146
+ PassengerAppType appType;
147
+ string appRoot;
148
+ if (config->appRoot == NULL) {
149
+ appType = detector.checkDocumentRoot(publicDir,
150
+ baseURI != NULL || config->resolveSymlinksInDocRoot == DirConfig::ENABLED,
151
+ &appRoot);
152
+ } else {
153
+ appRoot = config->appRoot;
154
+ appType = detector.checkAppRoot(appRoot);
155
+ }
156
+
157
+ this->appRoot = appRoot;
158
+ this->baseURI = baseURI;
159
+ this->appType = appType;
160
+ autoDetectionDone = true;
161
+ }
162
+
69
163
  public:
70
164
  /**
71
165
  * Create a new DirectoryMapper object.
@@ -82,131 +176,66 @@ public:
82
176
  this->cstat = cstat;
83
177
  this->throttleRate = throttleRate;
84
178
  appType = PAT_NONE;
85
- baseURIKnown = false;
86
179
  baseURI = NULL;
180
+ autoDetectionDone = false;
87
181
  }
88
182
 
89
183
  /**
90
- * Determine whether the given HTTP request falls under one of the specified
91
- * RailsBaseURIs or RackBaseURIs. If yes, then the first matching base URI will
92
- * be returned.
93
- *
94
- * If the document root seems to be a valid application 'public' folder, then this
95
- * method will return "/".
96
- *
184
+ * Determines whether the given HTTP request falls under one of the specified
185
+ * PassengerBaseURIs. If yes, then the first matching base URI will be returned.
97
186
  * Otherwise, NULL will be returned.
98
187
  *
99
- * @throws FileSystemException This method might also examine the filesystem in
100
- * order to detect the application's type. During that process, a
101
- * FileSystemException might be thrown.
188
+ * @throws FileSystemException An error occured while examening the filesystem.
189
+ * @throws DocumentRoot
190
+ * @throws TimeRetrievalException
191
+ * @throws boost::thread_interrupted
102
192
  * @warning The return value may only be used as long as <tt>config</tt>
103
193
  * hasn't been destroyed.
104
194
  */
105
195
  const char *getBaseURI() {
106
196
  TRACE_POINT();
107
- if (baseURIKnown) {
108
- return baseURI;
109
- }
110
-
111
- set<string>::const_iterator it;
112
- const char *uri = r->uri;
113
- size_t uri_len = strlen(uri);
114
-
115
- if (uri_len == 0 || uri[0] != '/') {
116
- baseURIKnown = true;
117
- return NULL;
118
- }
119
-
120
- UPDATE_TRACE_POINT();
121
- for (it = config->railsBaseURIs.begin(); it != config->railsBaseURIs.end(); it++) {
122
- const string &base(*it);
123
- if ( base == "/"
124
- || ( uri_len == base.size() && memcmp(uri, base.c_str(), uri_len) == 0 )
125
- || ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0
126
- && uri[base.size()] == '/' )
127
- ) {
128
- baseURIKnown = true;
129
- baseURI = base.c_str();
130
- appType = PAT_CLASSIC_RAILS;
131
- return baseURI;
132
- }
133
- }
134
-
135
- UPDATE_TRACE_POINT();
136
- for (it = config->rackBaseURIs.begin(); it != config->rackBaseURIs.end(); it++) {
137
- const string &base(*it);
138
- if ( base == "/"
139
- || ( uri_len == base.size() && memcmp(uri, base.c_str(), uri_len) == 0 )
140
- || ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0
141
- && uri[base.size()] == '/' )
142
- ) {
143
- baseURIKnown = true;
144
- baseURI = base.c_str();
145
- appType = PAT_RACK;
146
- return baseURI;
147
- }
148
- }
149
-
150
- UPDATE_TRACE_POINT();
151
- baseURIKnown = true;
152
- AppTypeDetector detector(cstat, throttleRate);
153
- appType = detector.checkAppRoot(config->getAppRoot(ap_document_root(r)));
154
- if (appType != PAT_NONE) {
155
- baseURI = "/";
156
- } else {
157
- baseURI = NULL;
158
- }
197
+ autoDetect();
159
198
  return baseURI;
160
199
  }
161
200
 
162
201
  /**
163
- * Returns the filename of the 'public' directory of the Rails/Rack application
202
+ * Returns the filename of the 'public' directory of the application
164
203
  * that's associated with the HTTP request.
165
204
  *
166
- * Returns an empty string if the document root of the HTTP request
167
- * cannot be determined, or if it isn't a valid folder.
168
- *
169
205
  * @throws FileSystemException An error occured while examening the filesystem.
206
+ * @throws DocumentRootDeterminationError Unable to query the location of the document root.
207
+ * @throws TimeRetrievalException
208
+ * @throws boost::thread_interrupted
170
209
  */
171
210
  string getPublicDirectory() {
172
- if (!baseURIKnown) {
173
- getBaseURI();
174
- }
175
- if (baseURI == NULL) {
176
- return "";
177
- }
178
-
179
- const char *docRoot = ap_document_root(r);
180
- size_t len = strlen(docRoot);
181
- if (len > 0) {
182
- string path;
183
- if (docRoot[len - 1] == '/') {
184
- path.assign(docRoot, len - 1);
185
- } else {
186
- path.assign(docRoot, len);
187
- }
188
- if (strcmp(baseURI, "/") != 0) {
189
- /* Application is deployed in a sub-URI.
190
- * This is probably a symlink, so let's resolve it.
191
- */
192
- path.append(baseURI);
193
- path = resolveSymlink(path);
194
- }
195
- return path;
196
- } else {
197
- return "";
198
- }
211
+ autoDetect();
212
+ return publicDir;
213
+ }
214
+
215
+ /**
216
+ * Returns the application root, or the empty string if this request does not
217
+ * belong to an application.
218
+ *
219
+ * @throws FileSystemException An error occured while examening the filesystem.
220
+ * @throws DocumentRootDeterminationError Unable to query the location of the document root.
221
+ * @throws TimeRetrievalException
222
+ * @throws boost::thread_interrupted
223
+ */
224
+ string getAppRoot() {
225
+ autoDetect();
226
+ return appRoot;
199
227
  }
200
228
 
201
229
  /**
202
230
  * Returns the application type that's associated with the HTTP request.
203
231
  *
204
232
  * @throws FileSystemException An error occured while examening the filesystem.
233
+ * @throws DocumentRootDeterminationError Unable to query the location of the document root.
234
+ * @throws TimeRetrievalException
235
+ * @throws boost::thread_interrupted
205
236
  */
206
237
  PassengerAppType getApplicationType() {
207
- if (!baseURIKnown) {
208
- getBaseURI();
209
- }
238
+ autoDetect();
210
239
  return appType;
211
240
  }
212
241
 
@@ -215,11 +244,12 @@ public:
215
244
  * with the HTTP request.
216
245
  *
217
246
  * @throws FileSystemException An error occured while examening the filesystem.
247
+ * @throws DocumentRootDeterminationError Unable to query the location of the document root.
248
+ * @throws TimeRetrievalException
249
+ * @throws boost::thread_interrupted
218
250
  */
219
251
  const char *getApplicationTypeName() {
220
- if (!baseURIKnown) {
221
- getBaseURI();
222
- }
252
+ autoDetect();
223
253
  return getAppTypeName(appType);
224
254
  }
225
255
  };