Exemplo n.º 1
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;
}
Exemplo n.º 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 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;
}