fix all the $_SERVER urls - take 2
I needed to `m_origPathInfo.reset()` in `RequestURI::clear`
Esse commit está contido em:
@@ -362,11 +362,10 @@ void HttpProtocol::PrepareSystemVariables(Transport *transport,
|
||||
} else {
|
||||
server.set(s_SCRIPT_NAME, r.resolvedURL());
|
||||
}
|
||||
if (!r.rewritten() && r.pathInfo().empty()) {
|
||||
server.set(s_PHP_SELF, r.resolvedURL());
|
||||
} else {
|
||||
// when URL is rewritten, or pathinfo is not empty, use original URL
|
||||
if (r.rewritten()) {
|
||||
server.set(s_PHP_SELF, r.originalURL());
|
||||
} else {
|
||||
server.set(s_PHP_SELF, r.resolvedURL() + r.origPathInfo());
|
||||
}
|
||||
|
||||
server.set(s_SCRIPT_FILENAME, r.absolutePath());
|
||||
|
||||
@@ -68,13 +68,11 @@ bool RequestURI::process(const VirtualHost *vhost, Transport *transport,
|
||||
m_originalURL = StringUtil::UrlDecode(m_originalURL, false);
|
||||
|
||||
// Fast path for files that exist
|
||||
String canon = Util::canonicalize(string(m_originalURL.c_str(),
|
||||
m_originalURL.size()));
|
||||
String relUrl(canon.charAt(0) == '/' ? canon.substr(1) : canon);
|
||||
if (virtualFileExists(vhost, sourceRoot, pathTranslation, relUrl)) {
|
||||
m_rewrittenURL = relUrl;
|
||||
m_resolvedURL = std::move(relUrl);
|
||||
PrependSlash(m_resolvedURL);
|
||||
String canon(Util::canonicalize(m_originalURL.c_str(), m_originalURL.size()),
|
||||
AttachString);
|
||||
if (virtualFileExists(vhost, sourceRoot, pathTranslation, canon)) {
|
||||
m_rewrittenURL = canon;
|
||||
m_resolvedURL = canon;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,8 +140,9 @@ bool RequestURI::rewriteURL(const VirtualHost *vhost, Transport *transport,
|
||||
}
|
||||
splitURL(m_rewrittenURL, m_rewrittenURL, m_queryString);
|
||||
}
|
||||
m_rewrittenURL = Util::canonicalize(string(m_rewrittenURL.c_str(),
|
||||
m_rewrittenURL.size()));
|
||||
m_rewrittenURL = String(
|
||||
Util::canonicalize(m_rewrittenURL.c_str(), m_rewrittenURL.size()),
|
||||
AttachString);
|
||||
if (!m_rewritten && m_rewrittenURL.charAt(0) == '/') {
|
||||
// A un-rewritten URL is always relative, so remove prepending /
|
||||
m_rewrittenURL = m_rewrittenURL.substr(1);
|
||||
@@ -184,31 +183,43 @@ bool RequestURI::rewriteURL(const VirtualHost *vhost, Transport *transport,
|
||||
bool RequestURI::resolveURL(const VirtualHost *vhost,
|
||||
const string &pathTranslation,
|
||||
const string &sourceRoot) {
|
||||
m_resolvedURL = m_rewrittenURL;
|
||||
|
||||
String startURL;
|
||||
if (m_rewritten) {
|
||||
startURL = m_rewrittenURL;
|
||||
} else {
|
||||
startURL = m_originalURL;
|
||||
}
|
||||
startURL = String(
|
||||
Util::canonicalize(startURL.c_str(), startURL.size(), false),
|
||||
AttachString);
|
||||
m_resolvedURL = startURL;
|
||||
|
||||
while (!virtualFileExists(vhost, sourceRoot, pathTranslation,
|
||||
m_resolvedURL)) {
|
||||
int pos = m_resolvedURL.rfind('/');
|
||||
if (pos <= 0) {
|
||||
// when none of the <subpath> exists, we give up, and try default doc
|
||||
m_resolvedURL = m_rewrittenURL;
|
||||
m_resolvedURL = startURL;
|
||||
if (!m_resolvedURL.empty() &&
|
||||
m_resolvedURL.charAt(m_resolvedURL.length() - 1) != '/') {
|
||||
m_resolvedURL += "/";
|
||||
}
|
||||
m_resolvedURL += String(RuntimeOption::DefaultDocument);
|
||||
m_pathInfo.reset();
|
||||
m_origPathInfo.reset();
|
||||
if (virtualFileExists(vhost, sourceRoot, pathTranslation,
|
||||
m_resolvedURL)) {
|
||||
m_defaultDoc = true;
|
||||
PrependSlash(m_resolvedURL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
m_resolvedURL = m_rewrittenURL.substr(0, pos);
|
||||
m_pathInfo = m_rewrittenURL.substr(pos);
|
||||
m_resolvedURL = startURL.substr(0, pos);
|
||||
m_origPathInfo = startURL.substr(pos);
|
||||
}
|
||||
PrependSlash(m_resolvedURL);
|
||||
m_pathInfo = String(
|
||||
Util::canonicalize(m_origPathInfo.c_str(), m_origPathInfo.size()),
|
||||
AttachString);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -219,13 +230,14 @@ bool RequestURI::virtualFileExists(const VirtualHost *vhost,
|
||||
if (filename.empty() || filename.charAt(filename.length() - 1) == '/') {
|
||||
return false;
|
||||
}
|
||||
String canon(Util::canonicalize(filename.c_str(), filename.size()),
|
||||
AttachString);
|
||||
if (!vhost->getDocumentRoot().empty()) {
|
||||
string fullname = filename.data();
|
||||
if (fullname[0] == '/') {
|
||||
string fullname = canon.data();
|
||||
while (fullname[0] == '/') {
|
||||
fullname = fullname.substr(1);
|
||||
} else {
|
||||
fullname = pathTranslation + fullname;
|
||||
}
|
||||
fullname = pathTranslation + fullname;
|
||||
m_path = fullname;
|
||||
m_absolutePath = String(sourceRoot) + m_path;
|
||||
processExt();
|
||||
@@ -241,8 +253,8 @@ bool RequestURI::virtualFileExists(const VirtualHost *vhost,
|
||||
(stat(m_absolutePath.c_str(), &st) == 0 &&
|
||||
(st.st_mode & S_IFMT) == S_IFREG);
|
||||
}
|
||||
m_path = filename;
|
||||
m_absolutePath = String(sourceRoot) + filename;
|
||||
m_path = canon;
|
||||
m_absolutePath = String(sourceRoot) + canon;
|
||||
processExt();
|
||||
return true;
|
||||
}
|
||||
@@ -327,6 +339,7 @@ void RequestURI::dump() {
|
||||
m_rewrittenURL.dump();
|
||||
m_resolvedURL.dump();
|
||||
m_pathInfo.dump();
|
||||
m_origPathInfo.dump();
|
||||
m_absolutePath.dump();
|
||||
m_path.dump();
|
||||
}
|
||||
@@ -337,6 +350,7 @@ void RequestURI::clear() {
|
||||
m_rewrittenURL.reset();
|
||||
m_resolvedURL.reset();
|
||||
m_pathInfo.reset();
|
||||
m_origPathInfo.reset();
|
||||
m_absolutePath.reset();
|
||||
m_path.reset();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
RequestURI(const VirtualHost *vhost, Transport *transport,
|
||||
const std::string &pathTranslation,
|
||||
const std::string &sourceRoot);
|
||||
RequestURI(const std::string & rpcFunc);
|
||||
explicit RequestURI(const std::string & rpcFunc);
|
||||
|
||||
CStrRef originalURL() const { return m_originalURL; }
|
||||
CStrRef resolvedURL() const { return m_resolvedURL; }
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
const char *ext() const { return m_ext; }
|
||||
CStrRef absolutePath() const { return m_absolutePath; }
|
||||
CStrRef pathInfo() const { return m_pathInfo; }
|
||||
CStrRef origPathInfo() const { return m_origPathInfo; }
|
||||
|
||||
bool rewritten() const { return m_rewritten; }
|
||||
bool defaultDoc() const { return m_defaultDoc; }
|
||||
@@ -59,6 +60,7 @@ private:
|
||||
// without pathinfo
|
||||
|
||||
String m_pathInfo;
|
||||
String m_origPathInfo;
|
||||
String m_absolutePath;
|
||||
String m_path; // path relative to SourceRoot
|
||||
|
||||
|
||||
+14
-11
@@ -552,7 +552,9 @@ std::string Util::canonicalize(const std::string &path) {
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const char *Util::canonicalize(const char *addpath, size_t addlen) {
|
||||
const char *Util::canonicalize(const char *addpath, size_t addlen,
|
||||
bool collapse_slashes /* = true */) {
|
||||
assert(strlen(addpath) == addlen);
|
||||
// 4 for slashes at start, after root, and at end, plus trailing
|
||||
// null
|
||||
size_t maxlen = addlen + 4;
|
||||
@@ -566,7 +568,7 @@ const char *Util::canonicalize(const char *addpath, size_t addlen) {
|
||||
|
||||
char *path = (char *)malloc(maxlen);
|
||||
|
||||
if (addpath[0] == '/') {
|
||||
if (addpath[0] == '/' && collapse_slashes) {
|
||||
/* Ignore the given root path, strip off leading
|
||||
* '/'s to a single leading '/' from the addpath,
|
||||
* and leave addpath at the first non-'/' character.
|
||||
@@ -586,9 +588,13 @@ const char *Util::canonicalize(const char *addpath, size_t addlen) {
|
||||
}
|
||||
seglen = next - addpath;
|
||||
|
||||
if (seglen == 0 || (seglen == 1 && addpath[0] == '.')) {
|
||||
/* noop segment (/ or ./) so skip it
|
||||
*/
|
||||
if (seglen == 0) {
|
||||
/* / */
|
||||
if (!collapse_slashes) {
|
||||
path[pathlen++] = '/';
|
||||
}
|
||||
} else if (seglen == 1 && addpath[0] == '.') {
|
||||
/* ./ */
|
||||
} else if (seglen == 2 && addpath[0] == '.' && addpath[1] == '.') {
|
||||
/* backpath (../) */
|
||||
if (pathlen == 1 && path[0] == '/') {
|
||||
@@ -603,15 +609,13 @@ const char *Util::canonicalize(const char *addpath, size_t addlen) {
|
||||
memcpy(path + pathlen, "../", *next ? 3 : 2);
|
||||
pathlen += *next ? 3 : 2;
|
||||
} else {
|
||||
/* otherwise crop the prior segment
|
||||
*/
|
||||
/* otherwise crop the prior segment */
|
||||
do {
|
||||
--pathlen;
|
||||
} while (pathlen && path[pathlen - 1] != '/');
|
||||
}
|
||||
} else {
|
||||
/* An actual segment, append it to the destination path
|
||||
*/
|
||||
/* An actual segment, append it to the destination path */
|
||||
if (*next) {
|
||||
seglen++;
|
||||
}
|
||||
@@ -619,8 +623,7 @@ const char *Util::canonicalize(const char *addpath, size_t addlen) {
|
||||
pathlen += seglen;
|
||||
}
|
||||
|
||||
/* Skip over trailing slash to the next segment
|
||||
*/
|
||||
/* Skip over trailing slash to the next segment */
|
||||
if (*next) {
|
||||
++next;
|
||||
}
|
||||
|
||||
+2
-1
@@ -174,7 +174,8 @@ std::string relativePath(const std::string fromDir, const std::string toFile);
|
||||
* Canonicalize path to remove "..", "." and "\/", etc..
|
||||
*/
|
||||
std::string canonicalize(const std::string &path);
|
||||
const char *canonicalize(const char *path, size_t len);
|
||||
const char *canonicalize(const char *path, size_t len,
|
||||
bool collapse_slashes = true);
|
||||
|
||||
/**
|
||||
* Makes sure there is ending slash by changing "path/name" to "path/name/".
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário