passenger 4.0.18 → 4.0.19

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.

data.tar.gz.asc CHANGED
@@ -2,11 +2,11 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQEcBAABAgAGBQJSOKPwAAoJECrHRaUKISqMIWsIAI0gIk9gSi5obV1E6ZzujCtb
6
- caa6QFENT8p9GY1w6V1vy1j8IX5fH4lVp5NpVpSfLUpebER0NLWChF53xSQ7pt2x
7
- ai9grp2EWke0mc/U8xpV1b/JdP3+6aAaynk0Gn6aqAz8Oj4Z1L3KL6zaaG8p8HX/
8
- wmlyjbkXvVxakyk+JIldGjZIsZIskEq2Z9uKfUGj4JVFHSq06d2g3u8tM8hA8QpY
9
- 6DmXvd2d/VV4S/g3UsvDqh69wKIEX43k4PTIgsyOypThkkoEiXcFMniBtnohPTfB
10
- ShqktUEJUUsTPPtuKaIw/LnrLhE8HscgSn6kSDpsLeLgKDO5P9DIJVEiYQ2V4mI=
11
- =UqRe
5
+ iQEcBAABAgAGBQJSQSkWAAoJECrHRaUKISqMWtsIAKiNtrucfxuOIVN6wptQyV0B
6
+ E1HSZ00iHfUSh96Tx7avx/QZT4VO76Kn7iWDSuv0txACtdbCWkcvMvEc/8Py2umr
7
+ PnvZm9FpY6yWaF9nd85flihTKHh8TVohYxhYyA+NvBc/qHvYtYwBi2Fq3SmHA7qT
8
+ nkx2Q3uZSE3w8bMfDvTfQL/tO5pidzKxV0pu6SBfQWg8OMpryRVP2dUv4dpg8lDh
9
+ ZsnP+aVW8rxSoOn56Wwhbkqez2/1W1MFo1HG11ms//nSvwjVXRO/XpHhNsIIvrFH
10
+ O8DXuKpcGeB32GQ4xAdX8FrSt4+ecMpraDTtcIEyMU4qagBcgOlXgqofcFCNIUE=
11
+ =H3GZ
12
12
  -----END PGP SIGNATURE-----
data/NEWS CHANGED
@@ -1,3 +1,15 @@
1
+ Release 4.0.19
2
+ --------------
3
+
4
+ * Fixed a problem with response buffering. Application processes are now
5
+ properly marked available for request processing immediately after they're
6
+ done sending the response, instead of after having sent the entire response
7
+ to the client.
8
+ * The "processed" counter in `passenger-status` is now bumped after the process
9
+ has handled a request, not at the beginning.
10
+ * [Enterprise] Fixed an off-by-one bug in the `passenger_max_processes` setting.
11
+
12
+
1
13
  Release 4.0.18
2
14
  --------------
3
15
 
@@ -187,13 +187,20 @@ task 'package:release' => ['package:set_official', 'package:gem', 'package:tarba
187
187
  else
188
188
  dir = "/u/apps/passenger_website/shared"
189
189
  subdir = string_option('NAME', version)
190
+ git_url = `git config remote.origin.url`.strip
191
+
190
192
  sh "scp #{PKG_DIR}/#{basename}.{gem,tar.gz,gem.asc,tar.gz.asc} app@shell.phusion.nl:#{dir}/"
191
193
  sh "ssh app@shell.phusion.nl 'mkdir -p \"#{dir}/assets/#{subdir}\" && mv #{dir}/#{basename}.{gem,tar.gz,gem.asc,tar.gz.asc} \"#{dir}/assets/#{subdir}/\"'"
192
194
  sh "curl -F file=@#{PKG_DIR}/#{basename}.gem --user admin:#{website_config['admin_password']} " +
193
195
  "https://www.phusionpassenger.com/enterprise_gems/upload"
194
196
 
197
+ puts "Initiating building of binaries"
198
+ command = "cd /srv/passenger_autobuilder/app && " +
199
+ "/tools/silence-unless-failed chpst -l /tmp/passenger_autobuilder.lock " +
200
+ "./autobuild-with-pbuilder #{git_url} passenger-enterprise --tag=#{tag}"
201
+ ssh "psg_autobuilder_run@juvia-helper.phusion.nl at now <<<'#{command}'"
202
+
195
203
  puts "Initiating building of Debian packages"
196
- git_url = `git config remote.origin.url`.strip
197
204
  command = "cd /srv/passenger_apt_automation && " +
198
205
  "chpst -l /tmp/passenger_apt_automation.lock " +
199
206
  "/tools/silence-unless-failed " +
@@ -557,7 +557,6 @@ public:
557
557
  } else {
558
558
  socket->sessions++;
559
559
  this->sessions++;
560
- processed++;
561
560
  socket->pqHandle = sessionSockets.push(socket, socket->utilization());
562
561
  lastUsed = SystemTime::getUsec();
563
562
  return make_shared<Session>(shared_from_this(), socket);
@@ -572,6 +571,7 @@ public:
572
571
 
573
572
  socket->sessions--;
574
573
  this->sessions--;
574
+ processed++;
575
575
  sessionSockets.decrease(socket->pqHandle, socket->utilization());
576
576
  assert(!atFullUtilization());
577
577
  }
