src/transaction.cc
/**
 * @name    processURI
 * @brief   Perform the analysis on the URI and all the query string variables.
 *
 * This method should be called at very beginning of a request process, it is
 * expected to be executed prior to the virtual host resolution, when the
 * connection arrives on the server.
 *
 * @note There is no direct connection between this function and any phase of
 *       the SecLanguage's phases. It is something that may occur between the
 *       SecLanguage phase 1 and 2.
 * @note Remember to check for a possible intervention.
 *
 * @param transaction ModSecurity transaction.
 * @param uri   Uri.
 * @param method   Method (GET, POST, PUT).
 * @param http_version   Http version (1.0, 1.1, 2.0).
 *
 * @returns If the operation was successful or not.
 * @retval true Operation was successful.
 * @retval false Operation failed.
 *
 */
@name    processURI
@brief   Perform the analysis on the URI and all the query string variables.

This method should be called at very beginning of a request process, it is
expected to be executed prior to the virtual host resolution, when the
connection arrives on the server.

@note There is no direct connection between this function and any phase of
the SecLanguage's phases. It is something that may occur between the
SecLanguage phase 1 and 2.
@note Remember to check for a possible intervention.

@param transaction ModSecurity transaction.
@param uri   Uri.
@param method   Method (GET, POST, PUT).

