passenger 4.0.48 → 4.0.49

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 (218) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.editorconfig +36 -2
  5. data/.travis.yml +1 -1
  6. data/CHANGELOG +16 -0
  7. data/Rakefile +0 -1
  8. data/build/apache2.rb +4 -4
  9. data/build/common_library.rb +18 -18
  10. data/build/cplusplus_support.rb +2 -2
  11. data/build/documentation.rb +1 -1
  12. data/build/integration_tests.rb +12 -4
  13. data/build/misc.rb +12 -7
  14. data/build/packaging.rb +14 -14
  15. data/build/preprocessor.rb +10 -10
  16. data/build/rake_extensions.rb +11 -11
  17. data/build/ruby_extension.rb +2 -2
  18. data/dev/ci/inituidgid +24 -0
  19. data/dev/ci/run_jenkins.sh +57 -0
  20. data/dev/ci/run_rpm_tests.sh +77 -0
  21. data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
  22. data/doc/Users guide Nginx.txt +2 -2
  23. data/doc/users_guide_snippets/environment_variables.txt +0 -2
  24. data/doc/users_guide_snippets/tips.txt +20 -1
  25. data/ext/apache2/Bucket.cpp +18 -18
  26. data/ext/apache2/Bucket.h +4 -4
  27. data/ext/apache2/Configuration.cpp +7 -7
  28. data/ext/apache2/Configuration.hpp +43 -43
  29. data/ext/apache2/DirectoryMapper.h +5 -5
  30. data/ext/apache2/Hooks.cpp +142 -142
  31. data/ext/apache2/MergeDirConfig.cpp +40 -40
  32. data/ext/common/Account.h +17 -17
  33. data/ext/common/AccountsDatabase.h +9 -9
  34. data/ext/common/AgentsStarter.cpp +2 -2
  35. data/ext/common/AgentsStarter.h +40 -40
  36. data/ext/common/ApplicationPool2/Common.h +10 -6
  37. data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
  38. data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
  39. data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
  40. data/ext/common/ApplicationPool2/Group.h +54 -38
  41. data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
  42. data/ext/common/ApplicationPool2/Options.h +98 -91
  43. data/ext/common/ApplicationPool2/Pool.h +70 -69
  44. data/ext/common/ApplicationPool2/Process.h +21 -21
  45. data/ext/common/ApplicationPool2/Session.h +11 -11
  46. data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
  47. data/ext/common/ApplicationPool2/Socket.h +19 -19
  48. data/ext/common/ApplicationPool2/Spawner.h +64 -72
  49. data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
  50. data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
  51. data/ext/common/BackgroundEventLoop.cpp +1 -1
  52. data/ext/common/BackgroundEventLoop.h +2 -2
  53. data/ext/common/Constants.h +1 -1
  54. data/ext/common/EventedBufferedInput.h +5 -5
  55. data/ext/common/EventedClient.h +51 -51
  56. data/ext/common/EventedMessageServer.h +39 -39
  57. data/ext/common/EventedServer.h +32 -32
  58. data/ext/common/Exceptions.h +23 -23
  59. data/ext/common/FileDescriptor.h +18 -18
  60. data/ext/common/Logging.cpp +1 -1
  61. data/ext/common/MessageClient.h +27 -27
  62. data/ext/common/MessageReadersWriters.h +79 -79
  63. data/ext/common/MessageServer.h +59 -59
  64. data/ext/common/RandomGenerator.h +12 -12
  65. data/ext/common/ResourceLocator.h +8 -8
  66. data/ext/common/SafeLibev.h +54 -25
  67. data/ext/common/ServerInstanceDir.h +31 -31
  68. data/ext/common/StaticString.h +50 -48
  69. data/ext/common/Utils.cpp +73 -78
  70. data/ext/common/Utils.h +6 -6
  71. data/ext/common/Utils/Base64.cpp +3 -3
  72. data/ext/common/Utils/Base64.h +7 -7
  73. data/ext/common/Utils/BlockingQueue.h +9 -9
  74. data/ext/common/Utils/BufferedIO.h +17 -17
  75. data/ext/common/Utils/CachedFileStat.hpp +16 -16
  76. data/ext/common/Utils/Dechunker.h +25 -25
  77. data/ext/common/Utils/FileChangeChecker.h +10 -10
  78. data/ext/common/Utils/MemZeroGuard.h +5 -5
  79. data/ext/common/Utils/MemoryBarrier.h +1 -1
  80. data/ext/common/Utils/MessageIO.h +61 -61
  81. data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
  82. data/ext/common/Utils/ScopeGuard.h +7 -7
  83. data/ext/common/Utils/SpeedMeter.h +1 -1
  84. data/ext/common/Utils/StrIntUtils.cpp +13 -13
  85. data/ext/common/Utils/StrIntUtils.h +3 -3
  86. data/ext/common/Utils/StringScanning.h +5 -5
  87. data/ext/common/Utils/SystemMetricsCollector.h +2 -2
  88. data/ext/common/Utils/SystemTime.h +10 -10
  89. data/ext/common/Utils/Template.h +2 -2
  90. data/ext/common/Utils/Timer.h +6 -6
  91. data/ext/common/Utils/VariantMap.h +29 -29
  92. data/ext/common/agents/Base.cpp +19 -19
  93. data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
  94. data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
  95. data/ext/common/agents/HelperAgent/Main.cpp +44 -43
  96. data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
  97. data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
  98. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
  99. data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
  100. data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
  101. data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
  102. data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
  103. data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
  104. data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
  105. data/ext/common/agents/SpawnPreparer.cpp +4 -4
  106. data/ext/common/agents/TempDirToucher.c +2 -2
  107. data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
  108. data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
  109. data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
  110. data/ext/common/agents/Watchdog/Main.cpp +22 -22
  111. data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
  112. data/ext/libeio/eio.c +1 -1
  113. data/ext/nginx/Configuration.c +30 -30
  114. data/ext/nginx/Configuration.h +1 -1
  115. data/ext/nginx/ContentHandler.c +54 -54
  116. data/ext/nginx/ContentHandler.h +3 -3
  117. data/ext/nginx/StaticContentHandler.c +2 -2
  118. data/ext/nginx/ngx_http_passenger_module.c +21 -21
  119. data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
  120. data/ext/oxt/detail/context.hpp +1 -1
  121. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
  122. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
  123. data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
  124. data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
  125. data/ext/oxt/dynamic_thread_group.hpp +18 -18
  126. data/ext/oxt/implementation.cpp +9 -8
  127. data/ext/oxt/macros.hpp +2 -2
  128. data/ext/oxt/system_calls.cpp +11 -11
  129. data/ext/oxt/system_calls.hpp +13 -13
  130. data/ext/oxt/thread.hpp +22 -14
  131. data/ext/ruby/passenger_native_support.c +55 -55
  132. data/lib/phusion_passenger.rb +24 -24
  133. data/lib/phusion_passenger/common_library.rb +2 -0
  134. data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
  135. data/lib/phusion_passenger/packaging.rb +9 -4
  136. data/lib/phusion_passenger/platform_info/apache.rb +45 -31
  137. data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
  138. data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
  139. data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
  140. data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
  141. data/lib/phusion_passenger/standalone/command.rb +22 -22
  142. data/packaging/rpm/LICENSE.txt +19 -0
  143. data/packaging/rpm/Makefile +13 -0
  144. data/packaging/rpm/README.md +41 -0
  145. data/packaging/rpm/Vagrantfile +38 -0
  146. data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
  147. data/packaging/rpm/build +170 -0
  148. data/packaging/rpm/create_project +41 -0
  149. data/packaging/rpm/git_update +88 -0
  150. data/packaging/rpm/image/Dockerfile +37 -0
  151. data/packaging/rpm/image/Gemfile +3 -0
  152. data/packaging/rpm/image/Gemfile.lock +12 -0
  153. data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
  154. data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
  155. data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
  156. data/packaging/rpm/image/site-defaults.cfg +168 -0
  157. data/packaging/rpm/internal/build_tasks.rb +238 -0
  158. data/packaging/rpm/internal/dummygpg +11 -0
  159. data/packaging/rpm/internal/exec_build +42 -0
  160. data/packaging/rpm/internal/get_distro_arch +14 -0
  161. data/packaging/rpm/internal/get_distro_id +10 -0
  162. data/packaging/rpm/internal/git_update +27 -0
  163. data/packaging/rpm/internal/inituidgid +17 -0
  164. data/packaging/rpm/internal/my_init +344 -0
  165. data/packaging/rpm/internal/python27 +3 -0
  166. data/packaging/rpm/internal/repo_update +46 -0
  167. data/packaging/rpm/internal/setuser +26 -0
  168. data/packaging/rpm/internal/tracking_helper +40 -0
  169. data/packaging/rpm/jenkins_release +99 -0
  170. data/packaging/rpm/lib/build_tasks_support.rb +402 -0
  171. data/packaging/rpm/lib/preprocessor.rb +341 -0
  172. data/packaging/rpm/nginx_spec/404.html +119 -0
  173. data/packaging/rpm/nginx_spec/50x.html +119 -0
  174. data/packaging/rpm/nginx_spec/index.html +116 -0
  175. data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
  176. data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
  177. data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
  178. data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
  179. data/packaging/rpm/nginx_spec/nginx.conf +131 -0
  180. data/packaging/rpm/nginx_spec/nginx.init +144 -0
  181. data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
  182. data/packaging/rpm/nginx_spec/nginx.service +15 -0
  183. data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
  184. data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
  185. data/packaging/rpm/nginx_spec/passenger.conf +9 -0
  186. data/packaging/rpm/nginx_spec/poweredby.png +0 -0
  187. data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
  188. data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
  189. data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
  190. data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
  191. data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
  192. data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
  193. data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
  194. data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
  195. data/packaging/rpm/repo_update +114 -0
  196. data/packaging/rpm/setup-system +60 -0
  197. data/packaging/rpm/shell +10 -0
  198. data/resources/templates/standalone/config.erb +3 -1
  199. data/test/config.json.rpm-automation +1 -1
  200. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
  201. data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
  202. data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
  203. data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
  204. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
  205. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
  206. data/test/cxx/ScgiRequestParserTest.cpp +75 -61
  207. data/test/cxx/UtilsTest.cpp +86 -85
  208. data/test/gdbinit.example +3 -0
  209. data/test/integration_tests/nginx_tests.rb +3 -3
  210. data/test/integration_tests/source_packaging_test.rb +3 -1
  211. data/test/stub/nginx/nginx.conf.erb +8 -1
  212. data/test/support/nginx_controller.rb +7 -7
  213. metadata +62 -17
  214. metadata.gz.asc +7 -7
  215. data/build/rpm.rb +0 -128
  216. data/dev/rpmtool +0 -21
  217. data/dev/test_rpm_packaging.sh +0 -28
  218. data/rpm/get_distro_id.py +0 -4