@@ -119,5 +119,10 @@ BackgroundEventLoop::stop() {
119
119
  }
120
120
  }
121
121
 
122
+ bool
123
+ BackgroundEventLoop::isStarted() const {
124
+ return priv->thr != NULL;
125
+ }
126
+
122
127
 
123
128
  } // namespace Passenger
@@ -54,6 +54,7 @@ namespace Passenger {
54
54
 
55
55
  void start(const string &threadName = "", unsigned int stackSize = 1024 * 1024);
56
56
  void stop();
57
+ bool isStarted() const;
57
58
  };
58
59
 
59
60
  }
@@ -72,7 +72,7 @@
72
72
 
73
73
  #define MESSAGE_SERVER_MAX_USERNAME_SIZE 100
74
74
 
75
- #define PASSENGER_VERSION "4.0.18"
75
+ #define PASSENGER_VERSION "4.0.19"
76
76
 
77
77
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
78
78
 
@@ -344,7 +344,7 @@ private:
344
344
  return;
345
345
  }
346
346
 
347
- assert(dataState = OPENING_FILE);
347
+ assert(dataState == OPENING_FILE);
348
348
  if (req.result < 0) {
349
349
  setError(req.errorno);
350
350
  } else {
@@ -1128,6 +1128,7 @@ private:
1128
1128
  }
1129
1129
 
1130
1130
  RH_DEBUG(client, "Application sent EOF");
1131
+ client->session.reset();
1131
1132
  client->endScopeLog(&client->scopeLogs.requestProxying);
1132
1133
  client->clientOutputPipe->end();
1133
1134
  }
@@ -2061,7 +2062,10 @@ private:
2061
2062
 
2062
2063
  RH_TRACE(client, 2, "Sending headers to application");
2063
2064
 