@returns If the operation was successful or not.
@retval true Operation was successful.
@retval false Operation failed.
@name processURI @brief Perform the analysis on the URI and all the query string variables . This method should be called at very beginning of a request process it is expected to be executed prior to the virtual host resolution when the connection arrives on the server . @note There is no direct connection between this function and any phase of the SecLanguage ' s phases . It is something that may occur between the SecLanguage phase 1 and 2 . @note Remember to check for a possible intervention . @param transaction ModSecurity transaction . @param uri Uri . @param method Method ( GET POST PUT ) . @returns If the operation was successful or not . @retval true Operation was successful . @retval false Operation failed .
int Transaction::processURI(const char *uri, const char *method,
    const char *http_version) {
#ifndef NO_LOGS
    debug(4, "Starting phase URI. (SecRules 0 + 1/2)");
#endif
    m_method = method;
    m_httpVersion = http_version;
    m_uri = uri;
    std::string uri_s(uri);
    m_uri_decoded = utils::uri_decode(uri);
    size_t pos = m_uri_decoded.find("?");
    size_t pos_raw = uri_s.find("?");
    m_collections.store("REQUEST_LINE", std::string(method) + " " +
        std::string(uri) + " HTTP/" + std::string(http_version));
    if (pos != std::string::npos) {
        m_uri_no_query_string_decoded = std::string(m_uri_decoded, 0, pos);
    } else {
        m_uri_no_query_string_decoded = std::string(m_uri_decoded);
    }
    if (pos_raw != std::string::npos) {
        m_collections.store("QUERY_STRING", std::string(uri_s, pos_raw + 1,
            uri_s.length() - (pos_raw + 1)));
    }
    std::string path_info;
    if (pos == std::string::npos) {
        path_info = std::string(m_uri_decoded, 0);
    } else {
        path_info = std::string(m_uri_decoded, 0, pos);
    }
    m_collections.store("PATH_INFO", path_info);
    m_collections.store("REQUEST_FILENAME", path_info);
    size_t offset = path_info.find_last_of("/\\");
    if (offset != std::string::npos && path_info.length() > offset + 1) {
        std::string basename = std::string(path_info, offset + 1,
            path_info.length() - (offset + 1));
        m_collections.store("REQUEST_BASENAME", basename);
    }
    m_collections.store("REQUEST_METHOD", method);
    m_collections.store("REQUEST_PROTOCOL",
        "HTTP/" + std::string(http_version));
    std::string parsedURI = m_uri_decoded;
    if (!m_uri_decoded.empty() && m_uri_decoded.at(0) != '/') {
        bool fullDomain = true;
        size_t scheme = m_uri_decoded.find(":")+1;
        if (scheme == std::string::npos) {
            fullDomain = false;
        }
        if (scheme != std::string::npos && fullDomain == true) {
            size_t netloc = m_uri_decoded.find("//", scheme) + 2;
            if (netloc == std::string::npos || (netloc != scheme + 2)) {
                fullDomain = false;
            }
            if (netloc != std::string::npos && fullDomain == true) {
                size_t path = m_uri_decoded.find("/", netloc);
                if (path != std::string::npos && fullDomain == true) {
                    parsedURI = m_uri_decoded.substr(path);
                }
            }
        }
    }
    m_collections.store("REQUEST_URI", parsedURI);
    m_collections.store("REQUEST_URI_RAW", uri);
    if (pos != std::string::npos && (m_uri_decoded.length() - pos) > 2) {
        extractArguments("GET", std::string(uri_s, pos_raw + 1,
            uri_s.length() - (pos_raw + 1)));
    }
    return true;
}
int Transaction :: processURI ( const char * uri , const char * method , const char * http_version ) { #ifndef NO_LOGS debug ( 4 , " " ) ; #endif m_method = method ; m_httpVersion = http_version ; m_uri = uri ; std :: string uri_s ( uri ) ; m_uri_decoded = utils :: uri_decode ( uri ) ; size_t pos = m_uri_decoded . find ( " " ) ; size_t pos_raw = uri_s . find ( " " ) ; m_collections . store ( " " , std :: string ( method ) + " " + std :: string ( uri ) + " " + std :: string ( http_version ) ) ; if ( pos != std :: string :: npos ) { m_uri_no_query_string_decoded = std :: string ( m_uri_decoded , 0 , pos ) ; } else { m_uri_no_query_string_decoded = std :: string ( m_uri_decoded ) ; } if ( pos_raw != std :: string :: npos ) { m_collections . store ( " " , std :: string ( uri_s , pos_raw + 1 , uri_s . length ( ) - ( pos_raw + 1 ) ) ) ; } std :: string path_info ; if ( pos == std :: string :: npos ) { path_info = std :: string ( m_uri_decoded , 0 ) ; } else { path_info = std :: string ( m_uri_decoded , 0 , pos ) ; } m_collections . store ( " " , path_info ) ; m_collections . store ( " " , path_info ) ; size_t offset = path_info . find_last_of ( " \\ " ) ; if ( offset != std :: string :: npos && path_info . length ( ) > offset + 1 ) { std :: string basename = std :: string ( path_info , offset + 1 , path_info . length ( ) - ( offset + 1 ) ) ; m_collections . store ( " " , basename ) ; } m_collections . store ( " " , method ) ; m_collections . store ( " " , " " + std :: string ( http_version ) ) ; std :: string parsedURI = m_uri_decoded ; if ( ! m_uri_decoded . empty ( ) && m_uri_decoded . at ( 0 ) != ' ' ) { bool fullDomain = true ; size_t scheme = m_uri_decoded . find ( " " ) + 1 ; if ( scheme == std :: string :: npos ) { fullDomain = false ; } if ( scheme != std :: string :: npos && fullDomain == true ) { size_t netloc = m_uri_decoded . find ( " " , scheme ) + 2 ; if ( netloc == std :: string :: npos || ( netloc != scheme + 2 ) ) { fullDomain = false ; } if ( netloc != std :: string :: npos && fullDomain == true ) { size_t path = m_uri_decoded . find ( " " , netloc ) ; if ( path != std :: string :: npos && fullDomain == true ) { parsedURI = m_uri_decoded . substr ( path ) ; } } } } m_collections . store ( " " , parsedURI ) ; m_collections . store ( " " , uri ) ; if ( pos != std :: string :: npos && ( m_uri_decoded . length ( ) - pos ) > 2 ) { extractArguments ( " " , std :: string ( uri_s , pos_raw + 1 , uri_s . length ( ) - ( pos_raw + 1 ) ) ) ; } return true ; }
@name    processURI
 @brief   Perform the analysis on the URI and all the query string variables.
@name processURI @brief Perform the analysis on the URI and all the query string variables .
// The more popular case is without domain // Searching with a pos of -1 is undefined we also shortcut // Assuming we found a colon make sure its followed