diff --git a/src/brpc/http_header.cpp b/src/brpc/http_header.cpp index ec9e88e998..5dbbd7ab44 100644 --- a/src/brpc/http_header.cpp +++ b/src/brpc/http_header.cpp @@ -29,6 +29,14 @@ HttpHeader::HttpHeader() // NOTE: don't forget to clear the field in Clear() as well. } +void HttpHeader::RemoveHeader(const char* key) { + if (IsContentType(key)) { + _content_type.clear(); + } else { + _headers.erase(key); + } +} + void HttpHeader::AppendHeader(const std::string& key, const butil::StringPiece& value) { std::string& slot = GetOrAddHeader(key); @@ -69,6 +77,17 @@ void HttpHeader::set_status_code(int status_code) { _status_code = status_code; } +std::string& HttpHeader::GetOrAddHeader(const std::string& key) { + if (IsContentType(key)) { + return _content_type; + } + + if (!_headers.initialized()) { + _headers.init(29); + } + return _headers[key]; +} + const HttpHeader& DefaultHttpHeader() { static HttpHeader h; return h; diff --git a/src/brpc/http_header.h b/src/brpc/http_header.h index 6de0b64732..c5af6448f9 100644 --- a/src/brpc/http_header.h +++ b/src/brpc/http_header.h @@ -41,6 +41,7 @@ class HttpHeader { public: typedef butil::CaseIgnoredFlatMap HeaderMap; typedef HeaderMap::const_iterator HeaderIterator; + typedef HeaderMap::key_equal HeaderKeyEqual; HttpHeader(); @@ -64,9 +65,9 @@ class HttpHeader { // True if the message is from HTTP2. bool is_http2() const { return major_version() == 2; } - // Get/set "Content-Type". Notice that you can't get "Content-Type" - // via GetHeader(). + // Get/set "Content-Type". // possible values: "text/plain", "application/json" ... + // NOTE: Equal to `GetHeader("Content-Type")', ·SetHeader("Content-Type")‘ (case-insensitive). const std::string& content_type() const { return _content_type; } void set_content_type(const std::string& type) { _content_type = type; } void set_content_type(const char* type) { _content_type = type; } @@ -77,20 +78,22 @@ class HttpHeader { // Namely, GetHeader("log-id"), GetHeader("Log-Id"), GetHeader("LOG-ID") // point to the same value. // Return pointer to the value, NULL on not found. - // NOTE: Not work for "Content-Type", call content_type() instead. + // NOTE: If the key is "Content-Type", `GetHeader("Content-Type")' + // (case-insensitive) is equal to `content_type()'. const std::string* GetHeader(const char* key) const { return _headers.seek(key); } const std::string* GetHeader(const std::string& key) const { return _headers.seek(key); } // Set value of a header. - // NOTE: Not work for "Content-Type", call set_content_type() instead. + // NOTE: If the key is "Content-Type", `SetHeader("Content-Type", ...)' + // (case-insensitive) is equal to `set_content_type(...)'. void SetHeader(const std::string& key, const std::string& value) { GetOrAddHeader(key) = value; } // Remove a header. - void RemoveHeader(const char* key) { _headers.erase(key); } - void RemoveHeader(const std::string& key) { _headers.erase(key); } + void RemoveHeader(const char* key); + void RemoveHeader(const std::string& key) { RemoveHeader(key.c_str()); } // Append value to a header. If the header already exists, separate // old value and new value with comma(,) according to: @@ -142,11 +145,10 @@ friend class HttpMessageSerializer; friend class policy::H2StreamContext; friend void policy::ProcessHttpRequest(InputMessageBase *msg); - std::string& GetOrAddHeader(const std::string& key) { - if (!_headers.initialized()) { - _headers.init(29); - } - return _headers[key]; + std::string& GetOrAddHeader(const std::string& key); + + static bool IsContentType(const std::string& key) { + return HeaderKeyEqual()(key, "content-type"); } HeaderMap _headers;