passenger 4.0.19 → 4.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.

Files changed (65) hide show
  1. checksums.yaml +15 -0
  2. checksums.yaml.gz.asc +12 -0
  3. data.tar.gz.asc +7 -7
  4. data/NEWS +22 -0
  5. data/bin/passenger-install-apache2-module +2 -2
  6. data/bin/passenger-install-nginx-module +2 -2
  7. data/build/agents.rb +6 -0
  8. data/build/apache2.rb +1 -0
  9. data/build/basics.rb +2 -2
  10. data/build/cplusplus_support.rb +6 -1
  11. data/build/cxx_tests.rb +1 -0
  12. data/build/nginx.rb +1 -0
  13. data/build/packaging.rb +1 -1
  14. data/dev/copy_boost_headers.rb +1 -0
  15. data/doc/Users guide Apache.idmap.txt +56 -54
  16. data/doc/Users guide Apache.txt +22 -3
  17. data/doc/Users guide Nginx.idmap.txt +52 -50
  18. data/doc/Users guide Nginx.txt +22 -3
  19. data/ext/apache2/Configuration.hpp +4 -0
  20. data/ext/apache2/ConfigurationCommands.cpp +6 -0
  21. data/ext/apache2/ConfigurationFields.hpp +6 -4
  22. data/ext/apache2/ConfigurationSetters.cpp +11 -0
  23. data/ext/apache2/CreateDirConfig.cpp +1 -0
  24. data/ext/apache2/Hooks.cpp +2 -0
  25. data/ext/apache2/MergeDirConfig.cpp +7 -0
  26. data/ext/boost/type_traits/detail/common_type_imp.hpp +333 -0
  27. data/ext/boost/type_traits/detail/has_binary_operator.hpp +229 -0
  28. data/ext/boost/type_traits/detail/has_postfix_operator.hpp +202 -0
  29. data/ext/boost/type_traits/detail/has_prefix_operator.hpp +210 -0
  30. data/ext/boost/type_traits/detail/is_function_ptr_tester.hpp +654 -0
  31. data/ext/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp +2759 -0
  32. data/ext/boost/type_traits/detail/wrap.hpp +18 -0
  33. data/ext/common/Constants.h +1 -1
  34. data/ext/common/Utils/StrIntUtils.cpp +1 -1
  35. data/ext/common/agents/HelperAgent/Main.cpp +18 -1
  36. data/ext/common/agents/HelperAgent/RequestHandler.h +3 -0
  37. data/ext/common/agents/SpawnPreparer.cpp +25 -0
  38. data/ext/common/agents/TempDirToucher.c +357 -0
  39. data/ext/common/agents/Watchdog/Main.cpp +38 -0
  40. data/ext/nginx/CacheLocationConfig.c +21 -1
  41. data/ext/nginx/CacheLocationConfig.c.erb +1 -1
  42. data/ext/nginx/ConfigurationCommands.c +10 -0
  43. data/ext/nginx/ConfigurationFields.h +18 -16
  44. data/ext/nginx/ConfigurationFields.h.erb +11 -6
  45. data/ext/nginx/CreateLocationConfig.c +4 -0
  46. data/ext/nginx/MergeLocationConfig.c +6 -0
  47. data/helper-scripts/node-loader.js +6 -2
  48. data/lib/phusion_passenger.rb +1 -1
  49. data/lib/phusion_passenger/{rails3_extensions → active_support3_extensions}/init.rb +10 -8
  50. data/lib/phusion_passenger/apache2/config_options.rb +5 -0
  51. data/lib/phusion_passenger/loader_shared_helpers.rb +61 -7
  52. data/lib/phusion_passenger/nginx/config_options.rb +4 -0
  53. data/lib/phusion_passenger/platform_info/apache.rb +6 -1
  54. data/lib/phusion_passenger/platform_info/compiler.rb +29 -2
  55. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  56. data/lib/phusion_passenger/platform_info/ruby.rb +7 -3
  57. data/lib/phusion_passenger/public_api.rb +4 -4
  58. data/lib/phusion_passenger/standalone/command.rb +10 -0
  59. data/lib/phusion_passenger/standalone/runtime_installer.rb +2 -2
  60. data/lib/phusion_passenger/standalone/start_command.rb +14 -8
  61. data/lib/phusion_passenger/utils/unseekable_socket.rb +52 -0
  62. data/resources/templates/standalone/config.erb +11 -0
  63. metadata +14 -15
  64. metadata.gz.asc +7 -7
  65. data/helper-scripts/touch-dir.sh +0 -48
