passenger 5.0.5 → 5.0.6
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 +17 -0
- data/build/test_basics.rb +2 -2
- data/doc/Users guide Apache.html +47 -42
- data/doc/Users guide Apache.idmap.txt +23 -21
- data/doc/Users guide Nginx.html +47 -42
- data/doc/Users guide Nginx.idmap.txt +23 -21
- data/doc/Users guide Standalone.html +39 -34
- data/doc/Users guide Standalone.idmap.txt +19 -17
- data/doc/users_guide_snippets/installation.txt +5 -0
- data/ext/apache2/Configuration.hpp +0 -12
- data/ext/apache2/Hooks.cpp +31 -35
- data/ext/common/AgentsStarter.h +24 -19
- data/ext/common/BackgroundEventLoop.cpp +1 -0
- data/ext/common/Constants.h +1 -1
- data/ext/common/MemoryKit/mbuf.cpp +4 -0
- data/ext/common/ResourceLocator.h +1 -1
- data/ext/common/ServerKit/Context.h +20 -0
- data/ext/common/ServerKit/HeaderTable.h +12 -4
- data/ext/common/ServerKit/HttpHeaderParser.h +2 -2
- data/ext/common/agents/HelperAgent/RequestHandler.h +2 -0
- data/ext/common/agents/HelperAgent/RequestHandler/BufferBody.cpp +4 -2
- data/ext/common/agents/HelperAgent/RequestHandler/Client.h +3 -1
- data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +7 -0
- data/ext/common/agents/HelperAgent/RequestHandler/Hooks.cpp +5 -0
- data/ext/common/agents/HelperAgent/RequestHandler/SendRequest.cpp +34 -1
- data/ext/common/agents/HelperAgent/ResponseCache.h +14 -2
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +2 -2
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/config/admin_command_command.rb +52 -12
- data/lib/phusion_passenger/config/utils.rb +1 -1
- data/lib/phusion_passenger/standalone/start_command.rb +8 -3
- metadata +2 -2
- metadata.gz.asc +7 -7
data/ext/common/Constants.h
CHANGED
@@ -151,6 +151,10 @@ mbuf_block_put(struct mbuf_block *mbuf_block)
|
|
151
151
|
mbuf_block->pool->nfree_mbuf_blockq++;
|
152
152
|
mbuf_block->pool->nactive_mbuf_blockq--;
|
153
153
|
STAILQ_INSERT_HEAD(&mbuf_block->pool->free_mbuf_blockq, mbuf_block, next);
|
154
|
+
|
155
|
+
#ifdef MBUF_ENABLE_DEBUGGING
|
156
|
+
TAILQ_REMOVE(&mbuf_block->pool->active_mbuf_blockq, mbuf_block, active_q);
|
157
|
+
#endif
|
154
158
|
}
|
155
159
|
|
156
160
|
/*
|
@@ -169,7 +169,7 @@ public:
|
|
169
169
|
return path;
|
170
170
|
}
|
171
171
|
|
172
|
-
throw RuntimeException("Support binary " + name + " not found");
|
172
|
+
throw RuntimeException("Support binary " + name + " not found (tried: " + getSupportBinariesDir() + "/" + name + " and " + path + ")");
|
173
173
|
}
|
174
174
|
};
|
175
175
|
|
@@ -98,6 +98,26 @@ public:
|
|
98
98
|
* mbuf_pool.mbuf_block_chunk_size);
|
99
99
|
mbufDoc["active_memory"] = byteSizeToJson(mbuf_pool.nactive_mbuf_blockq
|
100
100
|
* mbuf_pool.mbuf_block_chunk_size);
|
101
|
+
#ifdef MBUF_ENABLE_DEBUGGING
|
102
|
+
struct MemoryKit::active_mbuf_block_list *list =
|
103
|
+
const_cast<struct MemoryKit::active_mbuf_block_list *>(
|
104
|
+
&mbuf_pool.active_mbuf_blockq);
|
105
|
+
struct MemoryKit::mbuf_block *block;
|
106
|
+
Json::Value listJson(Json::arrayValue);
|
107
|
+
|
108
|
+
TAILQ_FOREACH (block, list, active_q) {
|
109
|
+
Json::Value blockJson;
|
110
|
+
blockJson["refcount"] = block->refcount;
|
111
|
+
#ifdef MBUF_ENABLE_BACKTRACES
|
112
|
+
blockJson["backtrace"] =
|
113
|
+
(block->backtrace == NULL)
|
114
|
+
? "(null)"
|
115
|
+
: block->backtrace;
|
116
|
+
#endif
|
117
|
+
listJson.append(blockJson);
|
118
|
+
}
|
119
|
+
mbufDoc["active_blocks_list"] = listJson;
|
120
|
+
#endif
|
101
121
|
|
102
122
|
doc["mbuf_pool"] = mbufDoc;
|
103
123
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2014 Phusion
|
3
|
+
* Copyright (c) 2014-2015 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -239,8 +239,13 @@ public:
|
|
239
239
|
return const_cast<LString *>(static_cast<const HeaderTable *>(this)->lookup(key));
|
240
240
|
}
|
241
241
|
|
242
|
-
/**
|
243
|
-
|
242
|
+
/**
|
243
|
+
* HeaderTable takes over ownership of `header`. But you must ensure that the pool
|
244
|
+
* that the header was allocated from is not destroyed before the HeaderTable
|
245
|
+
* is destroyed or cleared.
|
246
|
+
*/
|
247
|
+
void insert(Header **headerPtr, psg_pool_t *pool) {
|
248
|
+
Header *header = *headerPtr;
|
244
249
|
assert(header->key.size < MAX_KEY_LENGTH);
|
245
250
|
|
246
251
|
if (m_cells == NULL) {
|
@@ -260,6 +265,7 @@ public:
|
|
260
265
|
m_population++;
|
261
266
|
|
262
267
|
cell->header = header;
|
268
|
+
*headerPtr = NULL;
|
263
269
|
return;
|
264
270
|
} else if (psg_lstr_cmp(&cell->header->key, &header->key)) {
|
265
271
|
// Cell matches, so merge value into header.
|
@@ -278,6 +284,8 @@ public:
|
|
278
284
|
psg_lstr_append_part(&cell->header->val, part);
|
279
285
|
part = next;
|
280
286
|
}
|
287
|
+
psg_lstr_deinit(&header->key);
|
288
|
+
*headerPtr = NULL;
|
281
289
|
return;
|
282
290
|
} else {
|
283
291
|
cell = PHT_CIRCULAR_NEXT(cell);
|
@@ -295,7 +303,7 @@ public:
|
|
295
303
|
psg_lstr_init(&header->val);
|
296
304
|
psg_lstr_append(&header->val, pool, value.data(), value.size());
|
297
305
|
header->hash = name.hash();
|
298
|
-
insert(header, pool);
|
306
|
+
insert(&header, pool);
|
299
307
|
return header;
|
300
308
|
}
|
301
309
|
|
@@ -106,9 +106,9 @@ private:
|
|
106
106
|
|
107
107
|
void insertCurrentHeader() {
|
108
108
|
if (!state->secureMode) {
|
109
|
-
message->headers.insert(state->currentHeader, pool);
|
109
|
+
message->headers.insert(&state->currentHeader, pool);
|
110
110
|
} else {
|
111
|
-
message->secureHeaders.insert(state->currentHeader, pool);
|
111
|
+
message->secureHeaders.insert(&state->currentHeader, pool);
|
112
112
|
}
|
113
113
|
}
|
114
114
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2015 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -34,6 +34,7 @@ beginBufferingBody(Client *client, Request *req) {
|
|
34
34
|
req->bodyChannel.start();
|
35
35
|
req->bodyBuffer.reinitialize();
|
36
36
|
req->bodyBuffer.stop();
|
37
|
+
req->beginScopeLog(&req->scopeLogs.bufferingRequestBody, "buffering request body");
|
37
38
|
}
|
38
39
|
|
39
40
|
Channel::Result
|
@@ -77,8 +78,9 @@ whenBufferingBody_onRequestBody(Client *client, Request *req,
|
|
77
78
|
sizeof("content-length") - 1).hash();
|
78
79
|
|
79
80
|
req->headers.erase(HTTP_TRANSFER_ENCODING);
|
80
|
-
req->headers.insert(header, req->pool);
|
81
|
+
req->headers.insert(&header, req->pool);
|
81
82
|
}
|
83
|
+
req->endScopeLog(&req->scopeLogs.bufferingRequestBody);
|
82
84
|
checkoutSession(client, req);
|
83
85
|
return Channel::Result(0, true);
|
84
86
|
} else {
|
@@ -981,6 +981,7 @@ void
|
|
981
981
|
handleAppResponseBodyEnd(Client *client, Request *req) {
|
982
982
|
keepAliveAppConnection(client, req);
|
983
983
|
storeAppResponseInTurboCache(client, req);
|
984
|
+
finalizeUnionStationWithSuccess(client, req);
|
984
985
|
}
|
985
986
|
|
986
987
|
OXT_FORCE_INLINE void
|
@@ -1022,3 +1023,9 @@ storeAppResponseInTurboCache(Client *client, Request *req) {
|
|
1022
1023
|
}
|
1023
1024
|
}
|
1024
1025
|
}
|
1026
|
+
|
1027
|
+
void
|
1028
|
+
finalizeUnionStationWithSuccess(Client *client, Request *req) {
|
1029
|
+
req->endScopeLog(&req->scopeLogs.requestProcessing, true);
|
1030
|
+
req->endScopeLog(&req->scopeLogs.requestProxying, true);
|
1031
|
+
}
|
@@ -114,6 +114,8 @@ virtual void deinitializeRequest(Client *client, Request *req) {
|
|
114
114
|
req->endScopeLog(&req->scopeLogs.bufferingRequestBody, false);
|
115
115
|
req->endScopeLog(&req->scopeLogs.requestProcessing, false);
|
116
116
|
|
117
|
+
req->options.transaction.reset();
|
118
|
+
|
117
119
|
req->appSink.setConsumedCallback(NULL);
|
118
120
|
req->appSink.deinitialize();
|
119
121
|
req->appSource.deinitialize();
|
@@ -185,6 +187,9 @@ void deinitializeAppResponse(Client *client, Request *req) {
|
|
185
187
|
resp->headers.clear();
|
186
188
|
resp->secureHeaders.clear();
|
187
189
|
|
190
|
+
if (resp->setCookie != NULL) {
|
191
|
+
psg_lstr_deinit(resp->setCookie);
|
192
|
+
}
|
188
193
|
psg_lstr_deinit(&resp->bodyCacheBuffer);
|
189
194
|
}
|
190
195
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2015 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -89,7 +89,17 @@ struct SessionProtocolWorkingState {
|
|
89
89
|
const LString *remoteUser;
|
90
90
|
const LString *contentType;
|
91
91
|
const LString *contentLength;
|
92
|
+
char *environmentVariablesData;
|
93
|
+
size_t environmentVariablesSize;
|
92
94
|
bool hasBaseURI;
|
95
|
+
|
96
|
+
SessionProtocolWorkingState()
|
97
|
+
: environmentVariablesData(NULL)
|
98
|
+
{ }
|
99
|
+
|
100
|
+
~SessionProtocolWorkingState() {
|
101
|
+
free(environmentVariablesData);
|
102
|
+
}
|
93
103
|
};
|
94
104
|
|
95
105
|
void
|
@@ -183,6 +193,21 @@ determineHeaderSizeForSessionProtocol(Request *req,
|
|
183
193
|
} else {
|
184
194
|
state.contentLength = NULL;
|
185
195
|
}
|
196
|
+
if (!req->options.environmentVariables.empty()) {
|
197
|
+
size_t len = modp_b64_decode_len(req->options.environmentVariables.size());
|
198
|
+
state.environmentVariablesData = (char *) malloc(len);
|
199
|
+
if (state.environmentVariablesData == NULL) {
|
200
|
+
throw RuntimeException("Unable to allocate memory for base64 "
|
201
|
+
"decoding of environment variables");
|
202
|
+
}
|
203
|
+
len = modp_b64_decode(state.environmentVariablesData,
|
204
|
+
req->options.environmentVariables.data(),
|
205
|
+
req->options.environmentVariables.size());
|
206
|
+
if (len == (size_t) -1) {
|
207
|
+
throw RuntimeException("Unable to base64 decode environment variables");
|
208
|
+
}
|
209
|
+
state.environmentVariablesSize = len;
|
210
|
+
}
|
186
211
|
|
187
212
|
dataSize += sizeof("REQUEST_URI");
|
188
213
|
dataSize += req->path.size + 1;
|
@@ -289,6 +314,10 @@ determineHeaderSizeForSessionProtocol(Request *req,
|
|
289
314
|
it.next();
|
290
315
|
}
|
291
316
|
|
317
|
+
if (state.environmentVariablesData != NULL) {
|
318
|
+
dataSize += state.environmentVariablesSize;
|
319
|
+
}
|
320
|
+
|
292
321
|
return dataSize + 1;
|
293
322
|
}
|
294
323
|
|
@@ -427,6 +456,10 @@ constructHeaderForSessionProtocol(Request *req, char * restrict buffer, unsigned
|
|
427
456
|
it.next();
|
428
457
|
}
|
429
458
|
|
459
|
+
if (state.environmentVariablesData != NULL) {
|
460
|
+
pos = appendData(pos, end, state.environmentVariablesData, state.environmentVariablesSize);
|
461
|
+
}
|
462
|
+
|
430
463
|
Uint32Message::generate(buffer, pos - buffer - sizeof(boost::uint32_t));
|
431
464
|
|
432
465
|
size = pos - buffer;
|
@@ -60,7 +60,10 @@ public:
|
|
60
60
|
time_t date;
|
61
61
|
|
62
62
|
Header()
|
63
|
-
: valid(false)
|
63
|
+
: valid(false),
|
64
|
+
keySize(0),
|
65
|
+
hash(0),
|
66
|
+
date(0)
|
64
67
|
{ }
|
65
68
|
};
|
66
69
|
|
@@ -72,6 +75,14 @@ public:
|
|
72
75
|
char httpHeaderData[MAX_HEADER_SIZE];
|
73
76
|
// This data is dechunked.
|
74
77
|
char httpBodyData[MAX_BODY_SIZE];
|
78
|
+
|
79
|
+
Body()
|
80
|
+
: httpHeaderSize(0),
|
81
|
+
httpBodySize(0),
|
82
|
+
expiryDate(0)
|
83
|
+
{
|
84
|
+
key[0] = httpHeaderData[0] = httpBodyData[0] = '\0';
|
85
|
+
}
|
75
86
|
};
|
76
87
|
|
77
88
|
struct Entry {
|
@@ -571,7 +582,8 @@ public:
|
|
571
582
|
req->appResponse.cacheControl->start->data,
|
572
583
|
req->appResponse.cacheControl->size);
|
573
584
|
if (cacheControl.find(P_STATIC_STRING("no-store")) != string::npos
|
574
|
-
|| cacheControl.find(P_STATIC_STRING("private")) != string::npos
|
585
|
+
|| cacheControl.find(P_STATIC_STRING("private")) != string::npos
|
586
|
+
|| cacheControl.find(P_STATIC_STRING("no-cache")) != string::npos)
|
575
587
|
{
|
576
588
|
return false;
|
577
589
|
}
|
@@ -37,8 +37,8 @@ protected:
|
|
37
37
|
|
38
38
|
virtual void execProgram() const {
|
39
39
|
if (hasEnvOption("PASSENGER_RUN_HELPER_AGENT_IN_VALGRIND", false)) {
|
40
|
-
execlp("valgrind", "valgrind", "--dsymutil=yes",
|
41
|
-
agentFilename.c_str(),
|
40
|
+
execlp("valgrind", "valgrind", "--dsymutil=yes", "--track-origins=yes", "--leak-check=full",
|
41
|
+
agentFilename.c_str(), "server",
|
42
42
|
// Some extra space to allow the child process to change its process title.
|
43
43
|
" ", (char *) 0);
|
44
44
|
} else {
|
data/lib/phusion_passenger.rb
CHANGED
@@ -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 = '5.0.
|
33
|
+
VERSION_STRING = '5.0.6'
|
34
34
|
|
35
35
|
PREFERRED_NGINX_VERSION = '1.6.2'
|
36
36
|
NGINX_SHA256_CHECKSUM = 'b5608c2959d3e7ad09b20fc8f9e5bd4bc87b3bc8ba5936a513c04ed8f1391a18'
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
-
# Copyright (c) 2014 Phusion
|
2
|
+
# Copyright (c) 2014-2015 Phusion
|
3
3
|
#
|
4
4
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
5
5
|
#
|
@@ -37,13 +37,13 @@ module PhusionPassenger
|
|
37
37
|
include PhusionPassenger::Config::Utils
|
38
38
|
|
39
39
|
def self.create_default_options
|
40
|
-
return { :
|
40
|
+
return { :agent_name => "server_admin" }
|
41
41
|
end
|
42
42
|
|
43
43
|
def run
|
44
44
|
parse_options
|
45
45
|
initialize_objects
|
46
|
-
|
46
|
+
infer_socket_path_and_credentials
|
47
47
|
invoke
|
48
48
|
end
|
49
49
|
|
@@ -62,17 +62,22 @@ module PhusionPassenger
|
|
62
62
|
opts.separator " METHOD is an HTTP verb, like 'GET', 'POST', 'PUT' or 'DELETE'."
|
63
63
|
opts.separator " PATH is the admin URI. You can pass POST data with '-d'."
|
64
64
|
opts.separator ""
|
65
|
-
opts.separator " Example: passenger-config admin-command GET /server.json"
|
65
|
+
opts.separator " Example 1: passenger-config admin-command GET /server.json"
|
66
66
|
opts.separator " Sends the 'GET /server.json' command to the HTTP server agent."
|
67
67
|
opts.separator ""
|
68
|
-
opts.separator " Example: passenger-config admin-command PUT /config.json \\"
|
69
|
-
opts.separator "
|
68
|
+
opts.separator " Example 2: passenger-config admin-command PUT /config.json \\"
|
69
|
+
opts.separator " -d '{\"log_level\", 7}'"
|
70
70
|
opts.separator " Sends the 'PUT /config.json' command to the HTTP server agent, with the"
|
71
71
|
opts.separator " given PUT data."
|
72
72
|
opts.separator ""
|
73
|
-
opts.separator " Example: passenger-config admin-command POST /shutdown.json -a watchdog"
|
73
|
+
opts.separator " Example 3: passenger-config admin-command POST /shutdown.json -a watchdog"
|
74
74
|
opts.separator " Sends the 'POST /shutdown.json' command to the watchdog, with no POST data."
|
75
75
|
opts.separator ""
|
76
|
+
opts.separator " Example 4: passenger-config admin-command POST /shutdown.json \\"
|
77
|
+
opts.separator " -S /tmp/watchdog.sock"
|
78
|
+
opts.separator " Sends the 'POST /shutdown.json' command to the watchdog listening at the"
|
79
|
+
opts.separator " specific socket file /tmp/watchdog.sock. No POST data."
|
80
|
+
opts.separator ""
|
76
81
|
|
77
82
|
opts.separator "Options:"
|
78
83
|
opts.on("-d", "--data DATA", String, "Specify HTTP request body data") do |value|
|
@@ -90,12 +95,19 @@ module PhusionPassenger
|
|
90
95
|
"is sent to. Choices: watchdog,#{nl}" +
|
91
96
|
"server_admin, logging_admin.#{nl}" +
|
92
97
|
"Default: server_admin") do |val|
|
93
|
-
options[:
|
98
|
+
options[:agent_name] = val
|
99
|
+
end
|
100
|
+
opts.on("-S", "--socket PATH", String, "Instead of inferring the socket path from#{nl}" +
|
101
|
+
"the #{PROGRAM_NAME} instance directory#{nl}" +
|
102
|
+
"and agent name, send the command to a#{nl}" +
|
103
|
+
"specific Unix domain socket directly") do |val|
|
104
|
+
options[:socket_path] = val
|
94
105
|
end
|
95
106
|
opts.on("--show-headers", "Show HTTP response headers") do
|
96
107
|
options[:show_headers] = true
|
97
108
|
end
|
98
|
-
opts.on("--ignore-response-code", "Exit successfully even if a non-2xx
|
109
|
+
opts.on("--ignore-response-code", "Exit successfully even if a non-2xx#{nl}" +
|
110
|
+
"response was returned") do
|
99
111
|
options[:ignore_response_code] = true
|
100
112
|
end
|
101
113
|
opts.on("--instance NAME", String, "The #{PROGRAM_NAME} instance to select") do |value|
|
@@ -144,15 +156,43 @@ module PhusionPassenger
|
|
144
156
|
end
|
145
157
|
end
|
146
158
|
|
159
|
+
def infer_socket_path_and_credentials
|
160
|
+
if @options[:socket_path]
|
161
|
+
@socket_path = @options[:socket_path]
|
162
|
+
else
|
163
|
+
select_passenger_instance
|
164
|
+
@socket_path = "#{@instance.path}/agents.s/#{@options[:agent_name]}"
|
165
|
+
@password = obtain_full_admin_password(@instance)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
147
169
|
def invoke
|
148
|
-
|
149
|
-
|
170
|
+
if @password
|
171
|
+
@request.basic_auth("admin", @password)
|
172
|
+
end
|
150
173
|
@request["connection"] = "close"
|
151
174
|
if @options[:data]
|
152
175
|
@request.content_type = "application/json"
|
153
176
|
@request.body = @options[:data]
|
154
177
|
end
|
155
|
-
|
178
|
+
|
179
|
+
sock = Net::BufferedIO.new(UNIXSocket.new(@socket_path))
|
180
|
+
begin
|
181
|
+
@request.exec(sock, "1.1", @request.path)
|
182
|
+
|
183
|
+
done = false
|
184
|
+
while !done
|
185
|
+
response = Net::HTTPResponse.read_new(sock)
|
186
|
+
done = !response.kind_of?(Net::HTTPContinue)
|
187
|
+
end
|
188
|
+
|
189
|
+
response.reading_body(sock, @request.response_body_permitted?) do
|
190
|
+
# Nothing
|
191
|
+
end
|
192
|
+
ensure
|
193
|
+
sock.close
|
194
|
+
end
|
195
|
+
|
156
196
|
if @options[:show_headers]
|
157
197
|
print_headers(response)
|
158
198
|
end
|