📄 httprequestparser.cpp
字号:
+ (*ptr - '0') ); } else { return false; } break; case PARSE_HTTP_VERSION_MINOR_START: // parsing the first digit of the minor version number if (!isDigit(*ptr)) return false; m_http_request->setVersionMinor(*ptr - '0'); m_parse_state = PARSE_HTTP_VERSION_MINOR; break; case PARSE_HTTP_VERSION_MINOR: // parsing the major version number (not first digit) if (*ptr == '\r') { m_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*ptr == '\n') { m_parse_state = PARSE_EXPECTING_CR; } else if (isDigit(*ptr)) { m_http_request->setVersionMinor( (m_http_request->getVersionMinor() * 10) + (*ptr - '0') ); } else { return false; } break; case PARSE_EXPECTING_NEWLINE: // we received a CR; expecting a newline to follow if (*ptr == '\n') { m_parse_state = PARSE_HEADER_START; } else if (*ptr == '\r') { // we received two CR's in a row // assume CR only is (incorrectly) being used for line termination // therefore, the request is finished ++ptr; return true; } else if (*ptr == '\t' || *ptr == ' ') { m_parse_state = PARSE_HEADER_WHITESPACE; } else if (!isChar(*ptr) || isControl(*ptr) || isSpecial(*ptr)) { return false; } else { // assume it is the first character for the name of a header m_header_name.erase(); m_header_name.push_back(*ptr); m_parse_state = PARSE_HEADER_NAME; } break; case PARSE_EXPECTING_CR: // we received a newline without a CR if (*ptr == '\r') { m_parse_state = PARSE_HEADER_START; } else if (*ptr == '\n') { // we received two newlines in a row // assume newline only is (incorrectly) being used for line termination // therefore, the request is finished ++ptr; return true; } else if (*ptr == '\t' || *ptr == ' ') { m_parse_state = PARSE_HEADER_WHITESPACE; } else if (!isChar(*ptr) || isControl(*ptr) || isSpecial(*ptr)) { return false; } else { // assume it is the first character for the name of a header m_header_name.erase(); m_header_name.push_back(*ptr); m_parse_state = PARSE_HEADER_NAME; } break; case PARSE_HEADER_WHITESPACE: // parsing whitespace before a header name if (*ptr == '\r') { m_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*ptr == '\n') { m_parse_state = PARSE_EXPECTING_CR; } else if (*ptr != '\t' && *ptr != ' ') { if (!isChar(*ptr) || isControl(*ptr) || isSpecial(*ptr)) return false; // assume it is the first character for the name of a header m_header_name.erase(); m_header_name.push_back(*ptr); m_parse_state = PARSE_HEADER_NAME; } break; case PARSE_HEADER_START: // parsing the start of a new header if (*ptr == '\r') { m_parse_state = PARSE_EXPECTING_FINAL_NEWLINE; } else if (*ptr == '\n') { m_parse_state = PARSE_EXPECTING_FINAL_CR; } else if (*ptr == '\t' || *ptr == ' ') { m_parse_state = PARSE_HEADER_WHITESPACE; } else if (!isChar(*ptr) || isControl(*ptr) || isSpecial(*ptr)) { return false; } else { // first character for the name of a header m_header_name.erase(); m_header_name.push_back(*ptr); m_parse_state = PARSE_HEADER_NAME; } break; case PARSE_HEADER_NAME: // parsing the name of a header if (*ptr == ':') { m_header_value.erase(); m_parse_state = PARSE_SPACE_BEFORE_HEADER_VALUE; } else if (!isChar(*ptr) || isControl(*ptr) || isSpecial(*ptr)) { return false; } else if (m_header_name.size() >= HEADER_NAME_MAX) { return false; } else { // character (not first) for the name of a header m_header_name.push_back(*ptr); } break; case PARSE_SPACE_BEFORE_HEADER_VALUE: // parsing space character before a header's value if (*ptr == ' ') { m_parse_state = PARSE_HEADER_VALUE; } else if (*ptr == '\r') { m_http_request->addHeader(m_header_name, m_header_value); m_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*ptr == '\n') { m_http_request->addHeader(m_header_name, m_header_value); m_parse_state = PARSE_EXPECTING_CR; } else if (!isChar(*ptr) || isControl(*ptr) || isSpecial(*ptr)) { return false; } else { // assume it is the first character for the value of a header m_header_value.push_back(*ptr); m_parse_state = PARSE_HEADER_VALUE; } break; case PARSE_HEADER_VALUE: // parsing the value of a header if (*ptr == '\r') { m_http_request->addHeader(m_header_name, m_header_value); m_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*ptr == '\n') { m_http_request->addHeader(m_header_name, m_header_value); m_parse_state = PARSE_EXPECTING_CR; } else if (isControl(*ptr)) { return false; } else if (m_header_value.size() >= HEADER_VALUE_MAX) { return false; } else { // character (not first) for the value of a header m_header_value.push_back(*ptr); } break; case PARSE_EXPECTING_FINAL_NEWLINE: if (*ptr == '\n') ++ptr; return true; case PARSE_EXPECTING_FINAL_CR: if (*ptr == '\r') ++ptr; return true; } ++ptr; } return boost::indeterminate;}bool HTTPRequestParser::parseURLEncoded(HTTPTypes::StringDictionary& dict, const char *ptr, const size_t len){ // used to track whether we are parsing the name or value enum QueryParseState { QUERY_PARSE_NAME, QUERY_PARSE_VALUE } parse_state = QUERY_PARSE_NAME; // misc other variables used for parsing const char * const end = ptr + len; std::string query_name; std::string query_value; // iterate through each encoded character while (ptr < end) { switch (parse_state) { case QUERY_PARSE_NAME: // parsing query name if (*ptr == '=') { // end of name found if (query_name.empty()) return false; parse_state = QUERY_PARSE_VALUE; } else if (*ptr == '&') { // value is empty (OK) if (query_name.empty()) return false; dict.insert( std::make_pair(query_name, query_value) ); query_name.erase(); } else if (isControl(*ptr) || query_name.size() >= QUERY_NAME_MAX) { // control character detected, or max sized exceeded return false; } else { // character is part of the name query_name.push_back(*ptr); } break; case QUERY_PARSE_VALUE: // parsing query value if (*ptr == '&') { // end of value found (OK if empty) dict.insert( std::make_pair(query_name, query_value) ); query_name.erase(); query_value.erase(); parse_state = QUERY_PARSE_NAME; } else if (isControl(*ptr) || query_value.size() >= QUERY_VALUE_MAX) { // control character detected, or max sized exceeded return false; } else { // character is part of the value query_value.push_back(*ptr); } break; } ++ptr; } // handle last pair in string if (! query_name.empty()) dict.insert( std::make_pair(query_name, query_value) ); return true;}bool HTTPRequestParser::parseCookieHeader(HTTPTypes::StringDictionary& dict, const std::string& cookie_header){ // BASED ON RFC 2109 // // The current implementation ignores cookie attributes which begin with '$' // (i.e. $Path=/, $Domain=, etc.) // used to track what we are parsing enum CookieParseState { COOKIE_PARSE_NAME, COOKIE_PARSE_VALUE } parse_state = COOKIE_PARSE_NAME; // misc other variables used for parsing std::string cookie_name; std::string cookie_value; char value_quote_character = '\0'; // iterate through each character for (std::string::const_iterator string_iterator = cookie_header.begin(); string_iterator != cookie_header.end(); ++string_iterator) { switch (parse_state) { case COOKIE_PARSE_NAME: // parsing cookie name if (*string_iterator == '=') { // end of name found if (cookie_name.empty()) return false; value_quote_character = '\0'; parse_state = COOKIE_PARSE_VALUE; } else if (*string_iterator == ';' || *string_iterator == ',') { // ignore empty cookie names since this may occur naturally // when quoted values are encountered if (! cookie_name.empty()) { // value is empty (OK) if (cookie_name[0] != '$') dict.insert( std::make_pair(cookie_name, cookie_value) ); cookie_name.erase(); } } else if (*string_iterator != ' ') { // ignore whitespace // check if control character detected, or max sized exceeded if (isControl(*string_iterator) || cookie_name.size() >= COOKIE_NAME_MAX) return false; // character is part of the name // cookie names are case insensitive -> convert to lowercase cookie_name.push_back( tolower(*string_iterator) ); } break; case COOKIE_PARSE_VALUE: // parsing cookie value if (value_quote_character == '\0') { // value is not (yet) quoted if (*string_iterator == ';' || *string_iterator == ',') { // end of value found (OK if empty) if (cookie_name[0] != '$') dict.insert( std::make_pair(cookie_name, cookie_value) ); cookie_name.erase(); cookie_value.erase(); parse_state = COOKIE_PARSE_NAME; } else if (*string_iterator == '\'' || *string_iterator == '"') { if (cookie_value.empty()) { // begin quoted value value_quote_character = *string_iterator; } else if (cookie_value.size() >= COOKIE_VALUE_MAX) { // max size exceeded return false; } else { // assume character is part of the (unquoted) value cookie_value.push_back(*string_iterator); } } else if (*string_iterator != ' ') { // ignore unquoted whitespace // check if control character detected, or max sized exceeded if (isControl(*string_iterator) || cookie_value.size() >= COOKIE_VALUE_MAX) return false; // character is part of the (unquoted) value cookie_value.push_back(*string_iterator); } } else { // value is quoted if (*string_iterator == value_quote_character) { // end of value found (OK if empty) if (cookie_name[0] != '$') dict.insert( std::make_pair(cookie_name, cookie_value) ); cookie_name.erase(); cookie_value.erase(); parse_state = COOKIE_PARSE_NAME; } else if (cookie_value.size() >= COOKIE_VALUE_MAX) { // max size exceeded return false; } else { // character is part of the (quoted) value cookie_value.push_back(*string_iterator); } } break; } } // handle last cookie in string if (! cookie_name.empty() && cookie_name[0] != '$') dict.insert( std::make_pair(cookie_name, cookie_value) ); return true;}} // end namespace pion
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -