void HTTPTransportAgent::setConfig(SyncConfig &config)
{
    if (config.getUseProxy()) {
        setProxy(config.getProxyHost());
        UserIdentity identity = config.getProxyUser();
        Credentials cred = IdentityProviderCredentials(identity, config.getProxyPassword());
        setProxyAuth(cred.m_username, cred.m_password);
    }
    setUserAgent(config.getUserAgent());
    setSSL(config.findSSLServerCertificate(),
           config.getSSLVerifyServer(),
           config.getSSLVerifyHost());
}
Ejemplo n.º 2
0
void ProxygenTransport::onHeadersComplete(
  unique_ptr<HTTPMessage> msg) noexcept {

  Timer::GetMonotonicTime(m_requestStart);
  m_request = std::move(msg);
  if (m_request->isSecure()) {
    setSSL();
  }
  m_request->dumpMessage(4);
  auto method = m_request->getMethod();
  const auto& methodStr = m_request->getMethodString();
  if (method == HTTPMethod::GET) {
    m_method = Transport::Method::GET;
  } else if (method == HTTPMethod::POST ||
             s_post_methods.find(methodStr) != s_post_methods.end()) {
    m_method = Transport::Method::POST;
  } else if (method == HTTPMethod::HEAD) {
    m_method = Transport::Method::HEAD;
  } else if (method == HTTPMethod::CONNECT) {
    sendErrorResponse(400 /* Bad Request */);
    return;
  } else {
    // looks like proxygen HTTP parser understands a few more methods
    // than libevent:
    //   TRACE, COPY, MOVE, MKACTIVITY, CHECKOUT, MERGE, MSEARCH, NOTIFY,
    //   SUBSCRIBE, UNSUBSCRIBE, PATCH
    sendErrorResponse(400 /* Bad Request */);
    return;
  }
  m_extended_method = methodStr.c_str();

  const auto& headers = m_request->getHeaders();
  headers.forEach([&] (const std::string &header, const std::string &val) {
      m_requestHeaders[header.c_str()].push_back(val.c_str());
    });

  if (m_method == Transport::Method::POST && m_request->isHTTP1_1()) {
    const std::string& expectation =
      headers.getSingleOrEmpty(HTTP_HEADER_EXPECT);
    if (!expectation.empty()) {
      bool sendEom = false;
      HTTPMessage response;
      if (!boost::iequals(expectation, "100-continue")) {
        response.setStatusCode(417);
        response.setStatusMessage(HTTPMessage::getDefaultReason(417));
        response.getHeaders().add(HTTP_HEADER_CONNECTION, "close");
        sendEom = true;
      } else {
        response.setStatusCode(100);
        response.setStatusMessage(HTTPMessage::getDefaultReason(100));
      }
      response.setHTTPVersion(1, 1);
      response.dumpMessage(4);
      m_clientTxn->sendHeaders(response);
      if (sendEom) {
        m_responseCode = response.getStatusCode();
        m_responseCodeInfo = response.getStatusMessage();
        m_server->onRequestError(this);
        m_clientTxn->sendEOM();
        // this object is no longer valid
        return;
      }
    }
  }

  if (!bufferRequest()) {
    m_enqueued = true;
    m_server->onRequest(shared_from_this());
  } // otherwise we wait for EOM
}
Ejemplo n.º 3
0
void FastCGITransport::onHeadersComplete() {
  m_requestURI = getRawHeader(s_requestURI);
  m_remoteHost = getRawHeader(s_remoteHost);
  m_remoteAddr = getRawHeader(s_remoteAddr);
  m_serverName = getRawHeader(s_serverName);
  m_serverAddr = getRawHeader(s_serverAddr);
  m_serverSoftware = getRawHeader(s_serverSoftware);
  m_extendedMethod = getRawHeader(s_extendedMethod);
  m_httpVersion = getRawHeader(s_httpVersion);
  m_serverObject = getRawHeader(s_scriptName);
  m_scriptFilename = getRawHeader(s_scriptFilename);
  m_pathTranslated = getRawHeader(s_pathTranslated);
  if (getRawHeaderPtr(s_pathInfo) != nullptr) {
    m_pathInfoSet = true;
  }
  m_pathInfo = getRawHeader(s_pathInfo);
  m_documentRoot = getRawHeader(s_documentRoot);
  if (!m_documentRoot.empty() &&
      m_documentRoot[m_documentRoot.length() - 1] != '/') {
    m_documentRoot += '/';
  }

  m_serverPort = getIntHeader(s_serverPort);
  m_requestSize = getIntHeader(s_contentLength);
  int port = getIntHeader(s_remotePort);
  if (port < std::numeric_limits<decltype(m_remotePort)>::min() ||
      port > std::numeric_limits<decltype(m_remotePort)>::max()) {
    port = 0;
  }
  m_remotePort = port;

  auto* value = getRawHeaderPtr(s_https);
  if (value != nullptr && !value->empty()) {
    auto lValue = std::string{*value};
    for (auto& c : lValue) {
      c = std::toupper(c);
    }
    // IIS sets this value but sets it to off when SSL is off.
    if (lValue != "OFF") {
      setSSL();
    }
  }

  // Treat everything apart from GET and HEAD as a post to be like php-src.
  if (m_extendedMethod == "GET") {
    m_method = Method::GET;
  } else if (m_extendedMethod == "HEAD") {
    m_method = Method::HEAD;
  } else {
    m_method = Method::POST;
  }

  if (m_httpVersion.empty()) {
    // If we didn't receive a version, assume default transport version.
    // Flushing the request early requires HTTP_VERSION to be 1.1.
    m_httpVersion = Transport::getHTTPVersion();
  }

  if (m_scriptFilename.empty() || RuntimeOption::ServerFixPathInfo) {
    // According to php-fpm, some servers don't set SCRIPT_FILENAME. In
    // this case, it uses PATH_TRANSLATED.
    // Added runtime option to change m_scriptFilename to s_pathTranslated
    // which will allow mod_fastcgi and mod_action to work correctly.
    m_scriptFilename = getRawHeader(s_pathTranslated);
  }

  // do a check for mod_proxy_fcgi and remove the extra portions of the string
  if (m_scriptFilename.find(s_modProxy) == 0) {
    // remove the proxy:type + :// from the start.
    int proxyPos = m_scriptFilename.find(s_modProxySearch);
    if (proxyPos != String::npos) {
      m_scriptFilename = m_scriptFilename.substr(proxyPos + s_modProxySearch.size());
    }
    // remove everything before the first / which is host:port
    int slashPos = m_scriptFilename.find(s_slash);
    if (slashPos != String::npos) {
      m_scriptFilename = m_scriptFilename.substr(slashPos);
    }
    // remove everything after the first ?
    int questionPos = m_scriptFilename.find(s_questionMark);
    if (questionPos != String::npos) {
      m_scriptFilename = m_scriptFilename.substr(0, questionPos);
    }
  }

  // RequestURI needs script_filename and path_translated to not include
  // the document root
  if (!m_pathTranslated.empty()) {
    if (m_pathTranslated.find(m_documentRoot) == 0) {
      m_pathTranslated = m_pathTranslated.substr(m_documentRoot.length());
    }
  }
  
  if (!m_scriptFilename.empty()) {
    if (m_scriptFilename.find(m_documentRoot) == 0) {
      m_scriptFilename = m_scriptFilename.substr(m_documentRoot.length());
    } else {
      // if the document root isn't in the url set document root to /
      m_documentRoot = "/";
    }
  }

  auto* queryString = getRawHeaderPtr(s_queryString);
  if (queryString != nullptr && !queryString->empty()) {
    m_serverObject += "?" + *queryString;
  }

  m_connection->handleRequest(m_id);
}
Ejemplo n.º 4
0
void FastCGITransport::onHeadersComplete() {
  m_requestURI = getRawHeader(s_requestURI);
  m_remoteHost = getRawHeader(s_remoteHost);
  m_remoteAddr = getRawHeader(s_remoteAddr);
  m_serverName = getRawHeader(s_serverName);
  m_serverAddr = getRawHeader(s_serverAddr);
  m_extendedMethod = getRawHeader(s_extendedMethod);
  m_httpVersion = getRawHeader(s_httpVersion);
  m_serverObject = getRawHeader(s_scriptName);
  m_pathTranslated = getRawHeader(s_pathTranslated);
  m_documentRoot = getRawHeader(s_documentRoot) + "/";

  m_serverPort = getIntHeader(s_serverPort);
  m_requestSize = getIntHeader(s_contentLength);
  int port = getIntHeader(s_remotePort);
  if (port < std::numeric_limits<decltype(m_remotePort)>::min() ||
      port > std::numeric_limits<decltype(m_remotePort)>::max()) {
    port = 0;
  }
  m_remotePort = port;

  auto* value = getRawHeaderPtr(s_https);
  if (value != nullptr && !value->empty()) {
    auto lValue = std::string{*value};
    for (auto& c : lValue) {
      c = std::toupper(c);
    }
    // IIS sets this value but sets it to off when SSL is off.
    if (lValue != "OFF") {
      setSSL();
    }
  }

  if (m_extendedMethod == "GET") {
    m_method = Method::GET;
  } else if (m_extendedMethod == "POST") {
    m_method = Method::POST;
  } else if (m_extendedMethod == "HEAD") {
    m_method = Method::HEAD;
  } else {
    m_method = Method::Unknown;
  }

  if (m_pathTranslated.empty()) {
    // If someone follows http://wiki.nginx.org/HttpFastcgiModule they won't
    // pass in PATH_TRANSLATED and instead will just send SCRIPT_FILENAME
    m_pathTranslated = getRawHeader(s_scriptFilename);
  }

  // do a check for mod_proxy_cgi and remove the start portion of the string
  const std::string modProxy = "proxy:fcgi://";
  if (m_pathTranslated.find(modProxy) == 0) {
    m_pathTranslated = m_pathTranslated.substr(modProxy.length());
    // remove everything before the first / which is host:port
    int slashPos = m_pathTranslated.find('/');
    if (slashPos != String::npos) {
      m_pathTranslated = m_pathTranslated.substr(slashPos);
    }
  }

  // RequestURI needs path_translated to not include the document root
  if (!m_pathTranslated.empty()) {
    if (m_pathTranslated.find(m_documentRoot) == 0) {
      m_pathTranslated = m_pathTranslated.substr(m_documentRoot.length());
    } else {
      // if the document root isn't in the url set document root to /
      m_documentRoot = "/";
    }
  }

  auto* queryString = getRawHeaderPtr(s_queryString);
  if (queryString != nullptr && !queryString->empty()) {
    m_serverObject += "?" + *queryString;
  }

  m_connection->handleRequest(m_id);
}
Ejemplo n.º 5
0
void FastCGITransport::onHeadersComplete() {
  m_requestURI = getRawHeader("REQUEST_URI");
  m_remoteHost = getRawHeader("REMOTE_HOST");
  m_remoteAddr = getRawHeader("REMOTE_ADDR");
  m_serverName = getRawHeader("SERVER_NAME");
  m_serverAddr = getRawHeader("SERVER_ADDR");
  m_extendedMethod = getRawHeader("REQUEST_METHOD");
  m_httpVersion = getRawHeader("HTTP_VERSION");
  m_documentRoot = getRawHeader("DOCUMENT_ROOT") + "/";

  try {
    int remote_port = std::stoi(getRawHeader("REMOTE_PORT"));
    if (remote_port < std::numeric_limits<decltype(m_remotePort)>::min() ||
        remote_port > std::numeric_limits<decltype(m_remotePort)>::max()) {
      m_remotePort = 0;
    }
    m_remotePort = remote_port;
  } catch (std::invalid_argument&) {
    m_remotePort = 0;
  } catch (std::out_of_range&) {
    m_remotePort = 0;
  }

  auto value = getRawHeader("HTTPS");
  if (!value.empty()) {
    std::string lValue(value);
    boost::to_lower(lValue);
    // IIS sets this value but sets it to off when SSL is off.
    if (lValue.compare("off") != 0) {
      setSSL();
    }
  }

  try {
    m_serverPort = std::stoi(getRawHeader("SERVER_PORT"));
  } catch (std::invalid_argument&) {
    m_serverPort = 0;
  } catch (std::out_of_range&) {
    m_serverPort = 0;
  }

  if (m_extendedMethod == "GET") {
    m_method = Method::GET;
  } else if (m_extendedMethod == "POST") {
    m_method = Method::POST;
  } else if (m_extendedMethod == "HEAD") {
    m_method = Method::HEAD;
  } else {
    m_method = Method::Unknown;
  }

  try {
    m_requestSize = std::stoi(getRawHeader("CONTENT_LENGTH"));
  } catch (std::invalid_argument&) {
    m_requestSize = 0;
  } catch (std::out_of_range&) {
    m_requestSize = 0;
  }

  std::string pathTranslated = getRawHeader("PATH_TRANSLATED");
  std::string documentRoot = getRawHeader("DOCUMENT_ROOT");
  // use PATH_TRANSLATED - DOCUMENT_ROOT if it is valid instead of SCRIPT_NAME
  // for mod_fastcgi support
  if (!pathTranslated.empty() && !documentRoot.empty() &&
      pathTranslated.find(documentRoot) == 0) {
    m_serverObject = pathTranslated.substr(documentRoot.length());
  } else {
    m_serverObject = getRawHeader("SCRIPT_NAME");
  }

  std::string queryString = getRawHeader("QUERY_STRING");
  if (!queryString.empty()) {
    m_serverObject += "?" + queryString;
  }

  m_connection->handleRequest(m_id);
}