예제 #1
0
/**
 * Precondition: m_rewrittenURL is set
 * Postcondition: Output is true and m_path and m_absolutePath are set OR
 *   output is false and no file was found
 */
bool RequestURI::resolveURL(const VirtualHost *vhost,
                            const string &pathTranslation,
                            const string &sourceRoot) {
  m_resolvedURL = m_rewrittenURL;
  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;
      if (!m_resolvedURL.empty() &&
          m_resolvedURL.charAt(m_resolvedURL.length() - 1) != '/') {
        m_resolvedURL += "/";
      }
      m_resolvedURL += String(RuntimeOption::DefaultDocument);
      m_pathInfo.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);
  }
  PrependSlash(m_resolvedURL);
  return true;
}
예제 #2
0
/**
 * Precondition: m_originalURL and m_queryString are set
 * Postcondition: Output is false and we are redirecting OR
 *  m_rewrittenURL is set and m_queryString is updated if needed
 */
bool RequestURI::rewriteURL(const VirtualHost *vhost, Transport *transport,
                            const string &pathTranslation,
                            const string &sourceRoot) {
  bool qsa = false;
  int redirect = 0;
  string host = transport->getHeader("host");
  m_rewrittenURL = m_originalURL;
  if (vhost->rewriteURL(host, m_rewrittenURL, qsa, redirect)) {
    m_rewritten = true;
    if (qsa && !m_queryString.empty()) {
      m_rewrittenURL += (m_rewrittenURL.find('?') < 0) ? "?" : "&";
      m_rewrittenURL += m_queryString;
    }
    if (redirect) {
      if (m_rewrittenURL.substr(0, 7) != s_http &&
          m_rewrittenURL.substr(0, 8) != s_https) {
        PrependSlash(m_rewrittenURL);
      }
      transport->redirect(m_rewrittenURL.c_str(), redirect, "rewriteURL");
      return false;
    }
    splitURL(m_rewrittenURL, m_rewrittenURL, m_queryString);
  }
  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);
  }

  // If the URL refers to a folder but does not end
  // with a slash, then we need to redictect
  String url = m_rewrittenURL;
  if (!url.empty() &&
      url.charAt(url.length() - 1) != '/') {
    if (virtualFolderExists(vhost, sourceRoot, pathTranslation, url)) {
      url += "/";
      m_rewritten = true;
      String queryStr;
      m_rewrittenURL = m_originalURL;
      m_rewrittenURL += "/";
      if (!m_queryString.empty()) {
        m_rewrittenURL += "?";
        m_rewrittenURL += m_queryString;
      }
      if (m_rewrittenURL.substr(0, 7) != s_http &&
          m_rewrittenURL.substr(0, 8) != s_https) {
        PrependSlash(m_rewrittenURL);
      }
      transport->redirect(m_rewrittenURL.c_str(), 301, "rewriteURL");
      return false;
    }
  }

  return true;
}
예제 #3
0
bool RequestURI::process(const VirtualHost *vhost, Transport *transport,
                         const string &sourceRoot,
                         const string &pathTranslation, const char *url) {
  splitURL(url, m_originalURL, m_queryString);
  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 = relUrl;
    PrependSlash(m_resolvedURL);
    return true;
  }

  if (!rewriteURL(vhost, transport, pathTranslation, sourceRoot)) {
    // Redirection
    m_done = true;
    return true;
  }
  if (!resolveURL(vhost, pathTranslation, sourceRoot)) {
    // Can't find
    return false;
  }
  return true;
}
예제 #4
0
/**
 * Precondition: m_originalURL and m_queryString are set
 * Postcondition: Output is false and we are redirecting OR
 *  m_rewrittenURL is set and m_queryString is updated if needed
 */
bool RequestURI::rewriteURL(const VirtualHost *vhost, Transport *transport,
                            const std::string &pathTranslation,
                            const std::string &sourceRoot) {
  bool qsa = false;
  int redirect = 0;
  std::string host = transport->getHeader("host");
  m_rewrittenURL = m_originalURL;
  if (vhost->rewriteURL(host, m_rewrittenURL, qsa, redirect)) {
    m_rewritten = true;
    if (qsa && !m_queryString.empty()) {
      m_rewrittenURL += (m_rewrittenURL.find('?') < 0) ? "?" : "&";
      m_rewrittenURL += m_queryString;
    }
    if (redirect) {
      if (m_rewrittenURL.substr(0, 7) != s_http &&
          m_rewrittenURL.substr(0, 8) != s_https) {
        PrependSlash(m_rewrittenURL);
      }
      if (redirect < 0) {
        std::string error;
        StringBuffer response;
        int code = 0;
        HttpProtocol::ProxyRequest(transport, true,
                                   m_rewrittenURL.toCppString(),
                                   code, error,
                                   response);
        if (!code) {
          transport->sendString(error, 500, false, false, "proxyRequest");
        } else {
          const char* respData = response.data();
          if (!respData) respData = "";
          transport->sendRaw(const_cast<char*>(respData),
                             response.size(), code);
        }
        transport->onSendEnd();
      } else {
        transport->redirect(m_rewrittenURL.c_str(), redirect);
      }
      return false;
    }
    splitURL(m_rewrittenURL, m_rewrittenURL, m_queryString);
  }
  m_rewrittenURL = FileUtil::canonicalize(m_rewrittenURL);
  if (!m_rewritten && m_rewrittenURL.charAt(0) == '/') {
    // A un-rewritten URL is always relative, so remove prepending /
    m_rewrittenURL = m_rewrittenURL.substr(1);
  }

  // If the URL refers to a folder but does not end
  // with a slash, then we need to redictect
  String url = m_rewrittenURL;
  if (!url.empty() &&
      url.charAt(url.length() - 1) != '/') {
    if (virtualFolderExists(vhost, sourceRoot, pathTranslation, url)) {
      if (m_originalURL.find("..") != String::npos) {
        transport->sendString(getDefault404(), 404);
        transport->onSendEnd();
        return false;
      }
      url += "/";
      m_rewritten = true;
      String queryStr;
      m_rewrittenURL = m_originalURL;
      m_rewrittenURL += "/";
      if (!m_queryString.empty()) {
        m_rewrittenURL += "?";
        m_rewrittenURL += m_queryString;
      }
      if (m_rewrittenURL.substr(0, 7) != s_http &&
          m_rewrittenURL.substr(0, 8) != s_https) {
        PrependSlash(m_rewrittenURL);
      }
      transport->redirect(m_rewrittenURL.c_str(), 301);
      return false;
    }
  }

  return true;
}