2064
- if (client->session->getProtocol() == "session") {
2065
+ if (client->session == NULL) {
2066
+ disconnectWithError(client,
2067
+ "Application sent EOF before we were able to send headers to it");
2068
+ } else if (client->session->getProtocol() == "session") {
2065
2069
  char sizeField[sizeof(uint32_t)];
2066
2070
  SmallVector<StaticString, 10> data;
2067
2071
 
@@ -2164,15 +2168,20 @@ private:
2164
2168
  void state_sendingHeaderToApp_onAppOutputWritable(const ClientPtr &client) {
2165
2169
  state_sendingHeaderToApp_verifyInvariants(client);
2166
2170
 
2167
- ssize_t ret = gatheredWrite(client->session->fd(), NULL, 0, client->appOutputBuffer);
2168
- if (ret == -1) {
2169
- if (errno != EAGAIN && errno != EPIPE && errno != ECONNRESET) {
2170
- disconnectWithAppSocketWriteError(client, errno);
2171
+ if (client->session == NULL) {
2172
+ disconnectWithError(client,
2173
+ "Application sent EOF before we were able to send headers to it");
2174
+ } else {
2175
+ ssize_t ret = gatheredWrite(client->session->fd(), NULL, 0, client->appOutputBuffer);
2176
+ if (ret == -1) {
2177
+ if (errno != EAGAIN && errno != EPIPE && errno != ECONNRESET) {
2178
+ disconnectWithAppSocketWriteError(client, errno);
2179
+ }
2180
+ // TODO: what about other errors?
2181
+ } else if (client->appOutputBuffer.empty()) {
2182
+ client->appOutputWatcher.stop();
2183
+ sendBodyToApp(client);
2171
2184
  }
2172
- // TODO: what about other errors?
2173
- } else if (client->appOutputBuffer.empty()) {
2174
- client->appOutputWatcher.stop();
2175
- sendBodyToApp(client);
2176
2185
  }
2177
2186
  }
2178
2187
 
@@ -2216,6 +2225,14 @@ private:
2216
2225
  }
2217
2226
 
2218
2227
  RH_TRACE(client, 3, "Forwarding " << size << " bytes of client body data to application.");
2228
+
2229
+ if (client->session == NULL) {
2230
+ RH_TRACE(client, 2, "Application had already sent EOF. Stop reading client input.");
2231
+ client->clientInput->stop();
2232
+ syscalls::shutdown(client->fd, SHUT_RD);
2233
+ return 0;
2234
+ }
2235
+
2219
2236
  ssize_t ret = syscalls::write(client->session->fd(), data, size);
2220
2237
  int e = errno;
2221
2238
  if (ret == -1) {
@@ -2253,7 +2270,7 @@ private:
2253
2270
 
2254
2271
  RH_TRACE(client, 2, "End of (unbuffered) client body reached; done sending data to application");
2255
2272
  client->clientInput->stop();
2256
- if (client->shouldHalfCloseWrite()) {
2273
+ if (client->session != NULL && client->shouldHalfCloseWrite()) {
2257
2274
  syscalls::shutdown(client->session->fd(), SHUT_WR);
2258
2275
  }
2259
2276
  }
@@ -2280,6 +2297,14 @@ private:
2280
2297
  assert(client->requestBodyIsBuffered);
2281
2298
 
2282
2299
  RH_TRACE(client, 3, "Forwarding " << size << " bytes of buffered client body data to application.");
2300
+
2301
+ if (client->session == NULL) {
2302
+ RH_TRACE(client, 2, "Application had already sent EOF. Stop reading client input.");
2303
+ syscalls::shutdown(client->fd, SHUT_RD);
2304
+ consumed(0, true);
2305
+ return;
2306
+ }
2307
+
2283
2308
  ssize_t ret = syscalls::write(client->session->fd(), data, size);
2284
2309
  if (ret == -1) {
2285
2310
  int e = errno;
@@ -2306,7 +2331,7 @@ private:
2306
2331
  assert(client->requestBodyIsBuffered);
2307
2332
 
2308
2333
  RH_TRACE(client, 2, "End of (buffered) client body reached; done sending data to application");
2309
- if (client->shouldHalfCloseWrite()) {
2334
+ if (client->session != NULL && client->shouldHalfCloseWrite()) {
2310
2335
  syscalls::shutdown(client->session->fd(), SHUT_WR);
2311
2336
  }
2312
2337
  }
@@ -30,7 +30,7 @@ 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.18'
33
+ VERSION_STRING = '4.0.19'
34
34
 
35
35
  PREFERRED_NGINX_VERSION = '1.4.2'
36
36
  NGINX_SHA256_CHECKSUM = '5361ffb7b0ebf8b1a04369bc3d1295eaed091680c1c58115f88d56c8e51f3611'
@@ -63,10 +63,12 @@ namespace tut {
63
63
 
64
64
  ~RequestHandlerTest() {
65
65
  setLogLevel(DEFAULT_LOG_LEVEL);
66
+ if (bg.isStarted()) {
67
+ bg.safe->runSync(boost::bind(&RequestHandlerTest::destroy, this));
68
+ } else {
69
+ destroy();
70
+ }
66
71
  unlink(serverFilename.c_str());
67
- handler.reset();
68
- pool->destroy();
69
- pool.reset();
70
72
  }
71
73
 
72
74
  void init() {
@@ -74,6 +76,13 @@ namespace tut {
74
76
  bg.start();
75
77
  }
76
78
 
79
+ void destroy() {
80
+ handler.reset();
81
+ pool->destroy();
82
+ pool.reset();
83
+ ev_break(bg.loop, EVBREAK_ALL);
84
+ }
85
+
77
86
  void initPoolDebugging() {
78
87
  pool->initDebugging();
79
88
  debug = pool->debugSupport;
@@ -151,7 +160,7 @@ namespace tut {
151
160
  }
152
161
  };
153
162
 
154
- DEFINE_TEST_GROUP(RequestHandlerTest);
163
+ DEFINE_TEST_GROUP_WITH_LIMIT(RequestHandlerTest, 80);
155
164
 
156
165
  TEST_METHOD(1) {
157
166
  // Test one normal request.
@@ -914,6 +923,31 @@ namespace tut {
914
923
  ensure(response.find("This website is under heavy load") != string::npos);
915
924
  }
916
925
 
926
+ TEST_METHOD(51) {
927
+ set_test_name("It relieves the application process after having read its entire response data");
928
+
929
+ init();
930
+ connect();
931
+ sendHeaders(defaultHeaders,
932
+ "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
933
+ "PATH_INFO", "/blob",
934
+ NULL);
935
+ vector<ProcessPtr> processes;
936
+ EVENTUALLY(5,
937
+ processes = pool->getProcesses();
938
+ result = processes.size() == 1;
939
+ );
940
+ EVENTUALLY(5,
941
+ LockGuard l(pool->syncher);
942
+ result = processes[0]->processed == 1;
943
+ );
944
+ {
945
+ LockGuard l(pool->syncher);
946
+ ensure_equals("The session is closed before the client is done reading",
947
+ processes[0]->sessions, 0);
948
+ }
949
+ }
950
+
917
951
  // Test small response buffering.
918
952
  // Test large response buffering.
919
953
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.18
4
+ version: 4.0.19
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-17 00:00:00.000000000 Z
12
+ date: 2013-09-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
metadata.gz.asc CHANGED
@@ -2,11 +2,11 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQEcBAABAgAGBQJSOKPwAAoJECrHRaUKISqMlkcIAIyquE2ypVcCq8Kds8gncXoI
6
- T94rU5e49Jxqfzd8jxz0CDihW6wI+CvkuVOxziZdZaYfVYaBm3oGn7zhmhC6mQhL
7
- +B6g5NqzANlaty3OBCufl4yvAKMFw4M8GLc0nxtSdVdAwEKiI45gZY3WEZxwA74q
8
- aMZrVFACgXmYijayxqiHBUqITYEjMqrlAbpLjUNgulhKzwNNlpGhL2VeBg4t0Bpr
9
- NMldNutbg1Sc0PmIyIXOXmZJWtpYBm24RcrGyWCF6qikPWIEtpU9l3edLTKVmUHP
10
- J0hO08TMC7bDfE3qT3jB+KxGlXDPVFyO2cIn7+73llsZvricCWqr+GxTq5bCm88=
11
- =49PA
5
+ iQEcBAABAgAGBQJSQSkWAAoJECrHRaUKISqM2EkH/ipt34zAO/CrdwkuXBOMzpXy
6
+ VMVuZXXrVLZTqF8EdkjB3eq5pcwxrnfqQwOUfvLsyhc0rWKXxoWP0KOjm+bLpX4x
7
+ O+skjXJleMSk63nH792obDFCR6x7BYx+oqaDDokvL1l04b6w4HJGWujCPcaIvc49
8
+ CGo7U8d/ST2RilYpKAdkeaHD1Ms+kDObl7lbX/wLKMeuRYUbaEThI6wK3oKv7K4G
9
+ zzQeVf05TdGpCV/sn3c5rhRCgqlde8xqLgDTxUiOeWKq3AwJYw1Mq20rHFf/8hBL
10
+ NYlizIKtAXEZoTOdsX2BZ/vZfYIEinDbGO1rNx2hoCfh2daYhi5fnzDOn28vLrc=
11
+ =b5ry
12
12
  -----END PGP SIGNATURE-----