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()); }
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 }
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); }
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); }
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); }