2 http://code.google.com/p/phusion-passenger/issues/detail?id=30&colspec=ID%20Type%20Status%20Priority%20Milestone%20Stars%20Summary
3 http://code.google.com/p/phusion-passenger/issues/detail?id=136&colspec=ID%20Type%20Status%20Priority%20Milestone%20Stars%20Summary
5 Problem: The problem with RailsBaseURI is that it expects Rails directory
6 to be in virtualhost's documentroot. If it does'nt then you have to create
7 symlink to use rails application outside of document root.
9 Fix: Instead of creating symlinks there could be second optional argument
10 for RailsBaseURI which specifies full path to Rails application's public
13 For example, instead of creating symlink /var/www/somehost/railsapp1 ->
14 /home/user/railsapp1/public and:
16 DocumentRoot /var/www/somehost
17 RailsBaseURI /railsapp1
20 we skip the symlink and specify the full path in apache conf:
22 DocumentRoot /var/www/somehost
23 RailsBaseURI /railsapp1 /home/user/railsapp1/public
26 The patch (for 2.0.3) that does the thing is attached (patches also
31 1) Aliases and rewrite rules now apply when translating RailsBaseURI into
32 physical path. Resolved paths are cached.
33 2) Current behaviour remains: DocumentRoot+RailsBaseURI works also
34 3) If RailsBaseURI or RackBaseURI has second argument then this second argument
35 is used as physical path to rails public directory. This eliminates the need
36 for extra lookup using Apache subrequest and the overhead caused by it.
38 diff -wur ext/apache2/Configuration.cpp ext/apache2/Configuration.cpp
39 --- ext/apache2/Configuration.cpp 2008-08-09 15:19:15.000000000 +0300
40 +++ ext/apache2/Configuration.cpp 2008-09-23 22:06:15.000000000 +0300
42 DirConfig *add = (DirConfig *) addv;
44 config->railsBaseURIs = base->railsBaseURIs;
45 - for (set<string>::const_iterator it(add->railsBaseURIs.begin()); it != add->railsBaseURIs.end(); it++) {
46 + for (set<BaseURIConfig*>::const_iterator it(add->railsBaseURIs.begin()); it != add->railsBaseURIs.end(); it++) {
47 config->railsBaseURIs.insert(*it);
49 config->rackBaseURIs = base->rackBaseURIs;
50 - for (set<string>::const_iterator it(add->rackBaseURIs.begin()); it != add->rackBaseURIs.end(); it++) {
51 + for (set<BaseURIConfig*>::const_iterator it(add->rackBaseURIs.begin()); it != add->rackBaseURIs.end(); it++) {
52 config->rackBaseURIs.insert(*it);
56 *************************************************/
59 -cmd_rails_base_uri(cmd_parms *cmd, void *pcfg, const char *arg) {
60 +cmd_rails_base_uri(cmd_parms *cmd, void *pcfg, const char *arg, const char *arg2) {
61 DirConfig *config = (DirConfig *) pcfg;
62 + BaseURIConfig *bConfig = new BaseURIConfig;
63 if (strlen(arg) == 0) {
64 return "RailsBaseURI may not be set to the empty string";
65 } else if (arg[0] != '/') {
66 return "RailsBaseURI must start with a slash (/)";
67 } else if (strlen(arg) > 1 && arg[strlen(arg) - 1] == '/') {
68 return "RailsBaseURI must not end with a slash (/)";
70 - config->railsBaseURIs.insert(arg);
74 + apr_pool_cleanup_register(cmd->pool, bConfig, destroy_config_struct<BaseURIConfig>, apr_pool_cleanup_null);
76 + bConfig->baseURI = arg;
79 + bConfig->publicDirectory = arg2;
82 + config->railsBaseURIs.insert(bConfig);
88 *************************************************/
91 -cmd_rack_base_uri(cmd_parms *cmd, void *pcfg, const char *arg) {
92 +cmd_rack_base_uri(cmd_parms *cmd, void *pcfg, const char *arg, const char *arg2) {
93 DirConfig *config = (DirConfig *) pcfg;
94 + BaseURIConfig *bConfig = new BaseURIConfig;
95 if (strlen(arg) == 0) {
96 return "RackBaseURI may not be set to the empty string";
97 } else if (arg[0] != '/') {
98 return "RackBaseURI must start with a slash (/)";
99 } else if (strlen(arg) > 1 && arg[strlen(arg) - 1] == '/') {
100 return "RackBaseURI must not end with a slash (/)";
102 - config->rackBaseURIs.insert(arg);
106 + apr_pool_cleanup_register(cmd->pool, bConfig, destroy_config_struct<BaseURIConfig>, apr_pool_cleanup_null);
108 + bConfig->baseURI = arg;
111 + bConfig->publicDirectory = arg2;
113 + config->rackBaseURIs.insert(bConfig);
119 "The user that Rails/Rack applications must run as when user switching fails or is disabled."),
121 // Rails-specific settings.
122 - AP_INIT_TAKE1("RailsBaseURI",
123 + AP_INIT_TAKE12("RailsBaseURI",
124 (Take1Func) cmd_rails_base_uri,
128 "The spawn method to use."),
130 // Rack-specific settings.
131 - AP_INIT_TAKE1("RackBaseURI",
132 + AP_INIT_TAKE12("RackBaseURI",
133 (Take1Func) cmd_rack_base_uri,
136 diff -wur ext/apache2/Configuration.hpp ext/apache2/Configuration.hpp
137 --- ext/apache2/Configuration.hpp 2008-08-09 15:19:33.000000000 +0300
138 +++ ext/apache2/Configuration.hpp 2008-09-23 22:06:15.000000000 +0300
143 +struct BaseURIConfig {
144 + std::string baseURI;
145 + std::string publicDirectory;
149 * Per-directory configuration information.
151 * Use the getter methods to query information, because those will return
152 * the default value if the value is not specified.
155 enum Threeway { ENABLED, DISABLED, UNSET };
156 enum SpawnMethod { SM_UNSET, SM_SMART, SM_SMART_LV2, SM_CONSERVATIVE };
160 - std::set<std::string> railsBaseURIs;
161 - std::set<std::string> rackBaseURIs;
162 + std::set<BaseURIConfig*> railsBaseURIs;
163 + std::set<BaseURIConfig*> rackBaseURIs;
165 /** Whether to autodetect Rails applications. */
166 Threeway autoDetectRails;
167 diff -wur ext/apache2/DirectoryMapper.h ext/apache2/DirectoryMapper.h
168 --- ext/apache2/DirectoryMapper.h 2008-08-09 15:19:15.000000000 +0300
169 +++ ext/apache2/DirectoryMapper.h 2008-09-23 22:13:36.000000000 +0300
171 // compilation will fail on OpenBSD.
173 #include <http_core.h>
174 +#include <http_request.h>
176 namespace Passenger {
182 + BaseURIConfig *bConfig;
183 ApplicationType appType;
185 inline bool shouldAutoDetectRails() {
188 baseURIKnown = false;
198 - set<string>::const_iterator it;
199 + set<BaseURIConfig *>::const_iterator it;
200 const char *uri = r->uri;
201 size_t uri_len = strlen(uri);
206 for (it = config->railsBaseURIs.begin(); it != config->railsBaseURIs.end(); it++) {
207 - const string &base(*it);
208 + BaseURIConfig * bc = (*it);
209 + const string base = bc->baseURI;
211 || ( uri_len == base.size() && memcmp(uri, base.c_str(), uri_len) == 0 )
212 || ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0
213 @@ -155,13 +158,15 @@
215 baseURI = base.c_str();
217 + this->bConfig = bc;
222 UPDATE_TRACE_POINT();
223 for (it = config->rackBaseURIs.begin(); it != config->rackBaseURIs.end(); it++) {
224 - const string &base(*it);
225 + BaseURIConfig * bc = (*it);
226 + const string base = bc->baseURI;
228 || ( uri_len == base.size() && memcmp(uri, base.c_str(), uri_len) == 0 )
229 || ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0
232 baseURI = base.c_str();
234 + this->bConfig = bc;
238 @@ -213,26 +219,14 @@
242 - const char *docRoot = ap_document_root(r);
243 - size_t len = strlen(docRoot);
246 - if (docRoot[len - 1] == '/') {
247 - path.assign(docRoot, len - 1);
249 - path.assign(docRoot, len);
251 - if (strcmp(baseURI, "/") != 0) {
252 - /* Application is deployed in a sub-URI.
253 - * This is probably a symlink, so let's resolve it.
255 - path.append(baseURI);
256 - path = resolveSymlink(path);
261 + if (this->bConfig->publicDirectory.empty ()) {
262 + request_rec *sub_req;
263 + sub_req = ap_sub_req_lookup_uri(baseURI, r, NULL);
265 + this->bConfig->publicDirectory = resolveSymlink(sub_req->filename);
268 + return this->bConfig->publicDirectory;