passenger 4.0.41 → 4.0.42

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 (136) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.travis.yml +3 -3
  5. data/CHANGELOG +26 -0
  6. data/build/agents.rb +1 -1
  7. data/build/apache2.rb +3 -0
  8. data/build/debian.rb +1 -1
  9. data/build/integration_tests.rb +4 -4
  10. data/build/nginx.rb +3 -0
  11. data/build/packaging.rb +3 -5
  12. data/build/preprocessor.rb +2 -1
  13. data/build/ruby_extension.rb +5 -5
  14. data/build/test_basics.rb +2 -1
  15. data/debian.template/control.template +9 -4
  16. data/debian.template/rules.template +16 -4
  17. data/dev/run_travis.sh +32 -8
  18. data/doc/Users guide Apache.txt +55 -10
  19. data/doc/Users guide Nginx.txt +10 -8
  20. data/doc/Users guide Standalone.txt +5 -2
  21. data/doc/users_guide_snippets/installation.txt +14 -0
  22. data/ext/common/ApplicationPool2/Process.h +8 -0
  23. data/ext/common/ApplicationPool2/Spawner.h +51 -1
  24. data/ext/common/Constants.h +1 -1
  25. data/ext/common/Utils/Curl.h +4 -0
  26. data/ext/common/agents/HelperAgent/RequestHandler.h +14 -2
  27. data/ext/common/agents/LoggingAgent/LoggingServer.h +4 -4
  28. data/ext/common/agents/LoggingAgent/RemoteSender.h +66 -5
  29. data/ext/nginx/StaticContentHandler.c +0 -7
  30. data/lib/phusion_passenger.rb +3 -3
  31. data/lib/phusion_passenger/config/about_command.rb +0 -4
  32. data/lib/phusion_passenger/config/build_native_support_command.rb +78 -0
  33. data/lib/phusion_passenger/config/detach_process_command.rb +0 -4
  34. data/lib/phusion_passenger/config/main.rb +12 -5
  35. data/lib/phusion_passenger/config/restart_app_command.rb +0 -4
  36. data/lib/phusion_passenger/config/validate_install_command.rb +0 -4
  37. data/lib/phusion_passenger/platform_info/compiler.rb +58 -41
  38. data/lib/phusion_passenger/platform_info/cxx_portability.rb +5 -0
  39. data/lib/phusion_passenger/standalone/command.rb +29 -10
  40. data/lib/phusion_passenger/standalone/help_command.rb +2 -2
  41. data/lib/phusion_passenger/standalone/start_command.rb +5 -1
  42. data/lib/phusion_passenger/utils/tee_input.rb +1 -0
  43. data/resources/mime.types +1 -1
  44. data/resources/oss-binaries.phusionpassenger.com.crt +124 -0
  45. data/resources/templates/apache2/deployment_example.txt.erb +2 -0
  46. data/resources/templates/standalone/config.erb +3 -1
  47. data/resources/templates/undisclosed_error.html.template +38 -1
  48. data/resources/union_station_gateway.crt +21 -0
  49. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +34 -0
  50. data/test/cxx/RequestHandlerTest.cpp +10 -3
  51. data/test/cxx/TemplateTest.cpp +1 -1
  52. data/test/integration_tests/apache2_tests.rb +90 -106
  53. data/test/integration_tests/nginx_tests.rb +2 -0
  54. data/test/stub/rack/config.ru +7 -14
  55. data/test/stub/rack/library.rb +16 -0
  56. data/test/support/test_helper.rb +0 -3
  57. metadata +4 -80
  58. metadata.gz.asc +7 -7
  59. data/test/stub/rails2.3-mycook/Rakefile +0 -10
  60. data/test/stub/rails2.3-mycook/app/controllers/application_controller.rb +0 -12
  61. data/test/stub/rails2.3-mycook/app/controllers/recipes_controller.rb +0 -5
  62. data/test/stub/rails2.3-mycook/app/controllers/uploads_controller.rb +0 -15
  63. data/test/stub/rails2.3-mycook/app/controllers/welcome_controller.rb +0 -71
  64. data/test/stub/rails2.3-mycook/app/helpers/application_helper.rb +0 -3
  65. data/test/stub/rails2.3-mycook/app/helpers/recipes_helper.rb +0 -2
  66. data/test/stub/rails2.3-mycook/app/helpers/test_helper.rb +0 -2
  67. data/test/stub/rails2.3-mycook/app/helpers/uploads_helper.rb +0 -2
  68. data/test/stub/rails2.3-mycook/app/helpers/welcome_helper.rb +0 -2
  69. data/test/stub/rails2.3-mycook/app/views/layouts/default.rhtml +0 -26
  70. data/test/stub/rails2.3-mycook/app/views/recipes/create.rhtml +0 -13
  71. data/test/stub/rails2.3-mycook/app/views/recipes/index.rhtml +0 -3
  72. data/test/stub/rails2.3-mycook/app/views/recipes/new.rhtml +0 -8
  73. data/test/stub/rails2.3-mycook/app/views/uploads/index.rhtml +0 -1
  74. data/test/stub/rails2.3-mycook/app/views/uploads/new.html.erb +0 -8
  75. data/test/stub/rails2.3-mycook/app/views/welcome/cached.rhtml +0 -1
  76. data/test/stub/rails2.3-mycook/app/views/welcome/index.rhtml +0 -20
  77. data/test/stub/rails2.3-mycook/config/boot.rb +0 -110
  78. data/test/stub/rails2.3-mycook/config/database.yml +0 -19
  79. data/test/stub/rails2.3-mycook/config/environment.rb +0 -61
  80. data/test/stub/rails2.3-mycook/config/environments/development.rb +0 -18
  81. data/test/stub/rails2.3-mycook/config/environments/production.rb +0 -19
  82. data/test/stub/rails2.3-mycook/config/initializers/inflections.rb +0 -10
  83. data/test/stub/rails2.3-mycook/config/initializers/mime_types.rb +0 -5
  84. data/test/stub/rails2.3-mycook/config/routes.rb +0 -38
  85. data/test/stub/rails2.3-mycook/log/useless.txt +0 -1
  86. data/test/stub/rails2.3-mycook/public/.htaccess +0 -42
  87. data/test/stub/rails2.3-mycook/public/404.html +0 -30
  88. data/test/stub/rails2.3-mycook/public/422.html +0 -30
  89. data/test/stub/rails2.3-mycook/public/500.html +0 -30
  90. data/test/stub/rails2.3-mycook/public/dispatch.cgi +0 -10
  91. data/test/stub/rails2.3-mycook/public/dispatch.fcgi +0 -24
  92. data/test/stub/rails2.3-mycook/public/dispatch.rb +0 -10
  93. data/test/stub/rails2.3-mycook/public/favicon.ico +0 -0
  94. data/test/stub/rails2.3-mycook/public/images/angrywizard.gif +0 -0
  95. data/test/stub/rails2.3-mycook/public/images/cookbook.gif +0 -0
  96. data/test/stub/rails2.3-mycook/public/images/header.png +0 -0
  97. data/test/stub/rails2.3-mycook/public/images/rails.png +0 -0
  98. data/test/stub/rails2.3-mycook/public/robots.txt +0 -5
  99. data/test/stub/rails2.3-mycook/public/uploads.html +0 -26
  100. data/test/stub/rails2.3-mycook/public/uploads/.gitignore +0 -0
  101. data/test/stub/rails2.3-mycook/public/welcome/cached.html +0 -26
  102. data/test/stub/rails2.3-mycook/script/about +0 -3
  103. data/test/stub/rails2.3-mycook/script/console +0 -3
  104. data/test/stub/rails2.3-mycook/script/dbconsole +0 -3
  105. data/test/stub/rails2.3-mycook/script/destroy +0 -3
  106. data/test/stub/rails2.3-mycook/script/generate +0 -3
  107. data/test/stub/rails2.3-mycook/script/performance/benchmarker +0 -3
  108. data/test/stub/rails2.3-mycook/script/performance/profiler +0 -3
  109. data/test/stub/rails2.3-mycook/script/performance/request +0 -3
  110. data/test/stub/rails2.3-mycook/script/plugin +0 -3
  111. data/test/stub/rails2.3-mycook/script/process/inspector +0 -3
  112. data/test/stub/rails2.3-mycook/script/process/reaper +0 -3
  113. data/test/stub/rails2.3-mycook/script/process/spawner +0 -3
  114. data/test/stub/rails2.3-mycook/script/runner +0 -3
  115. data/test/stub/rails2.3-mycook/script/server +0 -3
  116. data/test/stub/rails2.3-mycook/sites/some.site/public/uploads.html +0 -26
  117. data/test/stub/rails2.3-mycook/sites/some.site/public/welcome/cached.html +0 -26
  118. data/test/stub/rails2.3-mycook/tmp/cache/useless.txt +0 -1
  119. data/test/stub/rails2.3-mycook/tmp/pids/useless.txt +0 -1
  120. data/test/stub/rails2.3-mycook/tmp/sessions/useless.txt +0 -1
  121. data/test/stub/rails2.3-mycook/tmp/sockets/useless.txt +0 -1
  122. data/test/stub/vendor_rails/minimal/README +0 -1
  123. data/test/stub/vendor_rails/minimal/actionmailer/lib/action_mailer.rb +0 -0
  124. data/test/stub/vendor_rails/minimal/actionpack/lib/action_controller.rb +0 -22
  125. data/test/stub/vendor_rails/minimal/actionpack/lib/action_pack.rb +0 -0
  126. data/test/stub/vendor_rails/minimal/actionpack/lib/action_view.rb +0 -0
  127. data/test/stub/vendor_rails/minimal/activerecord/lib/active_record.rb +0 -7
  128. data/test/stub/vendor_rails/minimal/activeresource/lib/active_resource.rb +0 -0
  129. data/test/stub/vendor_rails/minimal/activesupport/lib/active_support.rb +0 -17
  130. data/test/stub/vendor_rails/minimal/activesupport/lib/active_support/whiny_nil.rb +0 -0
  131. data/test/stub/vendor_rails/minimal/railties/lib/dispatcher.rb +0 -0
  132. data/test/stub/vendor_rails/minimal/railties/lib/initializer.rb +0 -57
  133. data/test/stub/vendor_rails/minimal/railties/lib/ruby_version_check.rb +0 -1
  134. data/test/stub/zsfa/header.png +0 -0
  135. data/test/stub/zsfa/index.html +0 -14
  136. data/test/stub/zsfa/zsfa.png +0 -0