@@ -156,9 +156,9 @@ Client::onAppInputData(const EventedBufferedInputPtr &source, const StaticString
156
156
  void
157
157
  Client::onAppInputChunk(const char *data, size_t size, void *userData) {
158
158
  Client *client = (Client *) userData;
159
- assert(client != NULL);
160
- assert(client->requestHandler != NULL);
161
- client->requestHandler->onAppInputChunk(client->shared_from_this(), StaticString(data, size));
159
+ if (client != NULL && client->connected()) {
160
+ client->requestHandler->onAppInputChunk(client->shared_from_this(), StaticString(data, size));
161
+ }
162
162
  }
163
163
 
164
164
  void
@@ -278,7 +278,7 @@ main() {
278
278
  FileDescriptor requestSocket(createTcpServer("127.0.0.1", 3000));
279
279
  setNonBlocking(requestSocket);
280
280
  handler = new RequestHandler(libev, requestSocket, pool, options);
281
-
281
+
282
282
  ev_signal_init(&sigquitwatcher, sigquit_cb, SIGQUIT);
283
283
  ev_signal_start(loop, &sigquitwatcher);
284
284
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2011-2013 Phusion
3
+ * Copyright (c) 2011-2014 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -25,7 +25,7 @@
25
25
 
26
26
  /*
27
27
  STAGES
28
-
28
+
29
29
  Accept connect password
30
30
  |
31
31
  \|/
@@ -113,6 +113,7 @@
113
113
  #include <boost/weak_ptr.hpp>
114
114
  #include <boost/make_shared.hpp>
115
115
  #include <boost/regex.hpp>
116
+ #include <boost/cstdint.hpp>
116
117
  #include <ev++.h>
117
118
 
118
119
  #if defined(__GLIBCXX__) || defined(__APPLE__)
@@ -186,21 +187,21 @@ private:
186
187
  static void onClientBodyBufferEnd(const FileBackedPipePtr &source);
187
188
  static void onClientBodyBufferError(const FileBackedPipePtr &source, int errorCode);
188
189
  static void onClientBodyBufferCommit(const FileBackedPipePtr &source);
189
-
190
+
190
191
  static void onClientOutputPipeData(const FileBackedPipePtr &source,
191
192
  const char *data, size_t size,
192
193
  const FileBackedPipe::ConsumeCallback &callback);
193
194
  static void onClientOutputPipeEnd(const FileBackedPipePtr &source);
194
195
  static void onClientOutputPipeError(const FileBackedPipePtr &source, int errorCode);
195
196
  static void onClientOutputPipeCommit(const FileBackedPipePtr &source);
196
-
197
+
197
198
  void onClientOutputWritable(ev::io &io, int revents);
198
199
 
199
200
  static size_t onAppInputData(const EventedBufferedInputPtr &source, const StaticString &data);
200
201
  static void onAppInputChunk(const char *data, size_t size, void *userData);
201
202
  static void onAppInputChunkEnd(void *userData);
202
203
  static void onAppInputError(const EventedBufferedInputPtr &source, const char *message, int errnoCode);
203
-
204
+
204
205
  void onAppOutputWritable(ev::io &io, int revents);
205
206
 
206
207
  void onTimeout(ev::timer &timer, int revents);
@@ -313,7 +314,7 @@ public:
313
314
  * socket (e.g. WebSocket data).
314
315
  *
315
316
  * Possible values:
316
- *
317
+ *
317
318
  * -1: infinite. Should keep forwarding client body until end of stream.
318
319
  * 0: no client body. Should stop after sending headers to application.
319
320
  * >0: Should forward exactly this many bytes of the client body.
@@ -366,7 +367,7 @@ public:
366
367
  clientInput->onData = onClientInputData;
367
368
  clientInput->onError = onClientInputError;
368
369
  clientInput->userData = this;
369
-
370
+
370
371
  clientBodyBuffer = boost::make_shared<FileBackedPipe>("/tmp");
371
372
  clientBodyBuffer->userData = this;
372
373
  clientBodyBuffer->onData = onClientBodyBufferData;
@@ -383,12 +384,12 @@ public:
383
384
 
384
385
  clientOutputWatcher.set<Client, &Client::onClientOutputWritable>(this);
385
386
 
386
-
387
+
387
388
  appInput = boost::make_shared< EventedBufferedInput<> >();
388
389
  appInput->onData = onAppInputData;
389
390
  appInput->onError = onAppInputError;
390
391
  appInput->userData = this;
391
-
392
+
392
393
  appOutputWatcher.set<Client, &Client::onAppOutputWritable>(this);
393
394
 
394
395
 
@@ -398,7 +399,7 @@ public:
398
399
  responseDechunker.onData = onAppInputChunk;
399
400
  responseDechunker.onEnd = onAppInputChunkEnd;
400
401
  responseDechunker.userData = this;
401
-
402
+
402
403
 
403
404
  bufferedConnectPassword.data = NULL;
404
405
  bufferedConnectPassword.alreadyRead = 0;
@@ -453,7 +454,7 @@ public:
453
454
  appInput->reset(NULL, FileDescriptor());
454
455
  appOutputBuffer.resize(0);
455
456
  appOutputWatcher.stop();
456
-
457
+
457
458
  timeoutTimer.stop();
458
459
  scgiParser.reset();
459
460
  session.reset();
@@ -873,7 +874,7 @@ private:
873
874
  * possibly modifies it, and forwards it to
874
875
  * clientOutputPipe.
875
876
  *****************************************************/
876
-
877
+
877
878
  struct Header {
878
879
  StaticString key;
879
880
  StaticString value;
@@ -884,7 +885,7 @@ private:
884
885
  : key(_key),
885
886
  value(_value)
886
887
  { }
887
-
888
+
888
889
  bool empty() const {
889
890
  return key.empty();
890
891
  }
@@ -915,11 +916,11 @@ private:
915
916
  const char *start = data;
916
917
  const char *end = data + size;
917
918
  const char *terminator;
918
-
919
+
919
920
  while (start < end && *start == ' ') {
920
921
  start++;
921
922
  }
922
-
923
+
923
924
  terminator = (const char *) memchr(start, '\r', end - start);
924
925
  if (terminator == NULL) {
925
926
  return StaticString();
@@ -1054,7 +1055,7 @@ private:
1054
1055
  headerData.reserve(origHeaderData.size() + 150);
1055
1056
  // Strip trailing CRLF.
1056
1057
  headerData.append(origHeaderData.data(), origHeaderData.size() - 2);
1057
-
1058
+
1058
1059
  if (startsWith(headerData, "HTTP/1.")) {
1059
1060
  Header status = lookupHeader(headerData, "Status", "status");
1060
1061
  if (status.empty()) {
@@ -1144,7 +1145,7 @@ private:
1144
1145
  headerData.append("\r\n");
1145
1146
 
1146
1147
  // Invalidate all cookies with a different route.
1147
- //
1148
+ //
1148
1149
  // TODO: This is not entirely correct. Clients MAY send multiple Cookie
1149
1150
  // headers, although this is in practice extremely rare.
1150
1151
  // http://stackoverflow.com/questions/16305814/are-multiple-cookie-headers-allowed-in-an-http-request
@@ -1937,7 +1938,7 @@ private:
1937
1938
  }
1938
1939
  options.baseURI = scriptName;
1939
1940
  }
1940
-
1941
+
1941
1942
  options.ruby = this->options.defaultRubyCommand;
1942
1943
  options.logLevel = getLogLevel();
1943
1944
  options.loggingAgentAddress = this->options.loggingAgentAddress;
@@ -1969,7 +1970,7 @@ private:
1969
1970
  fillPoolOption(client, options.raiseInternalError, "PASSENGER_RAISE_INTERNAL_ERROR");
1970
1971
  setStickySessionId(client);
1971
1972
  /******************/
1972
-
1973
+
1973
1974
  for (it = client->scgiParser.begin(); it != end; it++) {
1974
1975
  if (!startsWith(it->first, "PASSENGER_")
1975
1976
  && !startsWith(it->first, "HTTP_")
@@ -2001,7 +2002,7 @@ private:
2001
2002
  client->options.analytics = true;
2002
2003
  client->options.unionStationKey = key;
2003
2004
  }
2004
-
2005
+
2005
2006
  client->beginScopeLog(&client->scopeLogs.requestProcessing, "request processing");
2006
2007
 
2007
2008
  StaticString staticRequestMethod = parser.getHeader("REQUEST_METHOD");
@@ -2301,7 +2302,7 @@ private:
2301
2302
 
2302
2303
  void writeSpawnExceptionErrorResponse(const ClientPtr &client, const boost::shared_ptr<SpawnException> &e) {
2303
2304
  RH_ERROR(client, "Cannot checkout session because a spawning error occurred. " <<
2304
- "The identifier of the error is " << e->get("ERROR_ID") << ". Please see earlier logs for " <<
2305
+ "The identifier of the error is " << e->get("error_id") << ". Please see earlier logs for " <<
2305
2306
  "details about the error.");
2306
2307
  writeErrorResponse(client, e->getErrorPage(), e.get());
2307
2308
  }
@@ -2323,7 +2324,7 @@ private:
2323
2324
 
2324
2325
  RH_WARN(client, "Cannot checkout session (exception type " <<
2325
2326
  typeName << "): " << e->what());
2326
-
2327
+
2327
2328
  string response = "An internal error occurred while trying to spawn the application.\n";
2328
2329
  response.append("Exception type: ");
2329
2330
  response.append(typeName);
@@ -2362,7 +2363,7 @@ private:
2362
2363
  }
2363
2364
  return;
2364
2365
  }
2365
-
2366
+
2366
2367
  if (client->useUnionStation()) {
2367
2368
  client->endScopeLog(&client->scopeLogs.getFromPool);
2368
2369
  client->logMessage("Application PID: " +
@@ -2370,7 +2371,7 @@ private:
2370
2371
  " (GUPID: " + client->session->getGupid() + ")");
2371
2372
  client->beginScopeLog(&client->scopeLogs.requestProxying, "request proxying");
2372
2373
  }
2373
-
2374
+
2374
2375
  RH_DEBUG(client, "Session initiated: fd=" << client->session->fd());
2375
2376
  setNonBlocking(client->session->fd());
2376
2377
  client->appInput->reset(libev.get(), client->session->fd());
@@ -2398,10 +2399,10 @@ private:
2398
2399
  disconnectWithError(client,
2399
2400
  "Application sent EOF before we were able to send headers to it");
2400
2401
  } else if (client->session->getProtocol() == "session") {
2401
- char sizeField[sizeof(uint32_t)];
2402
+ char sizeField[sizeof(boost::uint32_t)];
2402
2403
  SmallVector<StaticString, 10> data;
2403
2404
 
2404
- data.push_back(StaticString(sizeField, sizeof(uint32_t)));
2405
+ data.push_back(StaticString(sizeField, sizeof(boost::uint32_t)));
2405
2406
  data.push_back(client->scgiParser.getHeaderData());
2406
2407
 
2407
2408
  data.push_back(makeStaticStringWithNull("PASSENGER_CONNECT_PASSWORD"));
@@ -2412,9 +2413,9 @@ private:
2412
2413
  data.push_back(makeStaticStringWithNull(client->options.transaction->getTxnId()));
2413
2414
  }
2414
2415
 
2415
- uint32_t dataSize = 0;
2416
+ boost::uint32_t dataSize = 0;
2416
2417
  for (unsigned int i = 1; i < data.size(); i++) {
2417
- dataSize += (uint32_t) data[i].size();
2418
+ dataSize += (boost::uint32_t) data[i].size();
2418
2419
  }
2419
2420
  Uint32Message::generate(sizeField, dataSize);
2420
2421
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010-2014 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -55,12 +55,12 @@ using namespace std;
55
55
  * char buf[1024 * 16];
56
56
  * ssize_t size;
57
57
  * unsigned in bytesAccepted;
58
- *
58
+ *
59
59
  * do {
60
60
  * size = read(fd, buf, sizeof(buf));
61
61
  * bytesAccepted = parser.feed(buf, size);
62
62
  * } while (parser.acceptingInput());
63
- *
63
+ *
64
64
  * // Check whether a parse error occured.
65
65
  * if (parser.getState() == ScgiRequestParser::ERROR) {
66
66
  * bailOut();
@@ -68,7 +68,7 @@ using namespace std;
68
68
  * // All good! Do something with the SCGI header that the parser parsed.
69
69
  * processHeader(parser.getHeaderData());
70
70
  * print(parser.getHeader("DOCUMENT_ROOT"));
71
- *
71
+ *
72
72
  * // If the last buffer passed to the parser also contains body data,
73
73
  * // then the body data starts at 'buf + bytesAccepted'.
74
74
  * if (bytesAccepted < size) {
@@ -115,53 +115,53 @@ public:
115
115
  DONE,
116
116
  ERROR
117
117
  };
118
-
118
+
119
119
  enum ErrorReason {
120
120
  NONE,
121
-
121
+
122
122
  /** The header has a length of 0 bytes. */
123
123
  EMPTY_HEADER,
124
-
124
+
125
125
  /** The length string is too large. */
126
126
  LENGTH_STRING_TOO_LARGE,
127
-
127
+
128
128
  /** The header is larger than the maxSize value provided to the constructor. */
129
129
  LIMIT_REACHED,
130
-
130
+
131
131
  /** The length string contains an invalid character. */
132
132
  INVALID_LENGTH_STRING,
133
-
134
- /** A header terminator character (",") was expected, but some else
133
+
134
+ /** A header terminator character (",") was expected, but something else
135
135
  * was encountered instead. */
136
136
  HEADER_TERMINATOR_EXPECTED,
137
-
137
+
138
138
  /** The header data itself contains errors. */
139
139
  INVALID_HEADER_DATA
140
140
  };
141
-
141
+
142
142
  private:
143
143
  State state;
144
144
  ErrorReason errorReason;
145
145
  unsigned int lengthStringBufferSize;
146
146
  size_t headerSize;
147
147
  size_t maxSize;
148
-
148
+
149
149
  StaticString headerData;
150
150
  string headerBuffer;
151
151
  HeaderMap headers;
152
152
  char lengthStringBuffer[sizeof("4294967296")];
153
-
153
+
154
154
  static inline bool isDigit(char byte) {
155
155
  return byte >= '0' && byte <= '9';
156
156
  }
157
-
157
+
158
158
  /**
159
159
  * Parse the given header data into key-value pairs, returns whether parsing succeeded.
160
160
  */
161
161
  bool parseHeaderData(const StaticString &data, HeaderMap &output) {
162
162
  const char *current = data.data();
163
163
  const char *end = data.data() + data.size();
164
-
164
+
165
165
  while (current < end) {
166
166
  const char *keyEnd = (const char *) memchr(current, '\0', end - current);
167
167
  if (OXT_UNLIKELY(
@@ -170,24 +170,24 @@ private:
170
170
  ) {
171
171
  return false;
172
172
  }
173
-
173
+
174
174
  StaticString key(current, keyEnd - current);
175
175
  current = keyEnd + 1;
176
176
  if (OXT_UNLIKELY(current >= end)) {
177
177
  return false;
178
178
  }
179
-
179
+
180
180
  const char *valueEnd = (const char *) memchr(current, '\0', end - current);
181
181
  if (OXT_UNLIKELY(valueEnd == NULL)) {
182
182
  return false;
183
183
  }
184
-
184
+
185
185
  output[key] = StaticString(current, valueEnd - current);
186
186
  current = valueEnd + 1;
187
187
  }
188
188
  return true;
189
189
  }
190
-
190
+
191
191
  public:
192
192
  /**
193
193
  * Create a new ScgiRequestParser, ready to parse a request.
@@ -199,7 +199,7 @@ public:
199
199
  this->maxSize = maxSize;
200
200
  reset();
201
201
  }
202
-
202
+
203
203
  void reset() {
204
204
  state = READING_LENGTH_STRING;
205
205
  errorReason = NONE;
@@ -227,41 +227,47 @@ public:
227
227
  */
228
228
  size_t feed(const char *data, size_t size) {
229
229
  size_t consumed = 0;
230
-
230
+
231
231
  while (acceptingInput() && consumed < size) {
232
232
  switch (state) {
233
233
  case READING_LENGTH_STRING:
234
234
  while (consumed < size
235
- && lengthStringBufferSize < sizeof(lengthStringBuffer) - 1
236
- && isDigit(data[consumed])) {
235
+ && lengthStringBufferSize < sizeof(lengthStringBuffer)
236
+ && isDigit(data[consumed]))
237
+ {
237
238
  lengthStringBuffer[lengthStringBufferSize] = data[consumed];
238
239
  lengthStringBufferSize++;
239
240
  consumed++;
240
241
  }
241
242
  if (consumed < size) {
242
- if (data[consumed] == ':') {
243
- consumed++;
244
- lengthStringBuffer[lengthStringBufferSize] = '\0';
245
- headerSize = atol(lengthStringBuffer);
246
- if (maxSize > 0 && headerSize > maxSize) {
247
- state = ERROR;
248
- errorReason = LIMIT_REACHED;
249
- } else if (headerSize == 0) {
243
+ if (lengthStringBufferSize == sizeof(lengthStringBuffer)) {
244
+ state = ERROR;
245
+ errorReason = LENGTH_STRING_TOO_LARGE;
246
+ } else if (data[consumed] == ':') {
247
+ if (lengthStringBufferSize == 0) {
250
248
  state = ERROR;
251
- errorReason = EMPTY_HEADER;
249
+ errorReason = INVALID_LENGTH_STRING;
252
250
  } else {
253
- state = READING_HEADER_DATA;
251
+ consumed++;
252
+ lengthStringBuffer[lengthStringBufferSize] = '\0';
253
+ headerSize = atol(lengthStringBuffer);
254
+ if (maxSize > 0 && headerSize > maxSize) {
255
+ state = ERROR;
256
+ errorReason = LIMIT_REACHED;
257
+ } else if (headerSize == 0) {
258
+ state = ERROR;
259
+ errorReason = EMPTY_HEADER;
260
+ } else {
261
+ state = READING_HEADER_DATA;
262
+ }
254
263
  }
255
- } else if (lengthStringBufferSize >= sizeof(lengthStringBuffer) - 1) {
256
- state = ERROR;
257
- errorReason = LENGTH_STRING_TOO_LARGE;
258
264
  } else {
259
265
  state = ERROR;
260
266
  errorReason = INVALID_LENGTH_STRING;
261
267
  }
262
268
  }
263
269
  break;
264
-
270
+
265
271
  case READING_HEADER_DATA: {
266
272
  const char *localData = data + consumed;
267
273
  size_t localSize = std::min(
@@ -283,7 +289,7 @@ public:
283
289
  consumed += localSize;
284
290
  break;
285
291
  }
286
-
292
+
287
293
  case EXPECTING_COMMA:
288
294
  if (data[consumed] == ',') {
289
295
  if (parseHeaderData(headerData, headers)) {
@@ -298,12 +304,12 @@ public:
298
304
  errorReason = HEADER_TERMINATOR_EXPECTED;
299
305
  }
300
306
  break;
301
-
307
+
302
308
  default:
303
309
  abort(); // Never reached.
304
310
  }
305
311
  }
306
-
312
+
307
313
  if (state == EXPECTING_COMMA && headerBuffer.empty()) {
308
314
  /* We got all the header data in a single round, except
309
315
  * for the closing comma. The static header data isn't
@@ -313,10 +319,10 @@ public:
313
319
  headerBuffer.assign(headerData.c_str(), headerData.size());
314
320
  headerData = headerBuffer;
315
321
  }
316
-
322
+
317
323
  return consumed;
318
324
  }
319
-
325
+
320
326
  /**
321
327
  * Get the raw header data that has been processed so far.
322
328
  * Please read the zero-copy notes in the class description for
@@ -330,7 +336,7 @@ public:
330
336
  const_iterator getHeaderIterator(const StaticString &name) const {
331
337
  return headers.find(name);
332
338
  }
333
-
339
+
334
340
  /**
335
341
  * Get the value of the header with the given name.
336
342
  * Lookup is case-sensitive.
@@ -350,7 +356,7 @@ public:
350
356
  return it->second;
351
357
  }
352
358
  }
353
-
359
+
354
360
  /**
355
361
  * Checks whether there is a header with the given name.
356
362
  * Lookup is case-sensitive.
@@ -364,7 +370,7 @@ public:
364
370
  HeaderMap &getMap() {
365
371
  return headers;
366
372
  }
367
-
373
+
368
374
  unsigned int size() const {
369
375
  return headers.size();
370
376
  }
@@ -376,14 +382,14 @@ public:
376
382
  const_iterator end() const {
377
383
  return headers.end();
378
384
  }
379
-
385
+
380
386
  /**
381
387
  * Get the parser's current state.
382
388
  */
383
389
  State getState() const {
384
390
  return state;
385
391
  }
386
-
392
+
387
393
  /**
388
394
  * Returns the reason why the parser entered the error state.
389
395
  *
@@ -392,7 +398,7 @@ public:
392
398
  ErrorReason getErrorReason() const {
393
399
  return errorReason;
394
400
  }
395
-
401
+
396
402
  /**
397
403
  * Checks whether this parser is still capable of accepting input (that
398
404
  * is, that this parser is not in a final/error state).