passenger 5.0.19 → 5.0.20

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.

checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDc5ZmMyZjkyOTcwYTE3YmVlZDZlZDRlM2UyMGY1ZDUwNDIxNjBlMw==
4
+ OGU3ZWRlNTY4YTI4N2JiYjg2M2U2YTlmMjg0OTEwNWU1M2JkZWRjMQ==
5
5
  data.tar.gz: !binary |-
6
- MzIxYTE0ZDg0NTdlNmQyN2ZhZjE3NmI4ZDM0YTBhZDQyYmZhMTNhYQ==
6
+ NGFhZjc4YWI1MTNhZTU5NTk3ZGY2MWZkYmUwZjZmMDBhNDdmODk4Nw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MjEyNzVjMDJkMzkxYjk5OWM2NzQxMjcwYmRjYzI2YTY2MjU3YTgwMDhlZGIz
10
- OGEyYmMzYjBkOGRhNDg3YTExY2U5MTdiZGIwMDQ4NTJkOTUwYzY0ZWMyMWE2
11
- OTE0MzMyNDRjMTI1MzA5NjliZDRiZDVjMWExMmRmNDVkZDFhMDI=
9
+ NDA0ZmIyNmY2ODQ0ODdhMDlkNzkzODgwNjk1MTQ1ZTc0ODhmZDdjNDRkOWI2
10
+ OWMyYTM4ZmIyZjA3NTQ3NmRiMTM2NjNmMmNmNmJkZjliODg3MDQ0M2FiZjIy
11
+ NDYyNzY1ZTBhMmQ3MWMyZDM0MDdhOTVmOTczZjNmMTNjOWQxZjI=
12
12
  data.tar.gz: !binary |-
13
- NDM4Zjk2N2FkOTViNmE0YzI0ZTJjNTlhYmU3M2M5MzUzYmFjY2M1MjFkZjhi
14
- YTMzOWViZDQxMTNhZDk3ZGVjYjA2ZGY0MDFiYWRiNDA5MTc5OWRjNjg1ZTU1
15
- YmZhNmJjYTg1NDU4YTdjMDk4YTU2MjQxNGExZDM2M2NlMDlkZmM=
13
+ NDU4YjAxNzc4YTIxODNiYTRjYjY4Y2VkNWZhYTY0ZWU2ZWQyODE0MGI1NDJh
14
+ MDJkYjg4NDgzOTdmYmNkMTcyYjkzMWVkM2QyOTg0MWI0MjQ0MWRjNTFkM2Zl
15
+ NDMzODhjZmE3NTAzN2FhMWM4MjUwYzE2OWJhYmZlODJjNGYzMzI=
checksums.yaml.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
- iQEcBAABAgAGBQJWA7ACAAoJECrHRaUKISqMhsMH/1v7Wd/pi016ufbPzUAP47kR
6
- 0OUx+LRS46aBqH6+b1nkDS00XZTyQyU3lfkUNCfvq+e5q9Ct64Fh6E09JxQl5Fzf
7
- dzjGtOqKFkWKC1FsJHzL0v8srqZ8UJXJMymRgJUmq3/txK79NCiqFf1YjiD6CKOX
8
- 0dzhFHAvLOO4iRw2N4ntAWYwcrwGjy9+Dkpmijgc9Q+IpBn+4UYiDXeMLp1VD3s1
9
- n/+QmzJH/Wn+gXO5lPvN6V1zW2+7S486CASC6A1qF23TJYG6A4obPTRV8jN8G0BJ
10
- zXrojyRe+U8HKcWsYws9rVGl0GklTajTvEBTjJuxJYr7lSVouzf0C7cyOpW4bLo=
11
- =aqnU
5
+ iQEcBAABAgAGBQJWBVguAAoJECrHRaUKISqM9UYH/Rex0SrCvVUTeChbuA/c4qSK
6
+ r6Kt0FDl+krahxG3FReSg0sIB86uvUL0r8Axqd32VnOIpbYBgmzBw3+RKW9p15Cg
7
+ UGpeKpphF+vV42V8pJTTbfOzqLmkVZdiqXj8bStOD5HGguIKUJSQlO1vgT1dXiMu
8
+ SXZVl+2l7yredGoh/J+NxGdLVrXGyHsR9SK2/aOWayC/271jl1038ATIjLpg5Sx4
9
+ mH0WBDCjbj7EE2dLG9ihsd9O6FRQLc2LHkenqULzbJasOEWBUmiI4UMmGhSuRa/+
10
+ +NPpYdok38hYlHBzClyXOV/7AmMLG97MBZOa6X/Dall5v/lCMpVhdpJHJzrzO7E=
11
+ =55ZZ
12
12
  -----END PGP SIGNATURE-----
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
- iQEcBAABAgAGBQJWA7ACAAoJECrHRaUKISqMhRUH/iTg+aF3zM3Gin7BWOGBGjnw
6
- YkMKTmkJOzd9Nv/jDzVhUTK+cW3gY7wdHjNVaG7uaHOm2aTkT0YmRuy8fUeTF9mb
7
- rnFwWIuroRTncqCyl8M1IuF1LEZ1tTYWICkcO3/aQjR2bp3ujYPCYlMhE4az7DGH
8
- lFNQzFi2O8FrkPMri8fJyBKAdlJMeiu8qj1TqWs5CsjxqXD146dDyVQy9ABFc051
9
- Rgcu5KmCo5wkRZ2kTYtcNgUQT53VjkJ1B0Pr4lWf1QEUARbVGiPlALnBIHo9Agg2
10
- aYVEV+iMQl5jfqSZtozvg3KLRNNMrpQjPu6EZR/3yaiJnvy7EjoD+DXY2DJEe2A=
11
- =AFTj
5
+ iQEcBAABAgAGBQJWBVguAAoJECrHRaUKISqMnD0H/RmCI5vqS9MtfHzF9CRTJ8mG
6
+ 2izv4FJ6Te1JU272ZijuVR9A62lT5bdsaJQG93Gm6XVmQEFuMSeM9rlyB96F0UfP
7
+ Bc47/Bt5mRd1S5TxK67bhQKifmjt9601uD1GgXa4cqiYLtYDcOQFY5YR52uj8U1A
8
+ 13GxzAWWEfqHxhMFR6IGSErYLhqtwy7g24DnyQtmHhn5qy2eL0ECnshczMoah6FI
9
+ 4rgPH7cY86LiRugDBAKq9Jp4KgBfIU7i2pKkgtUzE4PVVirq9ZeqdBpQGIiznMHX
10
+ glxwM2XGuXm0/8K8N2iMefULIU9XUPmYxA6+1wADIC0KK5fp0Ai6vThFrI/+dko=
11
+ =1Jp0
12
12
  -----END PGP SIGNATURE-----
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ Release 5.0.20
2
+ --------------
3
+
4
+ * Fixes memory management bugs in Union Station support.
5
+ * Improves the error handling in Union Station support.
6
+ * `passenger-config validate-install` now properly handles CR characters in Apache configuration files.
7
+
8
+
1
9
  Release 5.0.19
