Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 661 lines (576 sloc) 19.704 kb
bd6e3b4 Hongli Lai Insert GPL headers to source files.
FooBarWidget authored
1 /*
2 * Phusion Passenger - http://www.modrails.com/
3 * Copyright (C) 2008 Phusion
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
18 #include <ap_config.h>
19 #include <httpd.h>
20 #include <http_config.h>
21 #include <http_core.h>
22 #include <http_request.h>
23 #include <http_protocol.h>
24 #include <http_log.h>
25 #include <util_script.h>
26 #include <apr_pools.h>
27 #include <apr_strings.h>
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
28 #include <apr_lib.h>
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
29
81a559e Hongli Lai Aggressively report threading errors and associated system settings.
FooBarWidget authored
30 #include <sys/time.h>
31 #include <sys/resource.h>
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
32 #include <exception>
33 #include <unistd.h>
34
35 #include "Hooks.h"
fc309c4 Hongli Lai Improve API docs.
FooBarWidget authored
36 #include "Configuration.h"
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
37 #include "Utils.h"
31ac611 Hongli Lai Improve error reporting.
FooBarWidget authored
38 #include "Logging.h"
794939c Hongli Lai Add a new ApplicationPoolServer, for sharing the application pool betwee...
FooBarWidget authored
39 #include "ApplicationPoolClientServer.h"
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
40 #include "MessageChannel.h"
41
42 using namespace std;
43 using namespace Passenger;
44
c7cb438 Hongli Lai Finish the Apache 2 module installer script. Rename mod_rails to mod_pas...
FooBarWidget authored
45 extern "C" module AP_MODULE_DECLARE_DATA passenger_module;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
46
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
47 #define DEFAULT_RUBY_COMMAND "ruby"
48 #define DEFAULT_RAILS_ENV "production"
49
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
50
51 class Hooks {
52 private:
f954873 Hongli Lai - Refactor ApplicationPool so that ApplicationPoolServer can actually be...
FooBarWidget authored
53 struct Container {
54 Application::SessionPtr session;
55
56 static apr_status_t cleanup(void *p) {
57 delete (Container *) p;
58 return APR_SUCCESS;
59 }
60 };
61
794939c Hongli Lai Add a new ApplicationPoolServer, for sharing the application pool betwee...
FooBarWidget authored
62 ApplicationPoolServerPtr applicationPoolServer;
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
63 ApplicationPoolPtr applicationPool;
64
fc1c32f Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
65 DirConfig *getDirConfig(request_rec *r) {
c7cb438 Hongli Lai Finish the Apache 2 module installer script. Rename mod_rails to mod_pas...
FooBarWidget authored
66 return (DirConfig *) ap_get_module_config(r->per_dir_config, &passenger_module);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
67 }
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
68
69 ServerConfig *getServerConfig(server_rec *s) {
c7cb438 Hongli Lai Finish the Apache 2 module installer script. Rename mod_rails to mod_pas...
FooBarWidget authored
70 return (ServerConfig *) ap_get_module_config(s->module_config, &passenger_module);
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
71 }
72
935cdee Hongli Lai Implement autodetection of Rails apps.
FooBarWidget authored
73 /**
74 * Determine whether the given HTTP request falls under one of the specified
75 * RailsBaseURIs. If yes, then the first matching base URI will be returned.
76 *
77 * If Rails autodetection was enabled in the configuration, then this function
78 * will return '/' if the document root seems to be a valid Rails 'public' folder.
79 *
80 * Otherwise, NULL will be returned.
81 */
fc1c32f Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
82 const char *determineRailsBaseURI(request_rec *r, DirConfig *config) {
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
83 set<string>::const_iterator it;
84 const char *uri = r->uri;
85 size_t uri_len = strlen(uri);
86
87 if (uri_len == 0 || uri[0] != '/') {
88 return NULL;
89 }
90
91 for (it = config->base_uris.begin(); it != config->base_uris.end(); it++) {
92 const string &base(*it);
93 if ( base == "/"
94 || ( uri_len == base.size() && memcmp(uri, base.c_str(), uri_len) == 0 )
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
95 || ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0
96 && uri[base.size()] == '/' )
97 ) {
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
98 return apr_pstrdup(r->pool, base.c_str());
99 }
100 }
935cdee Hongli Lai Implement autodetection of Rails apps.
FooBarWidget authored
101
102 if ((config->autoDetect == DirConfig::ENABLED || config->autoDetect == DirConfig::UNSET)
7fe08da Hongli Lai Move verifyRailsDir() from Hooks.cpp to Utils.cpp.
FooBarWidget authored
103 && verifyRailsDir(ap_document_root(r))) {
935cdee Hongli Lai Implement autodetection of Rails apps.
FooBarWidget authored
104 return "/";
105 }
106
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
107 return NULL;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
108 }
109
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
110 string determineRailsDir(request_rec *r, const char *baseURI) {
e92c4f2 Hongli Lai Improve documentation
FooBarWidget authored
111 const char *docRoot = ap_document_root(r);
112 size_t len = strlen(docRoot);
113 if (len > 0) {
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
114 string path;
e92c4f2 Hongli Lai Improve documentation
FooBarWidget authored
115 if (docRoot[len - 1] == '/') {
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
116 path.assign(docRoot, len - 1);
e92c4f2 Hongli Lai Improve documentation
FooBarWidget authored
117 } else {
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
118 path.assign(docRoot, len);
e92c4f2 Hongli Lai Improve documentation
FooBarWidget authored
119 }
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
120 if (strcmp(baseURI, "/") != 0) {
121 path.append(baseURI);
122 }
123 return path;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
124 } else {
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
125 return "";
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
126 }
127 }
128
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
129 char *http2env(apr_pool_t *p, const char *name) {
130 char *env_name = apr_pstrcat(p, "HTTP_", name, NULL);
131 char *cp;
132
133 for (cp = env_name + 5; *cp != 0; cp++) {
134 if (*cp == '-') {
135 *cp = '_';
136 } else {
137 *cp = apr_toupper(*cp);
138 }
139 }
140
141 return env_name;
142 }
143
144 char *lookupName(apr_table_t *t, const char *name) {
145 const apr_array_header_t *hdrs_arr = apr_table_elts(t);
146 apr_table_entry_t *hdrs = (apr_table_entry_t *) hdrs_arr->elts;
147 int i;
148
149 for (i = 0; i < hdrs_arr->nelts; ++i) {
150 if (hdrs[i].key == NULL) {
151 continue;
152 }
153 if (strcasecmp(hdrs[i].key, name) == 0) {
154 return hdrs[i].val;
155 }
156 }
157 return NULL;
158 }
159
160 char *lookupHeader(request_rec *r, const char *name) {
161 return lookupName(r->headers_in, name);
162 }
163
164 char *lookupEnv(request_rec *r, const char *name) {
165 return lookupName(r->subprocess_env, name);
166 }
167
168 // This code is a duplicate of what's in util_script.c. We can't use
169 // r->unparsed_uri because it gets changed if there was a redirect.
170 char *originalURI(request_rec *r) {
171 char *first, *last;
172
173 if (r->the_request == NULL) {
174 return (char *) apr_pcalloc(r->pool, 1);
175 }
176
177 first = r->the_request; // use the request-line
178
179 while (*first && !apr_isspace(*first)) {
180 ++first; // skip over the method
181 }
182 while (apr_isspace(*first)) {
183 ++first; // and the space(s)
184 }
185
186 last = first;
187 while (*last && !apr_isspace(*last)) {
188 ++last; // end at next whitespace
189 }
190
191 return apr_pstrmemdup(r->pool, first, last - first);
192 }
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
193
194 void addHeader(apr_table_t *table, const char *name, const char *value) {
195 if (name != NULL && value != NULL) {
196 apr_table_addn(table, name, value);
197 }
198 }
199
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
200 apr_status_t sendHeaders(request_rec *r, Application::SessionPtr &session, const char *baseURI) {
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
201 apr_table_t *headers;
202 headers = apr_table_make(r->pool, 40);
203 if (headers == NULL) {
204 return APR_ENOMEM;
205 }
206
207 // Set standard CGI variables.
208 addHeader(headers, "SERVER_SOFTWARE", ap_get_server_version());
209 addHeader(headers, "SERVER_PROTOCOL", r->protocol);
210 addHeader(headers, "SERVER_NAME", ap_get_server_name(r));
211 addHeader(headers, "SERVER_ADMIN", r->server->server_admin);
212 addHeader(headers, "SERVER_ADDR", r->connection->local_ip);
213 addHeader(headers, "SERVER_PORT", apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
214 addHeader(headers, "REMOTE_ADDR", r->connection->remote_ip);
215 addHeader(headers, "REMOTE_PORT", apr_psprintf(r->pool, "%d", r->connection->remote_addr->port));
216 addHeader(headers, "REMOTE_USER", r->user);
217 addHeader(headers, "REQUEST_METHOD", r->method);
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
218 addHeader(headers, "REQUEST_URI", originalURI(r));
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
219 addHeader(headers, "QUERY_STRING", r->args ? r->args : "");
935cdee Hongli Lai Implement autodetection of Rails apps.
FooBarWidget authored
220 if (strcmp(baseURI, "/") != 0) {
221 addHeader(headers, "SCRIPT_NAME", baseURI);
222 }
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
223 addHeader(headers, "HTTPS", lookupEnv(r, "HTTPS"));
224 addHeader(headers, "CONTENT_TYPE", lookupHeader(r, "Content-type"));
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
225 addHeader(headers, "DOCUMENT_ROOT", ap_document_root(r));
b70c89c Hongli Lai Fix some nasty bugs in the DispatcherBucket. Add some minor changes to o...
FooBarWidget authored
226
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
227 // Set HTTP headers.
228 const apr_array_header_t *hdrs_arr;
229 apr_table_entry_t *hdrs;
230 int i;
231
232 hdrs_arr = apr_table_elts(r->headers_in);
233 hdrs = (apr_table_entry_t *) hdrs_arr->elts;
234 for (i = 0; i < hdrs_arr->nelts; ++i) {
235 if (hdrs[i].key) {
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
236 addHeader(headers, http2env(r->pool, hdrs[i].key), hdrs[i].val);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
237 }
238 }
239
240 // Add other environment variables.
241 const apr_array_header_t *env_arr;
242 apr_table_entry_t *env;
243
244 env_arr = apr_table_elts(r->subprocess_env);
245 env = (apr_table_entry_t*) env_arr->elts;
246 for (i = 0; i < env_arr->nelts; ++i) {
247 addHeader(headers, env[i].key, env[i].val);
248 }
249
8444070 Hongli Lai Forgot to commit unindexed files.
FooBarWidget authored
250 // Now send the headers.
251 string buffer;
252
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
253 hdrs_arr = apr_table_elts(headers);
254 hdrs = (apr_table_entry_t*) hdrs_arr->elts;
8444070 Hongli Lai Forgot to commit unindexed files.
FooBarWidget authored
255 buffer.reserve(1024 * 4);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
256 for (i = 0; i < hdrs_arr->nelts; ++i) {
8444070 Hongli Lai Forgot to commit unindexed files.
FooBarWidget authored
257 buffer.append(hdrs[i].key);
258 buffer.append(1, '\0');
259 buffer.append(hdrs[i].val);
260 buffer.append(1, '\0');
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
261 }
ab5bc95 Hongli Lai Make sure that headers that contain empty strings are unserialized corre...
FooBarWidget authored
262
263 /*
264 * If the last header value is an empty string, then the buffer
265 * will end with "\0\0". For example, if 'SSLOptions +ExportCertData'
266 * is set, and there's no client certificate, and 'SSL_CLIENT_CERT'
267 * is the last header, then the buffer will end with:
268 *
269 * "SSL_CLIENT_CERT\0\0"
270 *
271 * The data in the buffer will be processed by the RequestHandler class,
272 * which is implemented in Ruby. But it uses Hash[*data.split("\0")] to
273 * unserialize the data. Unfortunately String#split will not transform
274 * the trailing "\0\0" into an empty string:
275 *
276 * "SSL_CLIENT_CERT\0\0".split("\0")
277 * # => desired result: ["SSL_CLIENT_CERT", ""]
278 * # => actual result: ["SSL_CLIENT_CERT"]
279 *
280 * When that happens, Hash[..] will raise an ArgumentError because
281 * data.split("\0") does not return an array with a length that is a
282 * multiple of 2.
283 *
284 * So here, we add a dummy header to prevent situations like that from
285 * happening.
286 */
287 buffer.append("_\0_\0", 4);
288
f954873 Hongli Lai - Refactor ApplicationPool so that ApplicationPoolServer can actually be...
FooBarWidget authored
289 session->sendHeaders(buffer);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
290 return APR_SUCCESS;
291 }
dd1d137 Hongli Lai - Implement support for file uploads.
FooBarWidget authored
292
293 apr_status_t sendRequestBody(request_rec *r, Application::SessionPtr &session) {
294 if (ap_should_client_block(r)) {
295 char buf[1024 * 32];
296 apr_off_t len;
297
298 while ((len = ap_get_client_block(r, buf, sizeof(buf))) > 0) {
299 session->sendBodyBlock(buf, len);
300 }
301 if (len == -1) {
302 return HTTP_INTERNAL_SERVER_ERROR;
303 }
304 }
305 session->closeWriter();
306 return APR_SUCCESS;
307 }
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
308
309 public:
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
310 Hooks(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) {
311 ap_add_version_component(pconf, "Phusion_Passenger/" PASSENGER_VERSION);
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
312 passenger_config_merge_all_servers(pconf, s);
313
314 ServerConfig *config = getServerConfig(s);
c07e098 Hongli Lai Finish user switching configuration option.
FooBarWidget authored
315 const char *ruby, *environment, *user;
914c171 Hongli Lai Attempt to autodetect the spawn server's location.
FooBarWidget authored
316 string spawnServer;
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
317
318 ruby = (config->ruby != NULL) ? config->ruby : DEFAULT_RUBY_COMMAND;
319 environment = (config->env != NULL) ? config->env : DEFAULT_RAILS_ENV;
c07e098 Hongli Lai Finish user switching configuration option.
FooBarWidget authored
320 if (config->userSwitching) {
321 user = "";
322 } else if (config->defaultUser != NULL) {
323 user = config->defaultUser;
324 } else {
325 user = "nobody";
326 }
914c171 Hongli Lai Attempt to autodetect the spawn server's location.
FooBarWidget authored
327 if (config->spawnServer != NULL) {
328 spawnServer = config->spawnServer;
329 } else {
330 spawnServer = findSpawnServer();
331 if (spawnServer.empty()) {
332 throw FileNotFoundException("The Passenger spawn server script "
333 "could not be found. Please ensure that it can be found "
334 "in $PATH, or specify it with the RailsSpawnServer "
335 "configuration option.");
336 }
337 }
338 if (!fileExists(spawnServer.c_str())) {
339 string message("The specified Passenger spawn server script, '");
340 message.append(spawnServer);
341 message.append("', does not exist.");
342 throw FileNotFoundException(message);
343 }
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
344
c07e098 Hongli Lai Finish user switching configuration option.
FooBarWidget authored
345 applicationPoolServer = ptr(
346 new ApplicationPoolServer(spawnServer, "", environment, ruby, user)
347 );
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
348 }
349
350 void initChild(apr_pool_t *pchild, server_rec *s) {
757debd Hongli Lai - Implemented configuration options: RailsMaxPoolSize and RailsPoolIdleT...
FooBarWidget authored
351 ServerConfig *config = getServerConfig(s);
352
353 try {
354 applicationPool = applicationPoolServer->connect();
355 applicationPoolServer->detach();
356 applicationPool->setMax(config->maxPoolSize);
357 applicationPool->setMaxIdleTime(config->poolIdleTime);
358 } catch (const exception &e) {
359 fprintf(stderr, "*** Cannot initialize Passenger: %s", e.what());
360 fflush(stderr);
361 abort();
362 }
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
363 }
364
365 int handleRequest(request_rec *r) {
fc1c32f Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
366 DirConfig *config = getDirConfig(r);
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
367 const char *railsBaseURI = determineRailsBaseURI(r, config);
914c171 Hongli Lai Attempt to autodetect the spawn server's location.
FooBarWidget authored
368 if (railsBaseURI == NULL || r->filename == NULL || fileExists(r->filename)) {
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
369 return DECLINED;
370 }
371
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
372 string railsDir(determineRailsDir(r, railsBaseURI));
373 if (railsDir.empty()) {
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
374 ap_set_content_type(r, "text/html; charset=UTF-8");
9d714c0 Hongli Lai Rename 'mod_rails' directories to 'passenger'
FooBarWidget authored
375 ap_rputs("<h1>Passenger error #1</h1>\n", r);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
376 ap_rputs("Cannot determine the location of the Rails application's \"public\" directory.", r);
377 return OK;
7fe08da Hongli Lai Move verifyRailsDir() from Hooks.cpp to Utils.cpp.
FooBarWidget authored
378 } else if (!verifyRailsDir(railsDir)) {
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
379 ap_set_content_type(r, "text/html; charset=UTF-8");
9d714c0 Hongli Lai Rename 'mod_rails' directories to 'passenger'
FooBarWidget authored
380 ap_rputs("<h1>Passenger error #2</h1>\n", r);
200363f Hongli Lai Improve Passenger error message #2: explain that the problem might be ca...
FooBarWidget authored
381 ap_rputs("Passenger thought that the Rails application's \"public\" directory is \"", r);
ecde811 Hongli Lai Canonicalize Rails application root paths.
FooBarWidget authored
382 ap_rputs(ap_escape_html(r->pool, railsDir.c_str()), r);
200363f Hongli Lai Improve Passenger error message #2: explain that the problem might be ca...
FooBarWidget authored
383 ap_rputs("\". But upon further inspection, it doesn't seem to be a valid Rails ", r);
384 ap_rputs("\"public\" folder. It is possible that Apache doesn't have read ", r);
385 ap_rputs("permissions to your Rails application's folder. Please check your ", r);
386 ap_rputs("file permissions.", r);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
387 return OK;
388 }
389
dd1d137 Hongli Lai - Implement support for file uploads.
FooBarWidget authored
390 int httpStatus = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
391 if (httpStatus != OK) {
392 return httpStatus;
dd1d137 Hongli Lai - Implement support for file uploads.
FooBarWidget authored
393 }
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
394
395 try {
396 apr_bucket_brigade *bb;
397 apr_bucket *b;
a3003f3 Hongli Lai Support error pages in the Apache module
FooBarWidget authored
398 Application::SessionPtr session;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
399
a06160d Hongli Lai - Fix some crasher bugs in DispatcherBucket.
FooBarWidget authored
400 P_DEBUG("Processing HTTP request: " << r->uri);
a3003f3 Hongli Lai Support error pages in the Apache module
FooBarWidget authored
401 try {
829dad7 Hongli Lai Apparently Apache 2.0.55 doesn't allow other modules to read config opti...
FooBarWidget authored
402 const char *defaultUser;
2931e4f Hongli Lai Instead of using 'nobody' as hardcoded fallback user in user switching, ...
FooBarWidget authored
403 ServerConfig *sconfig;
404
405 sconfig = getServerConfig(r->server);
829dad7 Hongli Lai Apparently Apache 2.0.55 doesn't allow other modules to read config opti...
FooBarWidget authored
406 if (sconfig->defaultUser != NULL) {
407 defaultUser = sconfig->defaultUser;
2931e4f Hongli Lai Instead of using 'nobody' as hardcoded fallback user in user switching, ...
FooBarWidget authored
408 } else {
829dad7 Hongli Lai Apparently Apache 2.0.55 doesn't allow other modules to read config opti...
FooBarWidget authored
409 defaultUser = "nobody";
2931e4f Hongli Lai Instead of using 'nobody' as hardcoded fallback user in user switching, ...
FooBarWidget authored
410 }
411 session = applicationPool->get(canonicalizePath(railsDir + "/.."),
829dad7 Hongli Lai Apparently Apache 2.0.55 doesn't allow other modules to read config opti...
FooBarWidget authored
412 true, defaultUser);
a3003f3 Hongli Lai Support error pages in the Apache module
FooBarWidget authored
413 } catch (const SpawnException &e) {
414 if (e.hasErrorPage()) {
415 ap_set_content_type(r, "text/html; charset=utf-8");
416 ap_rputs(e.getErrorPage().c_str(), r);
417 // Unfortunately we can't return a 500 Internal Server
418 // Error. Apache's HTTP error handler would kick in.
419 return OK;
420 } else {
421 throw;
422 }
423 }
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
424 sendHeaders(r, session, railsBaseURI);
dd1d137 Hongli Lai - Implement support for file uploads.
FooBarWidget authored
425 sendRequestBody(r, session);
8444070 Hongli Lai Forgot to commit unindexed files.
FooBarWidget authored
426
427 apr_file_t *readerPipe = NULL;
f954873 Hongli Lai - Refactor ApplicationPool so that ApplicationPoolServer can actually be...
FooBarWidget authored
428 int reader = session->getReader();
429 apr_os_pipe_put(&readerPipe, &reader, r->pool);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
430
431 bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
8444070 Hongli Lai Forgot to commit unindexed files.
FooBarWidget authored
432 b = apr_bucket_pipe_create(readerPipe, r->connection->bucket_alloc);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
433 APR_BRIGADE_INSERT_TAIL(bb, b);
434
435 b = apr_bucket_eos_create(r->connection->bucket_alloc);
436 APR_BRIGADE_INSERT_TAIL(bb, b);
437
438 ap_scan_script_header_err_brigade(r, bb, NULL);
439 ap_pass_brigade(r->output_filters, bb);
a06160d Hongli Lai - Fix some crasher bugs in DispatcherBucket.
FooBarWidget authored
440
f954873 Hongli Lai - Refactor ApplicationPool so that ApplicationPoolServer can actually be...
FooBarWidget authored
441 Container *container = new Container();
442 container->session = session;
443 apr_pool_cleanup_register(r->pool, container, Container::cleanup, apr_pool_cleanup_null);
b70c89c Hongli Lai Fix some nasty bugs in the DispatcherBucket. Add some minor changes to o...
FooBarWidget authored
444
f6725b9 Hongli Lai - Improve documentation for the MessageChannel and SpawnManager C++ clas...
FooBarWidget authored
445 return OK;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
446 } catch (const exception &e) {
87621bf Hongli Lai Change error message
FooBarWidget authored
447 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "*** Unexpected error in Passenger: %s", e.what());
f6725b9 Hongli Lai - Improve documentation for the MessageChannel and SpawnManager C++ clas...
FooBarWidget authored
448 return HTTP_INTERNAL_SERVER_ERROR;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
449 }
450 }
451
452 int
453 mapToStorage(request_rec *r) {
fc1c32f Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
454 DirConfig *config = getDirConfig(r);
e543369 Hongli Lai Fix page caching for non-GET requests. Add tests for file upload support...
FooBarWidget authored
455 bool forwardToRails;
456
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
457 if (determineRailsBaseURI(r, config) == NULL
914c171 Hongli Lai Attempt to autodetect the spawn server's location.
FooBarWidget authored
458 || fileExists(r->filename)) {
954a489 Hongli Lai Add support for multiple base URIs. Fix a bug in static asset handling.
FooBarWidget authored
459 /*
460 * fileExists():
461 * If the file already exists, serve it directly.
462 * This is for static assets like .css and .js files.
463 */
e543369 Hongli Lai Fix page caching for non-GET requests. Add tests for file upload support...
FooBarWidget authored
464 forwardToRails = false;
465 } else if (r->method_number == M_GET) {
7e363bf Hongli Lai Fix page caching for root page.
FooBarWidget authored
466 char *html_file;
467 size_t len;
468
469 len = strlen(r->filename);
470 if (len > 0 && r->filename[len - 1] == '/') {
471 html_file = apr_pstrcat(r->pool, r->filename, "index.html", NULL);
472 } else {
473 html_file = apr_pstrcat(r->pool, r->filename, ".html", NULL);
474 }
914c171 Hongli Lai Attempt to autodetect the spawn server's location.
FooBarWidget authored
475 if (fileExists(html_file)) {
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
476 /* If a .html version of the URI exists, serve it directly.
e543369 Hongli Lai Fix page caching for non-GET requests. Add tests for file upload support...
FooBarWidget authored
477 * We're essentially accelerating Rails page caching.
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
478 */
479 r->filename = html_file;
480 r->canonical_filename = html_file;
e543369 Hongli Lai Fix page caching for non-GET requests. Add tests for file upload support...
FooBarWidget authored
481 forwardToRails = false;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
482 } else {
e543369 Hongli Lai Fix page caching for non-GET requests. Add tests for file upload support...
FooBarWidget authored
483 forwardToRails = true;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
484 }
e543369 Hongli Lai Fix page caching for non-GET requests. Add tests for file upload support...
FooBarWidget authored
485 } else {
486 /*
487 * Non-GET requests are always forwarded to Rails.
488 * This important because of REST conventions, e.g.
489 * 'POST /foo' maps to 'FooController.create',
490 * while 'GET /foo' maps to 'FooController.index'.
491 * We wouldn't want our page caching support to interfere
492 * with that.
493 */
494 forwardToRails = true;
495 }
496
497 if (forwardToRails) {
498 /* Apache's default map_to_storage process does strange
499 * things with the filename. Suppose that the DocumentRoot
500 * is /website, on server http://test.com/. If we access
501 * http://test.com/foo/bar, and /website/foo/bar does not
502 * exist, then Apache will change the filename to
503 * /website/foo instead of the expected /website/bar.
504 * We make sure that doesn't happen.
505 *
506 * Incidentally, this also disables mod_rewrite. That is a
507 * good thing because the default Rails .htaccess file
508 * interferes with Passenger anyway (it delegates requests
509 * to the CGI script dispatch.cgi).
510 */
34a9266 Hongli Lai Add a 'RailsAllowModRewrite' option for users who really want to use mod...
FooBarWidget authored
511 if (config->allowModRewrite == DirConfig::UNSET
512 || config->allowModRewrite == DirConfig::DISABLED) {
513 /* Of course, we only do that if the config allows us
514 * to. Some people have complex mod_rewrite rules that
515 * they don't want to abandon. Those people will have to
516 * make sure that the Rails app's .htaccess doesn't
517 * interfere.
518 */
519 return OK;
520 } else {
521 return DECLINED;
522 }
e543369 Hongli Lai Fix page caching for non-GET requests. Add tests for file upload support...
FooBarWidget authored
523 } else {
524 return DECLINED;
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
525 }
526 }
527 };
528
529
530
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
531 /******************************************************************
532 * Below follows lightweight C wrappers around the C++ Hook class.
533 ******************************************************************/
534
e92c4f2 Hongli Lai Improve documentation
FooBarWidget authored
535 /**
536 * @ingroup Hooks
537 * @{
538 */
539
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
540 static Hooks *hooks = NULL;
541
542 static apr_status_t
543 destroy_hooks(void *arg) {
544 delete hooks;
545 return APR_SUCCESS;
546 }
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
547
548 static int
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
549 init_module(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) {
550 /*
551 * 1. Apache on Unix calls the post_config hook twice, once before detach() and once
552 * after. On Windows it never calls detach().
553 * 2. When Apache is compiled to use DSO modules, the modules are unloaded between the
554 * two post_config hook calls.
555 * 3. On Unix, if the -X commandline option is given, detach() will not be called.
556 *
557 * Because of these 3 issues (and especially #2), we only want to intialize the second
558 * time the post_config hook is called.
559 */
560 void *firstInitCall = NULL;
561 apr_pool_t *processPool = s->process->pool;
562
563 apr_pool_userdata_get(&firstInitCall, "mod_passenger", processPool);
564 if (firstInitCall == NULL) {
565 apr_pool_userdata_set((const void *) 1, "mod_passenger",
566 apr_pool_cleanup_null, processPool);
567 return OK;
568 } else {
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
569 try {
570 hooks = new Hooks(pconf, plog, ptemp, s);
571 apr_pool_cleanup_register(pconf, NULL,
572 destroy_hooks,
573 apr_pool_cleanup_null);
574 return OK;
81a559e Hongli Lai Aggressively report threading errors and associated system settings.
FooBarWidget authored
575 } catch (const thread_resource_error &e) {
576 struct rlimit lim;
577 string pthread_threads_max;
578
579 lim.rlim_cur = 0;
580 lim.rlim_max = 0;
581 getrlimit(RLIMIT_NPROC, &lim);
582 #ifdef PTHREAD_THREADS_MAX
583 pthread_threads_max = toString(PTHREAD_THREADS_MAX);
584 #else
585 pthread_threads_max = "unknown";
586 #endif
587
588 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
589 "*** Passenger could not be initialize because a "
590 "threading resource could not be allocated or initialized. "
591 "The error message is:");
592 fprintf(stderr,
593 " %s\n\n"
594 "System settings:\n"
595 " RLIMIT_NPROC: soft = %d, hard = %d\n"
596 " PTHREAD_THREADS_MAX: %s\n"
597 "\n",
598 e.what(),
599 (int) lim.rlim_cur, (int) lim.rlim_max,
600 pthread_threads_max.c_str());
601
602 fprintf(stderr, "Output of 'uname -a' follows:\n");
603 fflush(stderr);
604 system("uname -a >&2");
605
606 fprintf(stderr, "\nOutput of 'ulimit -a' follows:\n");
607 fflush(stderr);
608 system("ulimit -a >&2");
609
610 return DECLINED;
611
b4ad493 Hongli Lai - Correctly honor server-wide global configuration options such as 'Rail...
FooBarWidget authored
612 } catch (const exception &e) {
613 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
614 "*** Passenger could not be initialized because of this error: %s",
615 e.what());
616 hooks = NULL;
617 return DECLINED;
618 }
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
619 }
620 }
621
622 static void
623 init_child(apr_pool_t *pchild, server_rec *s) {
624 if (hooks != NULL) {
625 return hooks->initChild(pchild, s);
626 }
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
627 }
628
629 static int
630 handle_request(request_rec *r) {
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
631 if (hooks != NULL) {
632 return hooks->handleRequest(r);
633 } else {
634 return DECLINED;
635 }
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
636 }
637
638 static int
639 map_to_storage(request_rec *r) {
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
640 if (hooks != NULL) {
641 return hooks->mapToStorage(r);
642 } else {
643 return DECLINED;
644 }
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
645 }
646
e92c4f2 Hongli Lai Improve documentation
FooBarWidget authored
647 /**
648 * Apache hook registration function.
649 */
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
650 void
651 passenger_register_hooks(apr_pool_t *p) {
f1725e9 Hongli Lai - Refactor the Hook class, and make it more 'C++-ey'. I.e. make less use...
FooBarWidget authored
652 ap_hook_post_config(init_module, NULL, NULL, APR_HOOK_MIDDLE);
653 ap_hook_child_init(init_child, NULL, NULL, APR_HOOK_MIDDLE);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
654 ap_hook_map_to_storage(map_to_storage, NULL, NULL, APR_HOOK_FIRST);
34a9266 Hongli Lai Add a 'RailsAllowModRewrite' option for users who really want to use mod...
FooBarWidget authored
655 ap_hook_handler(handle_request, NULL, NULL, APR_HOOK_MIDDLE);
348e8f9 Hongli Lai mod_rails is more usable now though it still crashes randomly.
FooBarWidget authored
656 }
e92c4f2 Hongli Lai Improve documentation
FooBarWidget authored
657
658 /**
659 * @}
660 */
Something went wrong with that request. Please try again.