passenger 5.0.0.beta2 → 5.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (73) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/CHANGELOG +30 -0
  5. data/CONTRIBUTORS +2 -0
  6. data/Gemfile.lock +1 -1
  7. data/bin/passenger-status +13 -15
  8. data/build/cxx_tests.rb +14 -1
  9. data/build/preprocessor.rb +4 -2
  10. data/debian.template/control.template +2 -2
  11. data/doc/Security of user switching support.txt +2 -2
  12. data/doc/Users guide Apache.idmap.txt +6 -4
  13. data/doc/Users guide Apache.txt +20 -1
  14. data/doc/Users guide Nginx.idmap.txt +5 -3
  15. data/doc/Users guide Nginx.txt +22 -2
  16. data/ext/apache2/Configuration.cpp +6 -0
  17. data/ext/apache2/Configuration.hpp +4 -1
  18. data/ext/apache2/Hooks.cpp +1 -0
  19. data/ext/common/Constants.h +4 -2
  20. data/ext/common/Constants.h.erb +1 -1
  21. data/ext/common/DataStructures/LString.h +10 -0
  22. data/ext/common/ServerKit/Channel.h +1 -1
  23. data/ext/common/ServerKit/Context.h +2 -21
  24. data/ext/common/ServerKit/CookieUtils.h +246 -0
  25. data/ext/common/ServerKit/FdSourceChannel.h +10 -0
  26. data/ext/common/ServerKit/FileBufferedChannel.h +173 -17
  27. data/ext/common/ServerKit/FileBufferedFdSinkChannel.h +33 -1
  28. data/ext/common/ServerKit/HeaderTable.h +3 -1
  29. data/ext/common/ServerKit/HttpServer.h +36 -8
  30. data/ext/common/ServerKit/Server.h +1 -0
  31. data/ext/common/Utils.cpp +2 -1
  32. data/ext/common/Utils/DateParsing.h +15 -2
  33. data/ext/common/Utils/JsonUtils.h +39 -1
  34. data/ext/common/agents/HelperAgent/Main.cpp +4 -2
  35. data/ext/common/agents/HelperAgent/OptionParser.h +14 -2
  36. data/ext/common/agents/HelperAgent/RequestHandler.h +22 -8
  37. data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +92 -11
  38. data/ext/common/agents/HelperAgent/RequestHandler/Hooks.cpp +3 -1
  39. data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +9 -5
  40. data/ext/common/agents/HelperAgent/RequestHandler/Request.h +1 -0
  41. data/ext/common/agents/HelperAgent/RequestHandler/SendRequest.cpp +27 -13
  42. data/ext/common/agents/HelperAgent/ResponseCache.h +91 -34
  43. data/ext/common/agents/LoggingAgent/AdminServer.h +21 -1
  44. data/ext/nginx/CacheLocationConfig.c +20 -0
  45. data/ext/nginx/Configuration.c +130 -24
  46. data/ext/nginx/Configuration.h +2 -1
  47. data/ext/nginx/ConfigurationCommands.c +10 -0
  48. data/ext/nginx/ConfigurationFields.h +2 -0
  49. data/ext/nginx/ContentHandler.c +1 -6
  50. data/ext/nginx/CreateLocationConfig.c +5 -0
  51. data/ext/nginx/MergeLocationConfig.c +6 -0
  52. data/ext/nginx/StaticContentHandler.c +3 -9
  53. data/ext/nginx/ngx_http_passenger_module.c +2 -1
  54. data/ext/ruby/extconf.rb +5 -4
  55. data/lib/phusion_passenger.rb +2 -2
  56. data/lib/phusion_passenger/constants.rb +2 -1
  57. data/lib/phusion_passenger/nginx/config_options.rb +5 -1
  58. data/lib/phusion_passenger/rack/thread_handler_extension.rb +3 -1
  59. data/lib/phusion_passenger/ruby_core_enhancements.rb +3 -4
  60. data/lib/phusion_passenger/standalone/start_command.rb +5 -1
  61. data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +10 -3
  62. data/resources/templates/standalone/config.erb +2 -1
  63. data/test/cxx/DateParsingTest.cpp +75 -0
  64. data/test/cxx/ResponseCacheTest.cpp +322 -0
  65. data/test/cxx/ServerKit/CookieUtilsTest.cpp +274 -0
  66. data/test/cxx/ServerKit/HttpServerTest.cpp +77 -0
  67. data/test/stub/rails3.0/Gemfile.lock +2 -2
  68. data/test/stub/rails3.1/Gemfile.lock +2 -2
  69. data/test/stub/rails3.2/Gemfile.lock +2 -2
  70. data/test/stub/rails4.0/Gemfile.lock +2 -2
  71. data/test/stub/rails4.1/Gemfile.lock +2 -2
  72. metadata +6 -2
  73. metadata.gz.asc +7 -7
