Skip to content

Commit

Permalink
Canonicalize Rails application root paths.
Browse files Browse the repository at this point in the history
  • Loading branch information
FooBarWidget committed Mar 12, 2008
1 parent b7c22ea commit ecde811
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 13 deletions.
30 changes: 17 additions & 13 deletions ext/apache2/Hooks.cpp
Expand Up @@ -72,7 +72,9 @@ class Hooks {
const string &base(*it);
if ( base == "/"
|| ( uri_len == base.size() && memcmp(uri, base.c_str(), uri_len) == 0 )
|| ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0 && uri[base.size()] == '/' )) {
|| ( uri_len > base.size() && memcmp(uri, base.c_str(), base.size()) == 0
&& uri[base.size()] == '/' )
) {
return apr_pstrdup(r->pool, base.c_str());
}
}
Expand All @@ -85,24 +87,26 @@ class Hooks {
return NULL;
}

const char *determineRailsDir(request_rec *r, const char *baseURI) {
string determineRailsDir(request_rec *r, const char *baseURI) {
const char *docRoot = ap_document_root(r);
size_t len = strlen(docRoot);
if (len > 0) {
string temp;
string path;
if (docRoot[len - 1] == '/') {
temp.assign(docRoot, len - 1);
path.assign(docRoot, len - 1);
} else {
temp.assign(docRoot, len);
path.assign(docRoot, len);
}
temp.append(baseURI);
return apr_pstrdup(r->pool, temp.c_str());
if (strcmp(baseURI, "/") != 0) {
path.append(baseURI);
}
return path;
} else {
return NULL;
return "";
}
}

bool verifyRailsDir(apr_pool_t *pool, const char *dir) {
bool verifyRailsDir(apr_pool_t *pool, const string &dir) {
string temp(dir);
temp.append("/../config/environment.rb");
return fileExists(temp.c_str());
Expand Down Expand Up @@ -316,8 +320,8 @@ class Hooks {
return DECLINED;
}

const char *railsDir = determineRailsDir(r, railsBaseURI);
if (railsDir == NULL) {
string railsDir(determineRailsDir(r, railsBaseURI));
if (railsDir.empty()) {
ap_set_content_type(r, "text/html; charset=UTF-8");
ap_rputs("<h1>Passenger error #1</h1>\n", r);
ap_rputs("Cannot determine the location of the Rails application's \"public\" directory.", r);
Expand All @@ -326,7 +330,7 @@ class Hooks {
ap_set_content_type(r, "text/html; charset=UTF-8");
ap_rputs("<h1>Passenger error #2</h1>\n", r);
ap_rputs("Passenger thinks that the Rails application's \"public\" directory is \"", r);
ap_rputs(ap_escape_html(r->pool, railsDir), r);
ap_rputs(ap_escape_html(r->pool, railsDir.c_str()), r);
ap_rputs("\", but it doesn't seem to be valid.", r);
return OK;
}
Expand All @@ -343,7 +347,7 @@ class Hooks {

P_DEBUG("Processing HTTP request: " << r->uri);
try {
session = applicationPool->get(string(railsDir) + "/..");
session = applicationPool->get(canonicalizePath(railsDir + "/.."));
} catch (const SpawnException &e) {
if (e.hasErrorPage()) {
ap_set_content_type(r, "text/html; charset=utf-8");
Expand Down
25 changes: 25 additions & 0 deletions ext/apache2/Utils.cpp
@@ -1,6 +1,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <climits>
#include <unistd.h>
#include <fstream>
#include <iostream>
Expand Down Expand Up @@ -79,4 +80,28 @@ findSpawnServer() {
return "";
}

string
canonicalizePath(const string &path) {
#ifdef __GLIBC__
// We're using a GNU extension here. See the 'BUGS'
// section of the realpath(3) Linux manpage for
// rationale.
char *tmp = realpath(path.c_str(), NULL);
if (tmp == NULL) {
return "";
} else {
string result(tmp);
free(tmp);
return result;
}
#else
char tmp[PATH_MAX];
if (realpath(path.c_str(), tmp) == NULL) {
return "";
} else {
return tmp;
}
#endif
}

} // namespace Passenger
9 changes: 9 additions & 0 deletions ext/apache2/Utils.h
Expand Up @@ -88,6 +88,15 @@ bool fileExists(const char *filename);
*/
string findSpawnServer();

/**
* Returns a canonical version of the specified path. All symbolic links
* and relative path elements are resolved.
* Returns an empty string if something went wrong.
*
* @ingroup Support
*/
string canonicalizePath(const string &path);


#ifdef PASSENGER_DEBUG
#define P_DEBUG(expr) \
Expand Down

0 comments on commit ecde811

Please sign in to comment.