@@ -998,7 +998,7 @@ Nginx's response buffering works differently from Phusion Passenger's. Nginx's b
998
998
 
999
999
  How does response buffering - whether it's done by Nginx or by Phusion Passenger - exactly protect against slow clients?
1000
1000
  Consider an HTTP client that's on a dial-up modem link, and your
1001
- application process generates a 2 MB response. If the response is buffered
1001
+ application process generates a 2 MB response. If the response is not buffered
1002
1002
  then your application process will be blocked until the entire 2 MB has been
1003
1003
  sent out to the HTTP client. This disallows your application process to do any useful
1004
1004
  work in the mean time. By buffering responses, Phusion Passenger or Nginx will read
@@ -1216,11 +1216,13 @@ In each place, it may be specified at most once. The default value is 'on'.
1216
1216
  ==== passenger_friendly_error_pages <on|off> ====
1217
1217
  Phusion Passenger can display friendly error pages whenever an application fails
1218
1218
  to start. This friendly error page presents the startup error message, some
1219
- suggestions for solving the problem, and a backtrace. This feature is very useful
1220
- during application development and useful for less experienced system administrators,
1221
- but the page might reveal potentially sensitive information, depending on the
1222
- application. Experienced system administrators who are using Phusion Passenger
1223
- on serious production servers should consider turning this feature off.
1219
+ suggestions for solving the problem, a backtrace and a dump of the environment variables.
1220
+ This feature is very useful during application development and useful for less experienced
1221
+ system administrators, but the page might reveal potentially sensitive information,
1222
+ depending on the application. For this reason, friendly error pages are turned off by default when
1223
+ <<PassengerAppEnv,passenger_app_env (and its aliases such as rails_env and rack_env)>>
1224
+ is set to 'staging' or 'production', but enabled by default otherwise. You can use
1225
+ this option to explicitly enable or disable this feature.
1224
1226
 