@@ -0,0 +1,274 @@
1
+ #include <TestSupport.h>
2
+ #include <ServerKit/CookieUtils.h>
3
+
4
+ using namespace Passenger;
5
+ using namespace Passenger::ServerKit;
6
+ using namespace std;
7
+
8
+ namespace tut {
9
+ struct ServerKit_CookieUtilsTest {
10
+ psg_pool_t *pool;
11
+ LString name;
12
+ LString value;
13
+ LString header;
14
+ LString *result;
15
+
16
+ ServerKit_CookieUtilsTest() {
17
+ pool = psg_create_pool(PSG_DEFAULT_POOL_SIZE);
18
+ psg_lstr_init(&name);
19
+ psg_lstr_append(&name, pool, "foo");
20
+ psg_lstr_init(&value);
21
+ psg_lstr_append(&value, pool, "bar");
22
+ psg_lstr_init(&header);
23
+ result = NULL;
24
+ }
25
+
26
+ ~ServerKit_CookieUtilsTest() {
27
+ psg_lstr_deinit(&name);
28
+ psg_lstr_deinit(&value);
29
+ psg_lstr_deinit(&header);
30
+ if (result != NULL) {
31
+ psg_lstr_deinit(result);
32
+ }
33
+ psg_destroy_pool(pool);
34
+ }
35
+ };
36
+
37
+ DEFINE_TEST_GROUP(ServerKit_CookieUtilsTest);
38
+
39
+ TEST_METHOD(1) {
40
+ set_test_name("1 cookie in 1 part");
41
+ psg_lstr_append(&header, pool, "foo=bar");
42
+
43
+ result = findCookie(pool, &header, &name);
44
+ ensure("(1)", result != NULL);
45
+ ensure("(2)", psg_lstr_cmp(result, &value));
46
+ }
47
+
48
+
49
+ TEST_METHOD(2) {
50
+ set_test_name("1 cookie in multiple parts (1)");
51
+ psg_lstr_append(&header, pool, "fo");
52
+ psg_lstr_append(&header, pool, "o=");
53
+ psg_lstr_append(&header, pool, "bar");
54
+
55
+ result = findCookie(pool, &header, &name);
56
+ ensure("(1)", result != NULL);
57
+ ensure("(2)", psg_lstr_cmp(result, &value));
58
+ }
59
+
60
+ TEST_METHOD(3) {
61
+ set_test_name("1 cookie in multiple parts (2)");
62
+ psg_lstr_append(&header, pool, "foo");
63
+ psg_lstr_append(&header, pool, "=");
64
+ psg_lstr_append(&header, pool, "bar");
65
+
66
+ result = findCookie(pool, &header, &name);
67
+ ensure("(1)", result != NULL);
68
+ ensure("(2)", psg_lstr_cmp(result, &value));
69
+ }
70
+
71
+ TEST_METHOD(4) {
72
+ set_test_name("1 cookie in multiple parts (3)");
73
+ psg_lstr_append(&header, pool, "foo=");
74
+ psg_lstr_append(&header, pool, "bar");
75
+
76
+ result = findCookie(pool, &header, &name);
77
+ ensure("(1)", result != NULL);
78
+ ensure("(2)", psg_lstr_cmp(result, &value));
79
+ }
80
+
81
+ TEST_METHOD(5) {
82
+ set_test_name("1 cookie in multiple parts (4)");
83
+ psg_lstr_append(&header, pool, "foo=b");
84
+ psg_lstr_append(&header, pool, "ar");
85
+
86
+ result = findCookie(pool, &header, &name);
87
+ ensure("(1)", result != NULL);
88
+ ensure("(2)", psg_lstr_cmp(result, &value));
89
+ }
90
+
91
+
92
+ TEST_METHOD(10) {
93
+ set_test_name("Multiple cookies in 1 part (1)");
94
+ psg_lstr_append(&header, pool, "foo=bar; hello=world");
95
+
96
+ result = findCookie(pool, &header, &name);
97
+ ensure("(1)", result != NULL);
98
+ ensure("(2)", psg_lstr_cmp(result, &value));
99
+ }
100
+
101
+ TEST_METHOD(11) {
102
+ set_test_name("Multiple cookies in 1 part (2)");
103
+ psg_lstr_append(&header, pool, "hello=world; foo=bar");
104
+
105
+ result = findCookie(pool, &header, &name);
106
+ ensure("(1)", result != NULL);
107
+ ensure("(2)", psg_lstr_cmp(result, &value));
108
+ }
109
+
110
+ TEST_METHOD(12) {
111
+ set_test_name("Multiple cookies in 1 part (3)");
112
+ psg_lstr_append(&header, pool, "hello=world; foo=bar; a=b");
113
+
114
+ result = findCookie(pool, &header, &name);
115
+ ensure("(1)", result != NULL);
116
+ ensure("(2)", psg_lstr_cmp(result, &value));
117
+ }
118
+
119
+
120
+ TEST_METHOD(15) {
121
+ set_test_name("Multiple cookies in multiple parts (1)");
122
+ psg_lstr_append(&header, pool, "fo");
123
+ psg_lstr_append(&header, pool, "o=bar; hello=world");
124
+
125
+ result = findCookie(pool, &header, &name);
126
+ ensure("(1)", result != NULL);
127
+ ensure("(2)", psg_lstr_cmp(result, &value));
128
+ }
129
+
130
+ TEST_METHOD(16) {
131
+ set_test_name("Multiple cookies in multiple parts (2)");
132
+ psg_lstr_append(&header, pool, "foo");
133
+ psg_lstr_append(&header, pool, "=");
134
+ psg_lstr_append(&header, pool, "bar; hello=world");
135
+
136
+ result = findCookie(pool, &header, &name);
137
+ ensure("(1)", result != NULL);
138
+ ensure("(2)", psg_lstr_cmp(result, &value));
139
+ }
140
+
141
+ TEST_METHOD(17) {
142
+ set_test_name("Multiple cookies in multiple parts (3)");
143
+ psg_lstr_append(&header, pool, "foo");
144
+ psg_lstr_append(&header, pool, "=bar; hello=world");
145
+
146
+ result = findCookie(pool, &header, &name);
147
+ ensure("(1)", result != NULL);
148
+ ensure("(2)", psg_lstr_cmp(result, &value));
149
+ }
150
+
151
+ TEST_METHOD(18) {
152
+ set_test_name("Multiple cookies in multiple parts (4)");
153
+ psg_lstr_append(&header, pool, "foo=");
154
+ psg_lstr_append(&header, pool, "bar; hello=world");
155
+
156
+ result = findCookie(pool, &header, &name);
157
+ ensure("(1)", result != NULL);
158
+ ensure("(2)", psg_lstr_cmp(result, &value));
159
+ }
160
+
161
+ TEST_METHOD(19) {
162
+ set_test_name("Multiple cookies in multiple parts (5)");
163
+ psg_lstr_append(&header, pool, "foo=b");
164
+ psg_lstr_append(&header, pool, "ar; hello=world");
165
+
166
+ result = findCookie(pool, &header, &name);
167
+ ensure("(1)", result != NULL);
168
+ ensure("(2)", psg_lstr_cmp(result, &value));
169
+ }
170
+
171
+
172
+ TEST_METHOD(20) {
173
+ set_test_name("Multiple cookies in multiple parts (6)");
174
+ psg_lstr_append(&header, pool, "hello=world; fo");
175
+ psg_lstr_append(&header, pool, "o=bar");
176
+
177
+ result = findCookie(pool, &header, &name);
178
+ ensure("(1)", result != NULL);
179
+ ensure("(2)", psg_lstr_cmp(result, &value));
180
+ }
181
+
182
+ TEST_METHOD(21) {
183
+ set_test_name("Multiple cookies in multiple parts (7)");
184
+ psg_lstr_append(&header, pool, "hello=world; foo");
185
+ psg_lstr_append(&header, pool, "=");
186
+ psg_lstr_append(&header, pool, "bar");
187
+
188
+ result = findCookie(pool, &header, &name);
189
+ ensure("(1)", result != NULL);
190
+ ensure("(2)", psg_lstr_cmp(result, &value));
191
+ }
192
+
193
+ TEST_METHOD(22) {
194
+ set_test_name("Multiple cookies in multiple parts (8)");
195
+ psg_lstr_append(&header, pool, "hello=world; foo");
196
+ psg_lstr_append(&header, pool, "=bar");
197
+
198
+ result = findCookie(pool, &header, &name);
199
+ ensure("(1)", result != NULL);
200
+ ensure("(2)", psg_lstr_cmp(result, &value));
201
+ }
202
+
203
+ TEST_METHOD(23) {
204
+ set_test_name("Multiple cookies in multiple parts (9)");
205
+ psg_lstr_append(&header, pool, "hello=world; foo=");
206
+ psg_lstr_append(&header, pool, "bar");
207
+
208
+ result = findCookie(pool, &header, &name);
209
+ ensure("(1)", result != NULL);
210
+ ensure("(2)", psg_lstr_cmp(result, &value));
211
+ }
212
+
213
+ TEST_METHOD(24) {
214
+ set_test_name("Multiple cookies in multiple parts (10)");
215
+ psg_lstr_append(&header, pool, "hello=world; foo=b");
216
+ psg_lstr_append(&header, pool, "ar");
217
+
218
+ result = findCookie(pool, &header, &name);
219
+ ensure("(1)", result != NULL);
220
+ ensure("(2)", psg_lstr_cmp(result, &value));
221
+ }
222
+
223
+
224
+ TEST_METHOD(30) {
225
+ set_test_name("Multiple cookies in multiple parts (11)");
226
+ psg_lstr_append(&header, pool, "hello=world; fo");
227
+ psg_lstr_append(&header, pool, "o=bar; a=b");
228
+
229
+ result = findCookie(pool, &header, &name);
230
+ ensure("(1)", result != NULL);
231
+ ensure("(2)", psg_lstr_cmp(result, &value));
232
+ }
233
+
234
+ TEST_METHOD(31) {
235
+ set_test_name("Multiple cookies in multiple parts (12)");
236
+ psg_lstr_append(&header, pool, "hello=world; foo");
237
+ psg_lstr_append(&header, pool, "=");
238
+ psg_lstr_append(&header, pool, "bar; a=b");
239
+
240
+ result = findCookie(pool, &header, &name);
241
+ ensure("(1)", result != NULL);
242
+ ensure("(2)", psg_lstr_cmp(result, &value));
243
+ }
244
+
245
+ TEST_METHOD(32) {
246
+ set_test_name("Multiple cookies in multiple parts (13)");
247
+ psg_lstr_append(&header, pool, "hello=world; foo");
248
+ psg_lstr_append(&header, pool, "=bar; a=b");
249
+
250
+ result = findCookie(pool, &header, &name);
251
+ ensure("(1)", result != NULL);
252
+ ensure("(2)", psg_lstr_cmp(result, &value));
253
+ }
254
+
255
+ TEST_METHOD(33) {
256
+ set_test_name("Multiple cookies in multiple parts (14)");
257
+ psg_lstr_append(&header, pool, "hello=world; foo=");
258
+ psg_lstr_append(&header, pool, "bar; a=b");
259
+
260
+ result = findCookie(pool, &header, &name);
261
+ ensure("(1)", result != NULL);
262
+ ensure("(2)", psg_lstr_cmp(result, &value));
263
+ }
264
+
265
+ TEST_METHOD(34) {
266
+ set_test_name("Multiple cookies in multiple parts (15)");
267
+ psg_lstr_append(&header, pool, "hello=world; foo=b");
268
+ psg_lstr_append(&header, pool, "ar; a=b");
269
+
270
+ result = findCookie(pool, &header, &name);
271
+ ensure("(1)", result != NULL);
272
+ ensure("(2)", psg_lstr_cmp(result, &value));
273
+ }
274
+ }
@@ -329,6 +329,17 @@ namespace tut {
329
329
  *result = server->totalRequestsBegun;
330
330
  }
