bool IHTTPRequestHandler::AddResponseHeader(const std::string &field, const std::string &value, bool allowMultiple /* = false */) { if (field.empty() || value.empty()) return false; if (!allowMultiple && HasResponseHeader(field)) return false; m_response.headers.insert(std::make_pair(field, value)); return true; }
void Http::TCommonProtocol::PushHeader(const std::string& Header) { auto& mResponseUrl = mUrl; if ( Header.empty() ) { mHeadersComplete = true; Soy::Assert( HasResponseHeader() || HasRequestHeader(), "Finished http headers but never got response/request header" ); return; } // check for HTTP response header { std::regex ResponsePattern("^HTTP/[12].[01] ([0-9]+) (.*)$", std::regex::icase ); std::smatch Match; if ( std::regex_match( Header, Match, ResponsePattern ) ) { Soy::Assert( !HasResponseHeader(), "Already matched response header" ); Soy::Assert( !HasRequestHeader(), "Already matched request header" ); int ResponseCode; Soy::StringToType( ResponseCode, Match[1].str() ); mResponseCode = size_cast<size_t>(ResponseCode); mResponseUrl = Match[2].str(); Soy::StringTrimLeft( mResponseUrl, '/' ); return; } } // check for HTTP request header { std::regex RequestPattern("^(GET|POST) /(.*) HTTP/([12]).([01])$", std::regex::icase ); std::smatch Match; if ( std::regex_match( Header, Match, RequestPattern ) ) { Soy::Assert( !HasResponseHeader(), "Already matched response header" ); Soy::Assert( !HasRequestHeader(), "Already matched request header" ); mMethod = Match[1].str(); mUrl = Match[2].str(); Soy::SplitUrlPathVariables( mUrl, mVariables ); std::stringstream VersionString; VersionString << Match[3].str() << '.' << Match[4].str(); mRequestProtocolVersion = Soy::TVersion( VersionString.str() ); return; } } Soy::Assert( HasResponseHeader() || HasRequestHeader(), "Parsing http headers but never got response header" ); // split BufferArray<std::string,2> Parts; Soy::StringSplitByMatches( GetArrayBridge(Parts), Header, ":" ); // odd case while ( Parts.GetSize() < 2 ) Parts.PushBack(); auto& Key = Parts[0]; auto& Value = Parts[1]; Soy::StringTrimLeft(Key,' '); Soy::StringTrimLeft(Value,' '); // parse specific headers if ( ParseSpecificHeader( Key, Value ) ) return; // not expecting this... but dont throw auto Duplicate = mHeaders.find(Key); if ( Duplicate != mHeaders.end() ) { std::Debug << "Duplicate HTTP header [" << Key << "] found. Prev value=[" << Duplicate->second << "] new value=" << Value << "] skipped." << std::endl; return; } mHeaders[Key] = Value; }