1225
1227
  This option may occur in the following places:
1226
1228
 
@@ -1229,7 +1231,7 @@ This option may occur in the following places:
1229
1231
  * In a 'location' configuration block.
1230
1232
  * In an 'if' configuration scope.
1231
1233
 
1232
- In each place, it may be specified at most once. The default value is 'on'.
1234
+ In each place, it may be specified at most once. The default value depends on <<PassengerAppEnv,passenger_app_env (and its aliases such as rails_env and rack_env)>>, as documented above.
1233
1235
 
1234
1236
  === Resource control and optimization options ===
1235
1237
  [[PassengerMaxPoolSize]]
@@ -1694,7 +1696,7 @@ passenger_pre_start http://myblog.com/; # <----- WRONG! Missing "/store" part
1694
1696
  Application processes started with passenger_pre_start are
1695
1697
  also subject to the idle timeout rules as specified by
1696
1698
  <<PassengerPoolIdleTime,passenger_pool_idle_time>>! That means that by default,
1697
- the pre-started application processes for foo.com are bar.com are shut down
1699
+ the pre-started application processes for foo.com and bar.com are shut down
1698
1700
  after a few minutes of inactivity. If you don't want that to happen, then
1699
1701
  you should combine passenger_pre_start with
1700
1702
  <<PassengerMinInstances,passenger_min_instances>>, like this:
@@ -45,8 +45,11 @@ Most configuration is done by customizing the arguments passed to the `passenger
45
45
  If you don't want the number of application processes to scale dynamically, then use this option to set it to a value equal to `--max-pool-size`.
46
46
  `--spawn-method NAME`::
47
47
  When set to "smart" (the default), Phusion Passenger preloads your app and utilizes copy-on-write in order to save memory. You can disable this by setting this option to "direct". Preloading is only supported for Ruby apps. For apps written in other languages, it is as if "direct" is always used.
48
- `--no-friendly-error-pages`::
49
- If your app fails to start, Phusion Passenger will tell you by showing a friendly error page in the browser. This option disables it.
48
+ `--friendly-error-pages`::
49
+ Phusion Passenger can display a friendly error page whenever your application fails to start. The friendly error page presents the startup error message, some suggestions for solving the problem, a backtrace, and a dump of the environment variables. This feature is very useful during application development and useful for less experienced system administrators, but the page might reveal potentially sensitive information, depending on the application. For this reason, friendly error pages are turned off by default when `--environment` is set to 'staging' or 'production', but enabled by default otherwise.
50
+ +
51
+ You can use `--friendly-error-pages` and `--no-friendly-error-pages` to explicitly enable or disable this feature, respectively.
52
+
50
53
  `--ssl`::
51
54
  Enables SSL support. If this is set, you must also set `--ssl-certificate` and `--ssl-certificate-key` to the SSL certificate and key files, respectively.
52
55
  `--ssl-port`::
@@ -153,6 +153,13 @@ ifdef::apache[]
153
153
  --------------------------------------------------------------
154
154
  sudo apt-get install libapache2-mod-passenger
155
155
  --------------------------------------------------------------
156
+ +
157
+ 3. Enable the Phusion Passenger Apache module and restart Apache:
158
+ +
159
+ --------------------------------------------------------------
160
+ sudo a2enmod passenger
161
+ sudo service apache2 restart
162
+ --------------------------------------------------------------
156
163
  endif::[]
157
164
  ifdef::standalone[]
158
165
  2. Install the package:
@@ -183,6 +190,13 @@ ifdef::apache[]
183
190
  --------------------------------------------------------------
184
191
  sudo apt-get install libapache2-mod-passenger-enterprise
185
192
  --------------------------------------------------------------
193
+ +
194
+ 4. Enable the Phusion Passenger Apache module and restart Apache:
195
+ +
196
+ --------------------------------------------------------------
197
+ sudo a2enmod passenger
198
+ sudo service apache2 restart
199
+ --------------------------------------------------------------
186
200
  endif::[]
187
201
  ifdef::standalone[]
188
202
  --------------------------------------------------------------
@@ -224,6 +224,11 @@ public:
224
224
  FileDescriptor adminSocket;
225
225
  /** The sockets that this Process listens on for connections. */
226
226
  SocketListPtr sockets;
227
+ /** The code revision of the application, inferred through various means.
228
+ * See Spawner::prepareSpawn() to learn how this is determined.
229
+ * May be an empty string.
230
+ */
231
+ string codeRevision;
227
232
  /** Time at which the Spawner that created this process was created.
228
233
  * Microseconds resolution. */
229
234
  unsigned long long spawnerCreationTime;
@@ -642,6 +647,9 @@ public:
642
647
  stream << "<spawn_end_time>" << spawnEndTime << "</spawn_end_time>";
643
648
  stream << "<last_used>" << lastUsed << "</last_used>";
644
649
  stream << "<uptime>" << uptime() << "</uptime>";
650
+ if (!codeRevision.empty()) {
651
+ stream << "<code_revision>" << codeRevision << "</code_revision>";
652
+ }
645
653
  switch (lifeStatus) {
646
654
  case ALIVE:
647
655
  stream << "<life_status>ALIVE</life_status>";
@@ -318,6 +318,9 @@ protected:
318
318
  gid_t gid;
319
319
  int ngroups;
320
320
  shared_array<gid_t> gidset;
321
+
322
+ // Other information
323
+ string codeRevision;
321
324
  };
322
325
 
323
326
  /**
@@ -526,11 +529,14 @@ private:
526
529
  details);
527
530
  }
528
531
 
529
- return boost::make_shared<Process>(details.libev, details.pid,
532
+ ProcessPtr process = boost::make_shared<Process>(
533
+ details.libev, details.pid,
530
534
  details.gupid, details.connectPassword,
531
535
  details.adminSocket, details.errorPipe,
532
536
  sockets, creationTime, details.spawnStartTime,
533
537
  config);
538
+ process->codeRevision = details.preparation->codeRevision;
539
+ return process;
534
540
  }
535
541
 
536
542
  protected:
@@ -799,6 +805,7 @@ protected:
799
805
  prepareChroot(info, options);
800
806
  prepareUserSwitching(info, options);
801
807
  prepareSwitchingWorkingDirectory(info, options);
808
+ inferApplicationInfo(info);
802
809
  return info;
803
810
  }
804
811
 
@@ -980,6 +987,49 @@ protected:
980
987
  assert(info.appRootPathsInsideChroot.back() == info.appRootInsideChroot);
981
988
  }
982
989
 
990
+ void inferApplicationInfo(SpawnPreparationInfo &info) const {
991
+ info.codeRevision = readFromRevisionFile(info);
992
+ if (info.codeRevision.empty()) {
993
+ info.codeRevision = inferCodeRevisionFromCapistranoSymlink(info);
994
+ }
995
+ }
996
+
997
+ string readFromRevisionFile(const SpawnPreparationInfo &info) const {
998
+ string filename = info.appRoot + "/REVISION";
999
+ try {
1000
+ if (fileExists(filename)) {
1001
+ return strip(readAll(filename));
1002
+ }
1003
+ } catch (const SystemException &e) {
1004
+ P_WARN("Cannot access " << filename << ": " << e.what());
1005
+ }
1006
+ return string();
1007
+ }
1008
+
1009
+ string inferCodeRevisionFromCapistranoSymlink(const SpawnPreparationInfo &info) const {
1010
+ if (extractBaseName(info.appRoot) == "current") {
1011
+ char buf[PATH_MAX + 1];
1012
+ ssize_t ret;
1013
+
1014
+ do {
1015
+ ret = readlink(info.appRoot.c_str(), buf, PATH_MAX);
1016
+ } while (ret == -1 && errno == EINTR);
1017
+ if (ret == -1) {
1018
+ if (errno == EINVAL) {
1019
+ return string();
1020
+ } else {
1021
+ int e = errno;
1022
+ P_WARN("Cannot read symlink " << info.appRoot << ": " << strerror(e));
1023
+ }
1024
+ }
1025
+
1026
+ buf[ret] = '\0';
1027
+ return extractBaseName(buf);
1028
+ } else {
1029
+ return string();
1030
+ }
1031
+ }
1032
+
983
1033
  bool shouldLoadShellEnvvars(const Options &options, const SpawnPreparationInfo &preparation) const {
984
1034
  if (options.loadShellEnvvars) {
985
1035
  string shellName = extractBaseName(preparation.shell);
@@ -88,7 +88,7 @@
88
88
 
89
89
  #define NGINX_DOC_URL "http://www.modrails.com/documentation/Users%20guide%20Nginx.html"
90
90
 
91
- #define PASSENGER_VERSION "4.0.41"
91
+ #define PASSENGER_VERSION "4.0.42"
92
92
 
93
93
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
94
94
 
@@ -59,6 +59,10 @@ namespace Passenger {
59
59
  using namespace std;
60
60
  using namespace boost;
61
61
 
62
+ #ifndef CURLINFO_RESPONSE_CODE
63
+ #define CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
64
+ #endif
65
+
62
66
  struct CurlProxyInfo {
63
67
  string hostAndPort;
64
68
  string credentials;
@@ -723,6 +723,12 @@ private:
723
723
  }
724
724
  }
725
725
 
726
+ bool friendlyErrorPagesEnabled(const ClientPtr &client) const {
727
+ bool defaultValue = client->options.environment != "staging"
728
+ && client->options.environment != "production";
729
+ return getBoolOption(client, "PASSENGER_FRIENDLY_ERROR_PAGES", defaultValue);
730
+ }
731
+
726
732
  void writeSimpleResponse(const ClientPtr &client, const StaticString &data, int code = 200) {
727
733
  char header[256], statusBuffer[50];
728
734
  char *pos = header;
@@ -774,7 +780,7 @@ private:
774
780
  string templatesDir = resourceLocator.getResourcesDir() + "/templates";
775
781
  string data;
776
782
 
777
- if (getBoolOption(client, "PASSENGER_FRIENDLY_ERROR_PAGES", true)) {
783
+ if (friendlyErrorPagesEnabled(client)) {
778
784
  try {
779
785
  string cssFile = templatesDir + "/error_layout.css";
780
786
  string errorLayoutFile = templatesDir + "/error_layout.html.template";
@@ -819,7 +825,13 @@ private:
819
825
  }
820
826
  } else {
821
827
  try {
822
- data = readAll(templatesDir + "/undisclosed_error.html.template");
828
+ StringMap<StaticString> params;
829
+ params.set("PROGRAM_NAME", PROGRAM_NAME);
830
+ params.set("NGINX_DOC_URL", NGINX_DOC_URL);
831
+ params.set("APACHE2_DOC_URL", APACHE2_DOC_URL);
832
+ params.set("STANDALONE_DOC_URL", STANDALONE_DOC_URL);
833
+ data = Template::apply(readAll(templatesDir + "/undisclosed_error.html.template"),
834
+ params);
823
835
  } catch (const SystemException &e2) {
824
836
  P_ERROR("Cannot render an error page: " << e2.what() << "\n" <<
825
837
  e2.backtrace());
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010-2013 Phusion
3
+ * Copyright (c) 2010-2014 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -127,7 +127,7 @@ private:
127
127
 
128
128
  // Default interval at which this sink should be flushed.
129
129
  virtual unsigned int defaultFlushInterval() const {
130
- return 15;
130
+ return 5;
131
131
  }
132
132
 
133
133
  virtual void append(const DataStoreId &dataStoreId,
@@ -228,7 +228,7 @@ private:
228
228
  }
229
229
 
230
230
  virtual unsigned int defaultFlushInterval() const {
231
- return 60;
231
+ return 5;
232
232
  }
233
233
 
234
234
  virtual void append(const DataStoreId &dataStoreId, const StaticString &data) {
@@ -1128,7 +1128,7 @@ public:
1128
1128
  exitTimer(loop),
1129
1129
  dumpFile(options.get("analytics_dump_file", false, "/dev/null"))
1130
1130
  {
1131
- int sinkFlushTimerInterval = options.getInt("analytics_sink_flush_timer_interval", false, 15);
1131
+ int sinkFlushTimerInterval = options.getInt("analytics_sink_flush_timer_interval", false, 5);
1132
1132
  sinkFlushInterval = options.getInt("analytics_sink_flush_interval", false, 0);
1133
1133
  garbageCollectionTimer.set<LoggingServer, &LoggingServer::garbageCollect>(this);
1134
1134
  garbageCollectionTimer.start(GARBAGE_COLLECTION_TIMEOUT, GARBAGE_COLLECTION_TIMEOUT);
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010-2013 Phusion
3
+ * Copyright (c) 2010-2014 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -45,6 +45,7 @@
45
45
  #include <Utils/SystemTime.h>
46
46
  #include <Utils/ScopeGuard.h>
47
47
  #include <Utils/Base64.h>
48
+ #include <Utils/json.h>
48
49
  #include <Utils/Curl.h>
49
50
 
50
51
  namespace Passenger {
@@ -126,6 +127,60 @@ private:
126
127
  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
127
128
  responseBody.clear();
128
129
  }
130
+
131
+ static bool validateResponse(const Json::Value &response) {
132
+ if (response.isObject() && response["status"].isString()) {
133
+ string status = response["status"].asString();
134
+ if (status == "ok") {
135
+ return true;
136
+ } else if (status == "error") {
137
+ return response["message"].isString();
138
+ } else {
139
+ return false;
140
+ }
141
+ } else {
142
+ return false;
143
+ }
144
+ }
145
+
146
+ bool handleSendResponse() {
147
+ Json::Reader reader;
148
+ Json::Value response;
149
+ long httpCode = -1;
150
+
151
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
152
+
153
+ if (!reader.parse(responseBody, response, false) || !validateResponse(response)) {
154
+ P_ERROR("The Union Station gateway server " << ip << " encountered an error "
155
+ "while processing sent analytics data. It sent an invalid response "
156
+ "(parse error: " << reader.getFormattedErrorMessages().c_str() <<
157
+ "; HTTP code: " << httpCode <<
158
+ "; data: \"" << cEscapeString(responseBody) << "\").");
159
+ return false;
160
+ } else if (response["status"].asString() == "ok") {
161
+ if (httpCode == 200) {
162
+ P_DEBUG("The Union Station gateway server " << ip << " accepted the packet.");
163
+ return true;
164
+ } else {
165
+ P_ERROR("The Union Station gateway server " << ip << " encountered an error "
166
+ "while processing sent analytics data. It sent an invalid response "
167
+ "(HTTP code: " << httpCode <<
168
+ "; data: \"" << cEscapeString(responseBody) << "\").");
169
+ return false;
170
+ }
171
+ } else {
172
+ // response == error
173
+ P_ERROR("The Union Station gateway server " << ip << " did not accept the "
174
+ "sent analytics data. Error message: " << response["message"].asString());
175
+ // Return value of true is intentional. See comment for send().
176
+ return true;
177
+ }
178
+ }
179
+
180
+ void handleSendError() {
181
+ P_ERROR("Could not send data to Union Station gateway server " << ip
182
+ << ": " << lastErrorMessage);
183
+ }
129
184
 
130
185
  static size_t curlDataReceived(void *buffer, size_t size, size_t nmemb, void *userData) {
131
186
  Server *self = (Server *) userData;
@@ -193,6 +248,14 @@ private:
193
248
  }
194
249
  }
195
250
 
251
+ /** Returns true if the server is up, false if the server is down.
252
+ * The return value does NOT indicate whether the server accepted the data!
253
+ * Thus, if (for example) the Union Station key is invalid or disabled,
254
+ * but the connection is fine, then this method still returns true.
255
+ * This is because the return value is used to determine whether a different
256
+ * gateway server should be used. If the server is up but rejects the data
257
+ * then we'll want the code to keep sending future packets.
258
+ */
196
259
  bool send(const Item &item) {
197
260
  ScopeGuard guard(boost::bind(&Server::resetConnection, this));
198
261
  prepareRequest(sinkURL);
@@ -245,11 +308,9 @@ private:
245
308
 
246
309
  if (code == CURLE_OK) {
247
310
  guard.clear();
248
- // TODO: check response
249
- return true;
311
+ return handleSendResponse();
250
312
  } else {
251
- P_DEBUG("Could not send data to Union Station gateway server " << ip
252
- << ": " << lastErrorMessage);
313
+ handleSendError();
253
314
  return false;
254
315
  }
255
316
  }
@@ -67,13 +67,6 @@ passenger_static_content_handler(ngx_http_request_t *r, ngx_str_t *filename)
67
67
  return NGX_DECLINED;
68
68
  }
69
69
 
70
- #if (PASSENGER_NGINX_MINOR_VERSION == 8 && PASSENGER_NGINX_MICRO_VERSION < 38) || \
71
- (PASSENGER_NGINX_MINOR_VERSION == 7 && PASSENGER_NGINX_MICRO_VERSION < 66)
72
- if (r->zero_in_uri) {
73
- return NGX_DECLINED;
74
- }
75
- #endif
76
-
77
70
  log = r->connection->log;
78
71
 
79
72
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
@@ -30,10 +30,10 @@ module PhusionPassenger
30
30
 
31
31
  PACKAGE_NAME = 'passenger'
32
32
  # Run 'rake ext/common/Constants.h' after changing this number.
33
- VERSION_STRING = '4.0.41'
33
+ VERSION_STRING = '4.0.42'
34
34
 
35
- PREFERRED_NGINX_VERSION = '1.4.7'
36
- NGINX_SHA256_CHECKSUM = '23b8ff4a76817090678f91b0efbfcef59a93492f6612dc8370c44c1f1ce1b626'
35
+ PREFERRED_NGINX_VERSION = '1.6.0'
36
+ NGINX_SHA256_CHECKSUM = '943ad757a1c3e8b3df2d5c4ddacc508861922e36fa10ea6f8e3a348fc9abfc1a'
37
37
 
38
38
  PREFERRED_PCRE_VERSION = '8.34'
39
39
  PCRE_SHA256_CHECKSUM = '1dd78994c81e44ac41cf30b2a21d4b4cc6d76ccde7fc6e77713ed51d7bddca47'
@@ -28,10 +28,6 @@ module PhusionPassenger
28
28
  module Config
29
29
 
30
30
  class AboutCommand < Command
31
- def self.description
32
- return "Show information about #{PROGRAM_NAME}"
33
- end
34
-
35
31
  def self.help
36
32
  puts "Usage: passenger-config about <SUBCOMMAND>"
37
33
  puts "Show information about #{PROGRAM_NAME}."
@@ -0,0 +1,78 @@
1
+ # Phusion Passenger - https://www.phusionpassenger.com/
2
+ # Copyright (c) 2014 Phusion
3
+ #
4
+ # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+
24
+ require 'optparse'
25
+ PhusionPassenger.require_passenger_lib 'constants'
26
+ PhusionPassenger.require_passenger_lib 'config/command'
27
+
28
+ module PhusionPassenger
29
+ module Config
30
+
31
+ class BuildNativeSupportCommand < Command
32
+ def run
33
+ parse_options
34
+ PhusionPassenger.require_passenger_lib 'native_support'
35
+ end
36
+
37
+ private
38
+ def self.create_option_parser(options)
39
+ PhusionPassenger.require_passenger_lib 'platform_info/ruby'
40
+ OptionParser.new do |opts|
41
+ nl = "\n" + ' ' * 37
42
+ opts.banner = "Usage: passenger-config build-native-support [OPTIONS]\n"
43
+ opts.separator ""
44
+ opts.separator " #{PROGRAM_NAME} utilizes a Ruby native extension, called native_support,"
45
+ opts.separator " for improving Ruby performance. The extension depends on the"
46
+ opts.separator " #{PROGRAM_NAME} version and the Ruby version. Normally, every time you run"
47
+ opts.separator " a #{PROGRAM_NAME} version with a Ruby version that it hasn't encountered"
48
+ opts.separator " before, it will rebuild the native_support library for that Ruby version."
49
+ opts.separator " By running this command, you can force the native_support to be built for"
50
+ opts.separator " the current Ruby interpreter."
51
+ opts.separator ""
52
+ opts.separator " The current Ruby interpreter is:"
53
+ opts.separator " Path: #{PlatformInfo.ruby_command}"
54
+ opts.separator " Version: #{RUBY_VERSION}"
55
+ opts.separator ""
56
+
57
+ opts.separator "Options:"
58
+ opts.on("-h", "--help", "Show this help") do
59
+ options[:help] = true
60
+ end
61
+ end
62
+ end
63
+
64
+ def help
65
+ puts @parser
66
+ end
67
+
68
+ def parse_options
69
+ super
70
+ if @argv.size > 0
71
+ help
72
+ abort
73
+ end
74
+ end
75
+ end
76
+
77
+ end # module Config
78
+ end # module PhusionPassenger