331
331
 
332
+ unsigned int getBodyBytesRead() {
333
+ unsigned int result;
334
+ bg.safe->runSync(boost::bind(&ServerKit_HttpServerTest::_getBodyBytesRead,
335
+ this, &result));
336
+ return result;
337
+ }
338
+
339
+ void _getBodyBytesRead(unsigned int *result) {
340
+ *result = server->bodyBytesRead;
341
+ }
342
+
332
343
  unsigned int getActiveClientCount() {
333
344
  unsigned int result;
334
345
  bg.safe->runSync(boost::bind(&ServerKit_HttpServerTest::_getActiveClientCount,
@@ -1284,6 +1295,72 @@ namespace tut {
1284
1295
  ensure_equals(body.substr(1000000), response2);
1285
1296
  }
1286
1297
 
1298
+ TEST_METHOD(64) {
1299
+ set_test_name("If a request with body is ended but output is being flushed, "
1300
+ "then any received request body data will be discard");
1301
+
1302
+ connectToServer();
1303
+ sendRequest(
1304
+ "GET /large_response HTTP/1.1\r\n"
1305
+ "Connection: close\r\n"
1306
+ "Host: foo\r\n"
1307
+ "Size: 1000000\r\n"
1308
+ "Content-Length: 4\r\n\r\n");
1309
+ EVENTUALLY(1,
1310
+ result = getTotalRequestsBegun() == 1;
1311
+ );
1312
+
1313
+ unsigned long long previouslyBytesConsumed;
1314
+ previouslyBytesConsumed = getTotalBytesConsumed();
1315
+
1316
+ writeExact(fd, "abcd");
1317
+ string response = readAll(fd);
1318
+ string body = stripHeaders(response);
1319
+ ensure(startsWith(response, "HTTP/1.1 200 OK\r\n"));
1320
+ ensure_equals(body.size(), 1000000u);
1321
+ EVENTUALLY(1,
1322
+ result = getTotalBytesConsumed() > previouslyBytesConsumed;
1323
+ );
1324
+ ensure_equals(getBodyBytesRead(), 0u);
1325
+ }
1326
+
1327
+ TEST_METHOD(65) {
1328
+ set_test_name("If a request with body is ended but output is being flushed, "
1329
+ "then it won't attempt to keep-alive the connection after the output is flushed");
1330
+
1331
+ connectToServer();
1332
+ sendRequest(
1333
+ "GET /large_response HTTP/1.1\r\n"
1334
+ "Connection: keep-alive\r\n"
1335
+ "Host: foo\r\n"
1336
+ "Size: 1000000\r\n"
1337
+ "Content-Length: 4\r\n\r\n");
1338
+ EVENTUALLY(1,
1339
+ result = getTotalRequestsBegun() == 1;
1340
+ );
1341
+
1342
+ unsigned long long previouslyBytesConsumed;
1343
+ previouslyBytesConsumed = getTotalBytesConsumed();
1344
+
1345
+ writeExact(fd,
1346
+ "abcd"
1347
+ "GET /foo HTTP/1.1\r\n"
1348
+ "Connection: close\r\n"
1349
+ "Host: foo\r\n\r\n");
1350
+ string response = readAll(fd);
1351
+ string body = stripHeaders(response);
1352
+ ensure(startsWith(response, "HTTP/1.1 200 OK\r\n"));
1353
+ ensure_equals(body.size(), 1000000u);
1354
+ EVENTUALLY(1,
1355
+ result = getTotalBytesConsumed() > previouslyBytesConsumed;
1356
+ );
1357
+ ensure_equals(getBodyBytesRead(), 0u);
1358
+
1359
+ SHOULD_NEVER_HAPPEN(100,
1360
+ result = getTotalRequestsBegun() > 1;
1361
+ );
1362
+ }
1363
+
1287
1364
 
1288
1365
  /***** Miscellaneous *****/
1289
1366
 
@@ -33,7 +33,7 @@ GEM
33
33
  erubis (2.6.6)
34
34
  abstract (>= 1.0.0)
35
35
  i18n (0.5.0)
36
- json (1.7.6)
36
+ json (1.8.2)
37
37
  mail (2.2.19)
38
38
  activesupport (>= 2.3.6)
39
39
  i18n (>= 0.4.0)
@@ -63,7 +63,7 @@ GEM
63
63
  rake (10.0.3)
64
64
  rdoc (3.12)
65
65
  json (~> 1.4)
66
- sqlite3 (1.3.6)
66
+ sqlite3 (1.3.10)
67
67
  sqlite3-ruby (1.3.3)
68
68
  sqlite3 (>= 1.3.3)
69
69
  thor (0.14.6)
@@ -46,7 +46,7 @@ GEM
46
46
  jquery-rails (2.1.4)
47
47
  railties (>= 3.0, < 5.0)
48
48
  thor (>= 0.14, < 2.0)
49
- json (1.7.6)
49
+ json (1.8.2)
50
50
  mail (2.3.3)
51
51
  i18n (>= 0.4.0)
52
52
  mime-types (~> 1.16)
@@ -91,7 +91,7 @@ GEM
91
91
  hike (~> 1.2)
92
92
  rack (~> 1.0)
93
93
  tilt (~> 1.1, != 1.3.0)
94
- sqlite3 (1.3.7)
94
+ sqlite3 (1.3.10)
95
95
  thor (0.14.6)
96
96
  tilt (1.3.3)
97
97
  treetop (1.4.12)
@@ -46,7 +46,7 @@ GEM
46
46
  jquery-rails (2.1.4)
47
47
  railties (>= 3.0, < 5.0)
48
48
  thor (>= 0.14, < 2.0)
49
- json (1.7.6)
49
+ json (1.8.2)
50
50
  mail (2.4.4)
51
51
  i18n (>= 0.4.0)
52
52
  mime-types (~> 1.16)
@@ -89,7 +89,7 @@ GEM
89
89
  multi_json (~> 1.0)
90
90
  rack (~> 1.0)
91
91
  tilt (~> 1.1, != 1.3.0)
92
- sqlite3 (1.3.7)
92
+ sqlite3 (1.3.10)
93
93
  thor (0.17.0)
94
94
  tilt (1.3.3)
95
95
  treetop (1.4.12)
@@ -46,7 +46,7 @@ GEM
46
46
  jquery-rails (3.0.4)
47
47
  railties (>= 3.0, < 5.0)
48
48
  thor (>= 0.14, < 2.0)
49
- json (1.8.0)
49
+ json (1.8.2)
50
50
  libv8 (3.11.8.17)
51
51
  mail (2.5.4)
52
52
  mime-types (~> 1.16)
@@ -92,7 +92,7 @@ GEM
92
92
  actionpack (>= 3.0)
93
93
  activesupport (>= 3.0)
94
94
  sprockets (~> 2.8)
95
- sqlite3 (1.3.7)
95
+ sqlite3 (1.3.10)
96
96
  therubyracer (0.11.4)
97
97
  libv8 (~> 3.11.8.12)
98
98
  ref
@@ -46,7 +46,7 @@ GEM
46
46
  jquery-rails (3.1.1)
47
47
  railties (>= 3.0, < 5.0)
48
48
  thor (>= 0.14, < 2.0)
49
- json (1.8.1)
49
+ json (1.8.2)
50
50
  libv8 (3.16.14.3)
51
51
  mail (2.5.4)
52
52
  mime-types (~> 1.16)
@@ -95,7 +95,7 @@ GEM
95
95
  actionpack (>= 3.0)
96
96
  activesupport (>= 3.0)
97
97
  sprockets (~> 2.8)
98
- sqlite3 (1.3.9)
98
+ sqlite3 (1.3.10)
99
99
  therubyracer (0.12.1)
100
100
  libv8 (~> 3.16.14.0)
101
101
  ref