2
10
  --------------
3
11
 
@@ -191,11 +191,21 @@ private:
191
191
  int errcode)
192
192
  {
193
193
  size_t consumed = client->arrayReader.feed(buffer.start, buffer.size());
194
+
195
+ if (client->arrayReader.hasError()) {
196
+ disconnectWithError(&client,
197
+ string("Error processing message: array message parse error: ")
198
+ + client->arrayReader.errorString());
199
+ return Channel::Result(consumed, true);
200
+ }
201
+
194
202
  if (client->arrayReader.done()) {
203
+ // No error
195
204
  const vector<StaticString> &message = client->arrayReader.value();
196
205
  SKC_DEBUG(client, "Message received: " << toString(message));
197
206
  if (message.size() < 1) {
198
- disconnectWithError(&client, "Error processing message: too few parameters");
207
+ disconnectWithError(&client, "Error processing message:"
208
+ " too few parameters");
199
209
  return Channel::Result(consumed, true);
200
210
  }
201
211
 
@@ -209,7 +219,16 @@ private:
209
219
  int errcode)
210
220
  {
211
221
  size_t consumed = client->scalarReader.feed(buffer.start, buffer.size());
222
+
223
+ if (client->scalarReader.hasError()) {
224
+ disconnectWithError(&client,
225
+ string("Error processing message: scalar message parse error: ")
226
+ + client->scalarReader.errorString());
227
+ return Channel::Result(consumed, true);
228
+ }
229
+
212
230
  if (client->scalarReader.done()) {
231
+ // No error
213
232
  processLogMessageBody(client, client->scalarReader.value());
214
233
  client->scalarReader.reset();
215
234
  }
@@ -308,6 +327,23 @@ private:
308
327
  void processLogMessageBody(Client *client, const StaticString &body) {
309
328
  // In here we process the scalar message that's expected to come
310
329
  // after the "log" command.
330
+
331
+ if (getLogLevel() == LVL_DEBUG) {
332
+ string truncatedBody;
333
+ if (body.size() > 97) {
334
+ string truncatedBody = body.substr(0, 97);
335
+ truncatedBody.append("...");
336
+ SKC_DEBUG(client, "Processing message body (" << body.size() <<
337
+ " bytes): " << truncatedBody);
338
+ } else {
339
+ SKC_DEBUG(client, "Processing message body (" << body.size() <<
340
+ " bytes): " << body);
341
+ }
342
+ } else if (getLogLevel() >= LVL_DEBUG2) {
343
+ SKC_TRACE(client, 2, "Processing message body (" << body.size() <<
344
+ " bytes): " << body);
345
+ }
346
+
311
347
  writeLogEntry(client,
312
348
  client->logCommandParams.transaction,
313
349
  client->logCommandParams.timestamp,
@@ -999,7 +1035,7 @@ protected:
999
1035
  virtual void reinitializeClient(Client *client, int fd) {
1000
1036
  ParentClass::reinitializeClient(client, fd);
1001
1037
  client->arrayReader.setMaxSize(1024 * 16);
1002
- client->scalarReader.setMaxSize(1024 * 128);
1038
+ client->scalarReader.setMaxSize(1024 * 1024);
1003
1039
  client->state = Client::READING_AUTH_USERNAME;
1004
1040
  client->type = Client::UNINITIALIZED;
1005
1041
  }
@@ -56,6 +56,13 @@ private:
56
56
  }
57
57
 
58
58
  public:
59
+ DataStoreId()
60
+ : id(NULL),
61
+ groupNameSize(0),
62
+ nodeNameSize(0),
63
+ categorySize(0)
64
+ { }
65
+
59
66
  DataStoreId(const StaticString &groupName, const StaticString &nodeName,
60
67
  const StaticString &category)
61
68
  {
@@ -87,13 +94,12 @@ public:
87
94
  *end = '\0';
88
95
  }
89
96
 
90
- DataStoreId() {
91
- id = NULL;
92
- }
93
-
94
97
  DataStoreId(const DataStoreId &other) {
95
98
  if (other.id == NULL) {
96
99
  id = NULL;
100
+ groupNameSize = 0;
101
+ nodeNameSize = 0;
102
+ categorySize = 0;
97
103
  } else {
98
104
  id = new char[other.totalSize()];
99
105
  memcpy(id, other.id, other.totalSize());
@@ -104,17 +110,17 @@ public:
104
110
  }
105
111
 
106
112
  ~DataStoreId() {
107
- delete id;
113
+ delete[] id;
108
114
  }
109
115
 
110
116
  DataStoreId &operator=(const DataStoreId &other) {
111
117
  if (other.id == NULL) {
112
- delete id;
118
+ delete[] id;
113
119
  id = NULL;
114
120
  return *this;
115
121
  } else {
116
122
  if (totalSize() != other.totalSize()) {
117
- delete id;
123
+ delete[] id;
118
124
  id = NULL;
119
125
  }
120
126
  if (id == NULL) {
@@ -73,6 +73,34 @@ private:
73
73
  };
74
74
 
75
75
  class Server {
76
+ public:
77
+ enum SendResult {
78
+ /**
79
+ * The gateway accepted the packet.
80
+ */
81
+ SR_OK,
82
+
83
+ /**
84
+ * Unable to contact the gateway: it appears to be down.
85
+ * Unable to obtain a valid HTTP response from the gateway.
86
+ */
87
+ SR_DOWN,
88
+
89
+ /**
90
+ * We were able to contact the gateway, but it appears to be
91
+ * responding with gibberish. It might be so that the gateway
92
+ * machine is up, but the actual service running inside is
93
+ * down or malfunctioning.
94
+ */
95
+ SR_MALFUNCTION,
96
+
97
+ /**
98
+ * We were able to contact the gateway, but the
99
+ * rejected the packet by responding with an error.
100
+ */
101
+ SR_REJECTED
102
+ };
103
+
76
104
  private:
77
105
  string ip;
78
106
  unsigned short port;
@@ -88,7 +116,14 @@ private:
88
116
  string pingURL;
89
117
  string sinkURL;
90
118
 
119
+ mutable boost::mutex syncher;
91
120
  string lastErrorMessage;
121
+ unsigned long long lastErrorTime;
122
+ unsigned long long lastSuccessTime;
123
+ unsigned int pingErrors;
124
+ unsigned int packetsAccepted;
125
+ unsigned int packetsRejected;
126
+ unsigned int packetsDropped;
92
127
 
93
128
  void resetConnection() {
94
129
  if (curl != NULL) {
@@ -146,7 +181,7 @@ private:
146
181
  }
147
182
  }
148
183
 
149
- bool handleSendResponse() {
184
+ SendResult handleSendResponse(const Item &item) {
150
185
  Json::Reader reader;
151
186
  Json::Value response;
152
187
  long httpCode = -1;
@@ -154,42 +189,88 @@ private:
154
189
  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
155
190
 
156
191
  if (!reader.parse(responseBody, response, false) || !validateResponse(response)) {
157
- lastErrorMessage = "The Union Station gateway server "
158
- + ip + " encountered an error while processing sent analytics data. "
159
- "It sent an invalid response (parse error: "
160
- + reader.getFormattedErrorMessages()
192
+ setRequestError(
193
+ "The Union Station gateway server " + ip +
194
+ " encountered an error while processing sent analytics data. "
195
+ "It sent an invalid response. Key: " + item.unionStationKey
196
+ + ". Parse error: " + reader.getFormattedErrorMessages()
161
197
  + "; HTTP code: " + toString(httpCode)
162
- + "; data: \"" + cEscapeString(responseBody) + "\")";
163
- P_ERROR(lastErrorMessage);
164
- return false;
198
+ + "; data: \"" + cEscapeString(responseBody) + "\"");
199
+ return SR_MALFUNCTION;
165
200
  } else if (response["status"].asString() == "ok") {
166
201
  if (httpCode == 200) {
167
- P_DEBUG("The Union Station gateway server " << ip << " accepted the packet.");
168
- return true;
202
+ handleResponseSuccess();
203
+ P_DEBUG("The Union Station gateway server " << ip
204
+ << " accepted the packet. Key: "
205
+ << item.unionStationKey);
206
+ return SR_OK;
169
207
  } else {
170
- lastErrorMessage = "The Union Station gateway server "
171
- + ip + " encountered an error while processing sent "
172
- "analytics data. It sent an invalid response "
173
- "(HTTP code: " + toString(httpCode)
174
- + "; data: \"" + cEscapeString(responseBody) + "\")";
175
- P_ERROR(lastErrorMessage);
176
- return false;
208
+ setRequestError(
209
+ "The Union Station gateway server " + ip
210
+ + " encountered an error while processing sent "
211
+ "analytics data. It sent an invalid response. Key: "
212
+ + item.unionStationKey + ". HTTP code: "
213
+ + toString(httpCode) + ". Data: \""
214
+ + cEscapeString(responseBody) + "\"");
215
+ return SR_MALFUNCTION;
177
216
  }
178
217
  } else {
179
218
  // response == error
180
- lastErrorMessage = "The Union Station gateway server "
219
+ setPacketRejectedError(
220
+ "The Union Station gateway server "
181
221
  + ip + " did not accept the sent analytics data. "
182
- "Error message: " + response["message"].asString();
183
- P_ERROR(lastErrorMessage);
184
- // Return value of true is intentional. See comment for send().
185
- return true;
222
+ "Key: " + item.unionStationKey + ". "
223
+ "Error: " + response["message"].asString());
224
+ return SR_REJECTED;
186
225
  }
187
226
  }
188
227
 
189
- void handleSendError() {
190
- lastErrorMessage = "Could not send data to Union Station gateway server " +
191
- ip + ": " + lastCurlErrorMessage;
192
- P_ERROR(lastErrorMessage);
228
+ void handleSendError(const Item &item) {
229
+ setRequestError(
230
+ "Could not send data to Union Station gateway server " +
231
+ ip + ". It might be down. Key: " + item.unionStationKey +
232
+ ". Error: " + lastCurlErrorMessage);
233
+ }
234
+
235
+ void setPingError(const string &message) {
236
+ boost::lock_guard<boost::mutex> l(syncher);
237
+ P_INFO(message);
238
+ setLastErrorMessage(message);
239
+ pingErrors++;
240
+ }
241
+
242
+ /**
243
+ * Handles the case when SendResult == SR_DOWN
244
+ * or SendResult == SR_MALFUNCTION.
245
+ * See SendResult comments for notes.
246
+ */
247
+ void setRequestError(const string &message) {
248
+ boost::lock_guard<boost::mutex> l(syncher);
249
+ P_ERROR(message);
250
+ setLastErrorMessage(message);
251
+ packetsDropped++;
252
+ }
253
+
254
+ /**
255
+ * Handles the case when SendResult == SR_REJECTED.
256
+ * See SendResult comments for notes.
257
+ */
258
+ void setPacketRejectedError(const string &message) {
259
+ boost::lock_guard<boost::mutex> l(syncher);
260
+ P_ERROR(message);
261
+ setLastErrorMessage(message);
262
+ packetsRejected++;
263
+ }
264
+
265
+ void setLastErrorMessage(const string &message) {
266
+ lastErrorMessage = message;
267
+ lastErrorTime = SystemTime::getUsec();
268
+ }
269
+
270
+ void handleResponseSuccess() {
271
+ boost::lock_guard<boost::mutex> l(syncher);
272
+ lastSuccessTime = SystemTime::getUsec();
273
+ packetsAccepted++;
193
274
  }
194
275
 
195
276
  static size_t curlDataReceived(void *buffer, size_t size, size_t nmemb, void *userData) {
@@ -199,12 +280,12 @@ private:
199
280
  }
200
281
 
201
282
  public:
202
- Server(const string &ip, const string &hostName, unsigned short port, const string &cert,
203
- const CurlProxyInfo *proxyInfo)
283
+ Server(const string &ip, const string &hostName, unsigned short port,
284
+ const string &cert, const CurlProxyInfo *proxyInfo)
204
285
  {
205
286
  this->ip = ip;
206
287
  this->port = port;
207
- certificate = cert;
288
+ this->certificate = cert;
208
289
  this->proxyInfo = proxyInfo;
209
290
 
210
291
  hostHeader = "Host: " + hostName;
@@ -222,6 +303,12 @@ private:
222
303
  "/sink";
223
304
 
224
305
  curl = NULL;
306
+ lastErrorTime = 0;
307
+ lastSuccessTime = 0;
308
+ pingErrors = 0;
309
+ packetsAccepted = 0;
310
+ packetsRejected = 0;
311
+ packetsDropped = 0;
225
312
  resetConnection();
226
313
  }
227
314
 
@@ -243,32 +330,24 @@ private:
243
330
 
244
331
  curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
245
332
  if (curl_easy_perform(curl) != 0) {
246
- lastErrorMessage = "Could not ping Union Station gateway server " +
247
- ip + ": " + lastCurlErrorMessage;
248
- P_INFO(lastErrorMessage);
333
+ setPingError(
334
+ "Could not ping Union Station gateway server " +
335
+ ip + ": " + lastCurlErrorMessage);
249
336
  return false;
250
337
  }
251
338
  if (responseBody == "pong") {
252
339
  guard.clear();
253
340
  return true;
254
341
  } else {
255
- lastErrorMessage = "Union Station gateway server " + ip +
342
+ setPingError(
343
+ "Union Station gateway server " + ip +
256
344
  " returned an unexpected ping message: " +
257
- responseBody;
258
- P_INFO(lastErrorMessage);
345
+ responseBody);
259
346
  return false;
260
347
  }
261
348
  }
262
349
 
263
- /** Returns true if the server is up, false if the server is down.
264
- * The return value does NOT indicate whether the server accepted the data!
265
- * Thus, if (for example) the Union Station key is invalid or disabled,
266
- * but the connection is fine, then this method still returns true.
267
- * This is because the return value is used to determine whether a different
268
- * gateway server should be used. If the server is up but rejects the data
269
- * then we'll want the code to keep sending future packets.
270
- */
271
- bool send(const Item &item) {
350
+ SendResult send(const Item &item) {
272
351
  ScopeGuard guard(boost::bind(&Server::resetConnection, this));
273
352
  prepareRequest(sinkURL);
274
353
 
@@ -320,21 +399,41 @@ private:
320
399
 
321
400
  if (code == CURLE_OK) {
322
401
  guard.clear();
323
- return handleSendResponse();
402
+ return handleSendResponse(item);
324
403
  } else {
325
- handleSendError();
326
- return false;
404
+ handleSendError(item);
405
+ return SR_DOWN;
327
406
  }
328
407
  }
329
408
 
330
409
  Json::Value inspectStateAsJson() const {
331
- Json::Value doc;
332
- doc["ip"] = ip;
333
- doc["port"] = port;
410
+ Json::Value doc, errorDoc;
411
+ doc["sink_url"] = sinkURL;
334
412
  doc["ping_url"] = pingURL;
413
+
414
+ boost::lock_guard<boost::mutex> l(syncher);
415
+
416
+ if (lastErrorTime == 0) {
417
+ doc["last_error_time"] = Json::Value(Json::nullValue);
418
+ } else {
419
+ doc["last_error_time"] = timeToJson(lastErrorTime);
420
+ }
335
421
  if (!lastErrorMessage.empty()) {
336
422
  doc["last_error_message"] = lastErrorMessage;
337
423
  }
424
+ if (lastSuccessTime == 0) {
425
+ doc["last_success_time"] = Json::Value(Json::nullValue);
426
+ } else {
427
+ doc["last_success_time"] = timeToJson(lastSuccessTime);
428
+ }
429
+
430
+ errorDoc["ping_errors"] = pingErrors;
431
+ errorDoc["packets_dropped"] = packetsDropped;
432
+ errorDoc["packets_rejected"] = packetsRejected;
433
+
434
+ doc["errors"] = errorDoc;
435
+ doc["packets_accepted"] = packetsAccepted;
436
+
338
437
  return doc;
339
438
  }
340
439
  };
@@ -353,7 +452,7 @@ private:
353
452
  vector<ServerPtr> downServers;
354
453
  time_t lastCheckupTime, nextCheckupTime;
355
454
  string lastDnsErrorMessage;
356
- unsigned int packetsSent, packetsDropped;
455
+ unsigned int packetsAccepted, packetsRejected, packetsDropped;
357
456
 
358
457
  void threadMain() {
359
458
  ScopeGuard guard(boost::bind(&RemoteSender::freeThreadData, this));
@@ -417,8 +516,9 @@ private:
417
516
  P_INFO(ips.size() << " Union Station gateway servers found");
418
517
 
419
518
  for (it = ips.begin(); it != ips.end(); it++) {
420
- ServerPtr server = boost::make_shared<Server>(*it, gatewayAddress, gatewayPort,
421
- certificate, &proxyInfo);
519
+ ServerPtr server = boost::make_shared<Server>(
520
+ *it, gatewayAddress, gatewayPort, certificate,
521
+ &proxyInfo);
422
522
  if (server->ping()) {
423
523
  upServers.push_back(server);
424
524
  } else {
@@ -479,29 +579,36 @@ private:
479
579
 
480
580
  void sendOut(const Item &item) {
481
581
  boost::unique_lock<boost::mutex> l(syncher);
482
- bool sent = false;
483
- bool someServersWentDown = false;
582
+ bool done = false;
583
+ bool accepted = false;
584
+ bool rejected = false;
484
585
 
485
- while (!sent && !upServers.empty()) {
586
+ while (!done && !upServers.empty()) {
486
587
  // Pick first available server and put it on the back of the list
487
588
  // for round-robin load balancing.
488
589
  ServerPtr server = upServers.front();
590
+
489
591
  l.unlock();
490
- if (server->send(item)) {
491
- l.lock();
592
+ Server::SendResult result = server->send(item);
593
+ l.lock();
594
+
595
+ if (result == Server::SR_OK) {
596
+ upServers.pop_front();
597
+ upServers.push_back(server);
598
+ accepted = true;
599
+ done = true;
600
+ } else if (result == Server::SR_REJECTED) {
492
601
  upServers.pop_front();
493
602
  upServers.push_back(server);
494
- sent = true;
495
- packetsSent++;
603
+ rejected = true;
604
+ done = true;
496
605
  } else {
497
- l.lock();
498
606
  upServers.pop_front();
499
607
  downServers.push_back(server);
500
- someServersWentDown = true;
501
608
  }
502
609
  }
503
610
 
504
- if (someServersWentDown) {
611
+ if (!downServers.empty()) {
505
612
  if (upServers.empty()) {
506
613
  scheduleNextCheckup(5 * 60);
507
614
  } else {
@@ -509,13 +616,21 @@ private:
509
616
  }
510
617
  }
511
618
 
512
- /* If all servers went down then all items in the queue will be
513
- * effectively dropped until after the next checkup has detected
514
- * servers that are up.
515
- */
516
- if (!sent) {
619
+ if (accepted) {
620
+ packetsAccepted++;
621
+ } else if (rejected) {
622
+ packetsRejected++;
623
+ } else {
517
624
  packetsDropped++;
518
- l.unlock();
625
+ }
626
+ l.unlock();
627
+
628
+ if (!accepted && !rejected) {
629
+ assert(upServers.empty());
630
+ /* If all servers went down then all items in the queue will be
631
+ * effectively dropped until after the next checkup has detected
632
+ * servers that are up.
633
+ */
519
634
  P_WARN("Dropping Union Station packet because no servers are"
520
635
  " available. Run `passenger-status --show=union_station` to"
521
636
  " view server status. Details of dropped packet:"
@@ -583,8 +698,8 @@ private:
583
698
  }
584
699
 
585
700
  public:
586
- RemoteSender(const string &gatewayAddress, unsigned short gatewayPort, const string &certificate,
587
- const string &proxyAddress)
701
+ RemoteSender(const string &gatewayAddress, unsigned short gatewayPort,
702
+ const string &certificate, const string &proxyAddress)
588
703
  : queue(1024)
589
704
  {
590
705
  TRACE_POINT();
@@ -599,7 +714,8 @@ public:
599
714
  }
600
715
  lastCheckupTime = 0;
601
716
  nextCheckupTime = 0;
602
- packetsSent = 0;
717
+ packetsAccepted = 0;
718
+ packetsRejected = 0;
603
719
  packetsDropped = 0;
604
720
  thr = new oxt::thread(
605
721
  boost::bind(&RemoteSender::threadMain, this),
@@ -667,7 +783,8 @@ public:
667
783
  doc["up_servers"] = inspectUpServersStateAsJson();
668
784
  doc["down_servers"] = inspectDownServersStateAsJson();
669
785
  doc["queue_size"] = queue.size();
670
- doc["packets_sent_to_gateway"] = packetsSent;
786
+ doc["packets_accepted"] = packetsAccepted;
787
+ doc["packets_rejected"] = packetsRejected;
671
788
  doc["packets_dropped"] = packetsDropped;
672
789
  if (certificate.empty()) {
673
790
  doc["certificate"] = Json::nullValue;
@@ -678,13 +795,13 @@ public:
678
795
  doc["last_server_checkup_time"] = Json::Value(Json::nullValue);
679
796
  doc["last_server_checkup_time_note"] = "not yet started";
680
797
  } else {
681
- doc["last_server_checkout_time"] = timeToJson(lastCheckupTime * 1000000.0);
798
+ doc["last_server_checkup_time"] = timeToJson(lastCheckupTime * 1000000.0);
682
799
  }
683
800
  if (nextCheckupTime == 0) {
684
801
  doc["next_server_checkup_time"] = Json::Value(Json::nullValue);
685
802
  doc["next_server_checkup_time_note"] = "not yet scheduled, waiting for first packet";
686
803
  } else {
687
- doc["next_server_checkout_time"] = timeToJson(nextCheckupTime * 1000000.0);
804
+ doc["next_server_checkup_time"] = timeToJson(nextCheckupTime * 1000000.0);
688
805
  }
689
806
  if (!lastDnsErrorMessage.empty()) {
690
807
  doc["last_dns_error_message"] = lastDnsErrorMessage;
@@ -37,9 +37,16 @@ protected:
37
37
  }
38
38
 
39
39
  virtual void execProgram() const {
40
- execl(agentFilename.c_str(), AGENT_EXE, "ust-router",
41
- // Some extra space to allow the child process to change its process title.
42
- " ", (char *) 0);
40
+ if (hasEnvOption("PASSENGER_RUN_UST_ROUTER_IN_VALGRIND", false)) {
41
+ execlp("valgrind", "valgrind", "--dsymutil=yes", "--track-origins=yes", "--leak-check=full",
42
+ agentFilename.c_str(), "ust-router",
43
+ // Some extra space to allow the child process to change its process title.
44
+ " ", (char *) 0);
45
+ } else {
46
+ execl(agentFilename.c_str(), AGENT_EXE, "ust-router",
47
+ // Some extra space to allow the child process to change its process title.
48
+ " ", (char *) 0);
49
+ }
43
50
  }
44
51
 
45
52
  virtual void sendStartupArguments(pid_t pid, FileDescriptor &fd) {
@@ -118,7 +118,7 @@
118
118
 
119
119
  #define PASSENGER_DEFAULT_USER "nobody"
120
120
 
121
- #define PASSENGER_VERSION "5.0.19"
121
+ #define PASSENGER_VERSION "5.0.20"
122
122
 
123
123
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
124
124
 
@@ -433,6 +433,7 @@ public:
433
433
  }
434
434
  headerReader.reset();
435
435
  buffer.clear();
436
+ result = StaticString();
436
437
  }
437
438
 
438
439
  size_t feed(const char *data, size_t size) {
@@ -589,7 +589,11 @@ cEscapeString(const StaticString &input) {
589
589
  char c = *current;
590
590
  if (c >= 32 && c <= 126) {
591
591
  // Printable ASCII.
592
- result.append(1, c);
592
+ if (c == '"') {
593
+ result.append("\"");
594
+ } else {
595
+ result.append(1, c);
596
+ }
593
597
  } else {
594
598
  char buf[sizeof("000")];
595
599
  unsigned int size;
@@ -30,7 +30,7 @@ module PhusionPassenger
30
30
 
31
31
  PACKAGE_NAME = 'passenger'
32
32
  # Run 'rake src/cxx_supportlib/Constants.h' after changing this number.
33
- VERSION_STRING = '5.0.19'
33
+ VERSION_STRING = '5.0.20'
34
34
 
35
35
  PREFERRED_NGINX_VERSION = '1.8.0'
36
36
  NGINX_SHA256_CHECKSUM = '23cca1239990c818d8f6da118320c4979aadf5386deda691b1b7c2c96b9df3d5'
@@ -505,6 +505,9 @@ module PhusionPassenger
505
505
  f.read.split("\n")
506
506
  end
507
507
  lines.each do |line|
508
+ # Get rid of trailing CR
509
+ line = line.strip
510
+
508
511
  if line !~ /^[\s\t]*#/ && line =~ /LoadModule[\s\t]+passenger_module[\s\t]+(.*)/
509
512
  module_path = $1
510
513
  occurrences += 1
@@ -28,7 +28,7 @@ If your application is a Rails application, then you should use the [union_stati
28
28
 
29
29
  ### Using with Passenger
30
30
 
31
- **Note: This documentation section only applies to Passenger X.X.X or later!**
31
+ **Note: This documentation section only applies to Passenger 5.0.20 or later!**
32
32
 
33
33
  If you use [Passenger](https://www.phusionpassenger.com/), then you do not need to install the `union_station_hooks_core` gem. `union_station_hooks_core` is bundled with Passenger.
34
34
 
@@ -1,6 +1,29 @@
1
+ # Union Station - https://www.unionstationapp.com/
2
+ # Copyright (c) 2015 Phusion Holding B.V.
3
+ #
4
+ # "Union Station" and "Passenger" are trademarks of Phusion Holding B.V.
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
+
1
24
  require 'shellwords'
2
25
 
3
- TRAVIS_PASSENGER_BRANCH = 'ust_router_rewrite'
26
+ TRAVIS_PASSENGER_BRANCH = 'master'
4
27
 
5
28
  desc 'Run tests'
6
29
  task :spec do
@@ -42,7 +42,7 @@ end
42
42
 
43
43
  # The UnionStationHooks module is the entry point to the
44
44
  # `union_station_hooks_core` gem's public API. Note that this API is only
45
- # available since Passenger X.X.X!
45
+ # available since Passenger 5.0.20!
46
46
  #
47
47
  # **_Not familiar with `union_station_hooks_core`? Please read the
48
48
  # [README](https://github.com/phusion/union_station_hooks_core)
@@ -39,6 +39,6 @@
39
39
  {
40
40
  :major => 2,
41
41
  :minor => 0,
42
- :tiny => 0,
43
- :string => '2.0.0'
42
+ :tiny => 1,
43
+ :string => '2.0.1'
44
44
  }
@@ -1,4 +1,4 @@
1
- # Union Station Ruby hooks core
1
+ # Union Station Ruby hooks rails
2
2
 
3
3
  [![Build Status](https://travis-ci.org/phusion/union_station_hooks_rails.svg?branch=master)](https://travis-ci.org/phusion/union_station_hooks_rails)
4
4
 
@@ -23,7 +23,7 @@
23
23
 
24
24
  ### Using with Passenger
25
25
 
26
- **Note: This documentation section only applies to Passenger X.X.X or later!**
26
+ **Note: This documentation section only applies to Passenger 5.0.20 or later!**
27
27
 
28
28
  If you use [Passenger](https://www.phusionpassenger.com/), then you do not need to install the `union_station_hooks_rails` gem. `union_station_hooks_rails` is bundled with Passenger.
29
29
 
@@ -87,11 +87,11 @@ It is currently not possible to use Union Station without Passenger. If you woul
87
87
 
88
88
  ## Legacy code
89
89
 
90
- Before Passenger X.X.X, the Union Station setup instructions used to tell you to create a `config/initializers/passenger.rb` in which you call the following code:
90
+ Before Passenger 5.0.20, the Union Station setup instructions used to tell you to create a `config/initializers/passenger.rb` in which you call the following code:
91
91
 
92
92
  PhusionPassenger.install_framework_extensions! if defined?(PhusionPassenger)
93
93
 
94
- Since Passenger X.X.X, `PhusionPassenger.install_framework_extensions!` has become an alias for `UnionStationHooks.initialize!`, but the former is considered deprecated. Please replace the above code with:
94
+ Since Passenger 5.0.20, `PhusionPassenger.install_framework_extensions!` has become an alias for `UnionStationHooks.initialize!`, but the former is considered deprecated. Please replace the above code with:
95
95
 
96
96
  if defined?(UnionStationHooks)
97
97
  UnionStationHooks.initialize!
@@ -21,7 +21,7 @@
21
21
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
  # THE SOFTWARE.
23
23
 
24
- TRAVIS_PASSENGER_BRANCH = 'ust_router_rewrite'
24
+ TRAVIS_PASSENGER_BRANCH = 'master'
25
25
 
26
26
  if defined?(Bundler)
27
27
  # Undo Bundler environment so that calls to 'bundle install' won't try to
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.19
4
+ version: 5.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phusion - http://www.phusion.nl/
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-24 00:00:00.000000000 Z
11
+ date: 2015-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  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
- iQEcBAABAgAGBQJWA7ACAAoJECrHRaUKISqM+rsIALHKdaseCTlPU8SRc1HEnQpJ
6
- Uha8cRLPB0ljub3xbMK6LPzPNdSF/5KN6TRYW6hFqsCmPTUmNiZ+fkK2c8z3NCyV
7
- G7sQHlN8qF47rNqejKlavQPKDUMKSWduvwzRsv0IEJgi2AABxmXrJF/POPB6zt9P
8
- JMIuMJGZURx5jFbt0216laOhteZ6vJPoD5kXHzJoKGQhSRwiLoQvCFcsrNR3GUt3
9
- zXPB7j4yF8ZpdxJE43PmiWz7qRcozQ0xAs3N+z0QWhnnfVjcwz9WQ/Exl/W32UqT
10
- XQ0FQeFjb4DcZTrg+jGISDVWP+faBY/9+sKVUR+0W+2CuJfJprobZhABWLa4fKE=
11
- =5KHy
5
+ iQEcBAABAgAGBQJWBVgtAAoJECrHRaUKISqMRaUH/ifqMnFYPxS/1O49K5nb4gkb
6
+ FcOkj3cz5RDAm2jtLifuwAVOmYb9XLyTsxcgc71qpfrJpC5e2O7Sufl7+ECMicdj
7
+ EeyxxtwvQxUl0QbPxKrgYDga3ezDtPMiBf7vXNyafHxep8jppuQ3N67+eE9VjA/H
8
+ S5/ZPqoQVqYZzKLEYUuB6eNrubCVKbTZcJXkx5ns9rs3QWsiZK/RNyuQdAanJNmM
9
+ z8ZpOXjaIW6QKn9e1lQMmtzXWD3KTARzVa0XiV0srd2nNF/+olOa1vTN+dpO71tP
10
+ RrjWwhrkjjdSnNmhJCLhU3b7sdsgtpHyzT99elyAxRmbEQEDlC74A727GRw+Hzc=
11
+ =X4J3
12
12
  -----END PGP SIGNATURE-----