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 +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/CHANGELOG +8 -0
- data/src/agent/UstRouter/Controller.h +38 -2
- data/src/agent/UstRouter/DataStoreId.h +13 -7
- data/src/agent/UstRouter/RemoteSender.h +192 -75
- data/src/agent/Watchdog/UstRouterWatcher.cpp +10 -3
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/cxx_supportlib/MessageReadersWriters.h +1 -0
- data/src/cxx_supportlib/Utils/StrIntUtils.cpp +5 -1
- data/src/ruby_supportlib/phusion_passenger.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/config/validate_install_command.rb +3 -0
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README.md +1 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Rakefile +24 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/README.md +4 -4
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Rakefile +1 -1
- metadata +2 -2
- metadata.gz.asc +7 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OGU3ZWRlNTY4YTI4N2JiYjg2M2U2YTlmMjg0OTEwNWU1M2JkZWRjMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NGFhZjc4YWI1MTNhZTU5NTk3ZGY2MWZkYmUwZjZmMDBhNDdmODk4Nw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDA0ZmIyNmY2ODQ0ODdhMDlkNzkzODgwNjk1MTQ1ZTc0ODhmZDdjNDRkOWI2
|
10
|
+
OWMyYTM4ZmIyZjA3NTQ3NmRiMTM2NjNmMmNmNmJkZjliODg3MDQ0M2FiZjIy
|
11
|
+
NDYyNzY1ZTBhMmQ3MWMyZDM0MDdhOTVmOTczZjNmMTNjOWQxZjI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
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:
|
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 *
|
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
|
-
|
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
|
-
|
158
|
-
|
159
|
-
"
|
160
|
-
+
|
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
|
-
|
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
|
-
|
168
|
-
|
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
|
-
|
171
|
-
|
172
|
-
"
|
173
|
-
"
|
174
|
-
+
|
175
|
-
|
176
|
-
|
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
|
-
|
219
|
+
setPacketRejectedError(
|
220
|
+
"The Union Station gateway server "
|
181
221
|
+ ip + " did not accept the sent analytics data. "
|
182
|
-
"
|
183
|
-
|
184
|
-
|
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
|
-
|
191
|
-
|
192
|
-
|
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,
|
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
|
-
|
247
|
-
|
248
|
-
|
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
|
-
|
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
|
-
|
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
|
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["
|
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
|
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>(
|
421
|
-
certificate,
|
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
|
483
|
-
bool
|
582
|
+
bool done = false;
|
583
|
+
bool accepted = false;
|
584
|
+
bool rejected = false;
|
484
585
|
|
485
|
-
while (!
|
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
|
-
|
491
|
-
|
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
|
-
|
495
|
-
|
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 (
|
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
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
619
|
+
if (accepted) {
|
620
|
+
packetsAccepted++;
|
621
|
+
} else if (rejected) {
|
622
|
+
packetsRejected++;
|
623
|
+
} else {
|
517
624
|
packetsDropped++;
|
518
|
-
|
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,
|
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
|
-
|
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["
|
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["
|
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["
|
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
|
-
|
41
|
-
|
42
|
-
|
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) {
|
@@ -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
|
-
|
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.
|
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
|
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 = '
|
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
|
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)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Union Station Ruby hooks
|
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
|
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
|
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
|
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 = '
|
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.
|
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-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
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-----
|