@@ -0,0 +1,18 @@
1
+ // (C) Copyright David Abrahams 2002.
2
+ // Use, modification and distribution are subject to the Boost Software License,
3
+ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4
+ // http://www.boost.org/LICENSE_1_0.txt).
5
+ //
6
+ // See http://www.boost.org/libs/type_traits for most recent version including documentation.
7
+
8
+ #ifndef BOOST_TT_DETAIL_WRAP_HPP_INCLUDED
9
+ #define BOOST_TT_DETAIL_WRAP_HPP_INCLUDED
10
+
11
+ namespace boost {
12
+ namespace type_traits {
13
+
14
+ template <class T> struct wrap {};
15
+
16
+ }} // namespace boost::type_traits
17
+
18
+ #endif // BOOST_TT_DETAIL_WRAP_HPP_INCLUDED
@@ -72,7 +72,7 @@
72
72
 
73
73
  #define MESSAGE_SERVER_MAX_USERNAME_SIZE 100
74
74
 
75
- #define PASSENGER_VERSION "4.0.19"
75
+ #define PASSENGER_VERSION "4.0.20"
76
76
 
77
77
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
78
78
 
@@ -512,7 +512,7 @@ cEscapeString(const StaticString &input) {
512
512
  string
513
513
  escapeHTML(const StaticString &input) {
514
514
  string result;
515
- result.reserve((int) round(input.size() * 1.25));
515
+ result.reserve((int) ceil(input.size() * 1.25));
516
516
 
517
517
  const char *current = (const char *) input.c_str();
518
518
  const char *end = current + input.size();
@@ -506,7 +506,24 @@ public:
506
506
  requestHandler.reset();
507
507
 
508
508
  if (!options.requestSocketLink.empty()) {
509
- syscalls::unlink(options.requestSocketLink.c_str());
509
+ char path[PATH_MAX + 1];
510
+ ssize_t ret;
511
+ bool shouldUnlink;
512
+
513
+ ret = readlink(options.requestSocketLink.c_str(), path, PATH_MAX);
514
+ if (ret != -1) {
515
+ path[ret] = '\0';
516
+ // Only unlink if a new Flying Passenger instance hasn't overwritten the
517
+ // symlink.
518
+ // https://code.google.com/p/phusion-passenger/issues/detail?id=939
519
+ shouldUnlink = getRequestSocketFilename() == path;
520
+ } else {
521
+ shouldUnlink = true;
522
+ }
523
+
524
+ if (shouldUnlink) {
525
+ syscalls::unlink(options.requestSocketLink.c_str());
526
+ }
510
527
  }
511
528
 
512
529
  P_TRACE(2, "All threads have been shut down.");
@@ -1747,6 +1747,9 @@ private:
1747
1747
 
1748
1748
  client->beginScopeLog(&client->scopeLogs.requestProcessing, "request processing");
1749
1749
 
1750
+ StaticString staticRequestMethod = parser.getHeader("REQUEST_METHOD");
1751
+ client->logMessage("Request method: " + staticRequestMethod);
1752
+
1750
1753
  StaticString staticRequestURI = parser.getHeader("REQUEST_URI");
1751
1754
  if (!staticRequestURI.empty()) {
1752
1755
  client->logMessage("URI: " + staticRequestURI);
@@ -1,3 +1,28 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2012-2013 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+
1
26
  /*
2
27
  * Sets given environment variables, dumps the entire environment to
3
28
  * a given file (for diagnostics purposes), then execs the given command.
@@ -0,0 +1,357 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2013 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+
26
+ /* This tool touches everything in a directory every 30 minutes to prevent
27
+ * /tmp cleaners from removing it.
28
+ */
29
+
30
+ #include <sys/stat.h>
31
+ #include <sys/types.h>
32
+ #include <sys/wait.h>
33
+ #include <stdio.h>
34
+ #include <stdlib.h>
35
+ #include <unistd.h>
36
+ #include <signal.h>
37
+ #include <fcntl.h>
38
+ #include <limits.h>
39
+ #include <errno.h>
40
+ #include <string.h>
41
+
42
+ #define ERROR_PREFIX "*** TempDirToucher error"
43
+
44
+ static char *dir;
45
+ /**
46
+ * When Passenger Standalone is started with --daemonize, then it will
47
+ * pass --cleanup to this tool so that this tool is responsible
48
+ * for cleaning up the Standalone temp dir.
49
+ */
50
+ static int shouldCleanup = 0;
51
+ static int shouldDaemonize = 0;
52
+ static const char *pidFile = NULL;
53
+ static const char *logFile = NULL;
54
+ static int terminationPipe[2];
55
+
56
+
57
+ static void
58
+ parseArguments(int argc, char *argv[]) {
59
+ dir = argv[1];
60
+ int i;
61
+
62
+ for (i = 2; i < argc; i++) {
63
+ if (strcmp(argv[i], "--cleanup") == 0) {
64
+ shouldCleanup = 1;
65
+ } else if (strcmp(argv[i], "--daemonize") == 0) {
66
+ shouldDaemonize = 1;
67
+ } else if (strcmp(argv[i], "--pid-file") == 0) {
68
+ pidFile = argv[i + 1];
69
+ i++;
70
+ } else if (strcmp(argv[i], "--log-file") == 0) {
71
+ logFile = argv[i + 1];
72
+ i++;
73
+ } else {
74
+ fprintf(stderr, ERROR_PREFIX ": unrecognized argument %s\n",
75
+ argv[i]);
76
+ exit(1);
77
+ }
78
+ }
79
+ }
80
+
81
+ static void
82
+ setNonBlocking(int fd) {
83
+ int flags, ret, e;
84
+
85
+ do {
86
+ flags = fcntl(fd, F_GETFL);
87
+ } while (flags == -1 && errno == EINTR);
88
+ if (flags == -1) {
89
+ e = errno;
90
+ fprintf(stderr, ERROR_PREFIX
91
+ ": cannot set pipe to non-blocking mode: "
92
+ "cannot get file descriptor flags. Error: %s (errno %d)\n",
93
+ strerror(e), e);
94
+ exit(1);
95
+ }
96
+ do {
97
+ ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
98
+ } while (ret == -1 && errno == EINTR);
99
+ if (ret == -1) {
100
+ e = errno;
101
+ fprintf(stderr, ERROR_PREFIX
102
+ ": cannot set pipe to non-blocking mode: "
103
+ "cannot set file descriptor flags. Error: %s (errno %d)\n",
104
+ strerror(e), e);
105
+ exit(1);
106
+ }
107
+ }
108
+
109
+ static void
110
+ initialize(int argc, char *argv[]) {
111
+ int e, fd;
112
+
113
+ parseArguments(argc, argv);
114
+
115
+ if (logFile != NULL) {
116
+ fd = open(logFile, O_WRONLY | O_APPEND | O_CREAT);
117
+ if (fd == -1) {
118
+ e = errno;
119
+ fprintf(stderr, ERROR_PREFIX
120
+ ": cannot open log file %s for writing: %s (errno %d)\n",
121
+ logFile, strerror(e), e);
122
+ exit(1);
123
+ }
124
+
125
+ if (dup2(fd, 1) == -1) {
126
+ e = errno;
127
+ fprintf(stderr, ERROR_PREFIX ": cannot dup2(%d, 1): %s (errno %d)\n",
128
+ fd, strerror(e), e);
129
+ }
130
+ if (dup2(fd, 2) == -1) {
131
+ e = errno;
132
+ fprintf(stderr, ERROR_PREFIX ": cannot dup2(%d, 2): %s (errno %d)\n",
133
+ fd, strerror(e), e);
134
+ }
135
+
136
+ close(fd);
137
+ }
138
+
139
+ if (pipe(terminationPipe) == -1) {
140
+ e = errno;
141
+ fprintf(stderr, ERROR_PREFIX ": cannot create a pipe: %s (errno %d)\n",
142
+ strerror(e), e);
143
+ exit(1);
144
+ }
145
+
146
+ setNonBlocking(terminationPipe[1]);
147
+ }
148
+
149
+ static void
150
+ exitHandler(int signo) {
151
+ write(terminationPipe[1], "x", 1);
152
+ }
153
+
154
+ static void
155
+ installSignalHandlers() {
156
+ struct sigaction action;
157
+
158
+ action.sa_handler = exitHandler;
159
+ action.sa_flags = SA_RESTART;
160
+ sigemptyset(&action.sa_mask);
161
+ sigaction(SIGINT, &action, NULL);
162
+ sigaction(SIGTERM, &action, NULL);
163
+ }
164
+
165
+ static void
166
+ redirectStdinToNull() {
167
+ int fd = open("/dev/null", O_RDONLY);
168
+ if (fd != -1) {
169
+ dup2(fd, 1);
170
+ close(fd);
171
+ }
172
+ }
173
+
174
+ static void
175
+ maybeDaemonize() {
176
+ pid_t pid;
177
+ int e;
178
+
179
+ if (shouldDaemonize) {
180
+ pid = fork();
181
+ if (pid == 0) {
182
+ setsid();
183
+ chdir("/");
184
+ redirectStdinToNull();
185
+ } else if (pid == -1) {
186
+ e = errno;
187
+ fprintf(stderr, ERROR_PREFIX ": cannot fork: %s (errno %d)\n",
188
+ strerror(e), e);
189
+ exit(1);
190
+ } else {
191
+ _exit(0);
192
+ }
193
+ }
194
+ }
195
+
196
+ static void
197
+ maybeWritePidfile() {
198
+ FILE *f;
199
+
200
+ if (pidFile != NULL) {
201
+ f = fopen(pidFile, "w");
202
+ if (f != NULL) {
203
+ fprintf(f, "%d\n", (int) getpid());
204
+ fclose(f);
205
+ } else {
206
+ fprintf(stderr, ERROR_PREFIX ": cannot open PID file %s for writing\n",
207
+ pidFile);
208
+ exit(1);
209
+ }
210
+ }
211
+ }
212
+
213
+ static int
214
+ dirExists(const char *dir) {
215
+ struct stat buf;
216
+ return stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode);
217
+ }
218
+
219
+ static void
220
+ touchDir(const char *dir) {
221
+ pid_t pid;
222
+ int e, status;
223
+
224
+ pid = fork();
225
+ if (pid == 0) {
226
+ close(terminationPipe[0]);
227
+ close(terminationPipe[1]);
228
+ if (chdir(dir) == -1) {
229
+ e = errno;
230
+ fprintf(stderr, ERROR_PREFIX
231
+ ": cannot change working directory to %s: %s (errno %d)\n",
232
+ dir, strerror(e), e);
233
+ _exit(1);
234
+ }
235
+ execlp("/bin/sh", "/bin/sh", "-c",
236
+ "find \"$1\" | xargs touch", "/bin/sh", ".",
237
+ (const char * const) 0);
238
+ e = errno;
239
+ fprintf(stderr, ERROR_PREFIX ": cannot execute /bin/sh: %s (errno %d)\n",
240
+ strerror(e), e);
241
+ _exit(1);
242
+ } else if (pid == -1) {
243
+ e = errno;
244
+ fprintf(stderr, ERROR_PREFIX ": cannot fork: %s (errno %d)\n",
245
+ strerror(e), e);
246
+ exit(1);
247
+ } else {
248
+ if (waitpid(pid, &status, 0) == -1) {
249
+ if (errno != ESRCH && errno != EPERM) {
250
+ fprintf(stderr, ERROR_PREFIX
251
+ ": unable to wait for shell command 'find %s | xargs touch'\n",
252
+ dir);
253
+ exit(1);
254
+ }
255
+ } else if (WEXITSTATUS(status) != 0) {
256
+ fprintf(stderr, ERROR_PREFIX
257
+ ": shell command 'find %s | xargs touch' failed with exit status %d\n",
258
+ dir, WEXITSTATUS(status));
259
+ exit(1);
260
+ }
261
+ }
262
+ }
263
+
264
+ static int
265
+ doSleep(int sec) {
266
+ fd_set readfds;
267
+ struct timeval timeout;
268
+ int ret, e;
269
+
270
+ FD_ZERO(&readfds);
271
+ FD_SET(terminationPipe[0], &readfds);
272
+ timeout.tv_sec = sec;
273
+ timeout.tv_usec = 0;
274
+ do {
275
+ ret = select(terminationPipe[0] + 1, &readfds, NULL, NULL, &timeout);
276
+ } while (ret == -1 && errno == EINTR);
277
+ if (ret == -1) {
278
+ e = errno;
279
+ fprintf(stderr, ERROR_PREFIX ": cannot select(): %s (errno %d)\n",
280
+ strerror(e), e);
281
+ exit(1);
282
+ return -1; /* Never reached */
283
+ } else {
284
+ return ret == 0;
285
+ }
286
+ }
287
+
288
+ static void
289
+ maybeDeletePidFile() {
290
+ if (pidFile != NULL) {
291
+ unlink(pidFile);
292
+ }
293
+ }
294
+
295
+ static void
296
+ performCleanup(const char *dir) {
297
+ pid_t pid;
298
+ int e, status;
299
+
300
+ pid = fork();
301
+ if (pid == 0) {
302
+ close(terminationPipe[0]);
303
+ close(terminationPipe[1]);
304
+ execlp("/bin/sh", "/bin/sh", "-c",
305
+ "rm -rf \"$1\"", "/bin/sh", dir,
306
+ (const char * const) 0);
307
+ e = errno;
308
+ fprintf(stderr, ERROR_PREFIX ": cannot execute /bin/sh: %s (errno %d)\n",
309
+ strerror(e), e);
310
+ _exit(1);
311
+ } else if (pid == -1) {
312
+ e = errno;
313
+ fprintf(stderr, ERROR_PREFIX ": cannot fork: %s (errno %d)\n",
314
+ strerror(e), e);
315
+ exit(1);
316
+ } else {
317
+ if (waitpid(pid, &status, 0) == -1) {
318
+ if (errno != ESRCH && errno != EPERM) {
319
+ fprintf(stderr, ERROR_PREFIX
320
+ ": unable to wait for shell command 'rm -rf %s'\n",
321
+ dir);
322
+ exit(1);
323
+ }
324
+ } else if (WEXITSTATUS(status) != 0) {
325
+ fprintf(stderr, ERROR_PREFIX
326
+ ": shell command 'rm -rf %s' failed with exit status %d\n",
327
+ dir, WEXITSTATUS(status));
328
+ exit(1);
329
+ }
330
+ }
331
+ }
332
+
333
+ int
334
+ main(int argc, char *argv[]) {
335
+ initialize(argc, argv);
336
+ installSignalHandlers();
337
+ maybeDaemonize();
338
+ maybeWritePidfile();
339
+
340
+ while (1) {
341
+ if (dirExists(dir)) {
342
+ touchDir(dir);
343
+ if (!doSleep(1800)) {
344
+ break;
345
+ }
346
+ } else {
347
+ break;
348
+ }
349
+ }
350
+
351
+ maybeDeletePidFile();
352
+ if (shouldCleanup) {
353
+ performCleanup(dir);
354
+ }
355
+
356
+ return 0;
357
+ }