Skip to content

Commit

Permalink
Support MultiFlatMap
Browse files Browse the repository at this point in the history
  • Loading branch information
chenBright committed Apr 14, 2024
1 parent 30ed3aa commit 7abda2b
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 175 deletions.
2 changes: 1 addition & 1 deletion src/brpc/details/http_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int HttpMessage::on_header_value(http_parser *parser,
&header.GetOrAddHeader(http_message->_cur_header);
} else {
http_message->_cur_value =
&header.GetNewHeader(http_message->_cur_header);
&header.AddHeader(http_message->_cur_header);
}
if (http_message->_cur_value && !http_message->_cur_value->empty()) {
http_message->_cur_value->append(
Expand Down
52 changes: 25 additions & 27 deletions src/brpc/http_header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ HttpHeader::HttpHeader()
: _status_code(HTTP_STATUS_OK)
, _method(HTTP_METHOD_GET)
, _version(1, 1)
, _first_set_cookie_iter(_headers.end()) {
, _first_set_cookie(NULL) {
CHECK_EQ(0, _headers.init(29));
// NOTE: don't forget to clear the field in Clear() as well.
}

Expand All @@ -55,21 +56,18 @@ void HttpHeader::Clear() {
}

const std::string* HttpHeader::GetHeader(const char* key) const {
HeaderIterator iter;
if (IsSetCookie(key)) {
iter = _first_set_cookie_iter;
} else {
iter = _headers.find(key);
}
return iter != _headers.end() ? &iter->second : NULL;
return GetHeader(std::string(key));
}

const std::string* HttpHeader::GetHeader(const std::string& key) const {
return GetHeader(key.c_str());
if (IsSetCookie(key)) {
return _first_set_cookie;
}
std::string* val = _headers.seek(key);
return val;
}

std::vector<const std::string*>
HttpHeader::GetAllSetCookieHeader() const {
std::vector<const std::string*> HttpHeader::GetAllSetCookieHeader() const {
return GetMultiLineHeaders(SET_COOKIE);
}

Expand All @@ -95,7 +93,7 @@ void HttpHeader::RemoveHeader(const char* key) {
} else {
_headers.erase(key);
if (IsSetCookie(key)) {
_first_set_cookie_iter = _headers.end();
_first_set_cookie = NULL;
}
}
}
Expand All @@ -104,7 +102,7 @@ void HttpHeader::AppendHeader(const std::string& key,
const butil::StringPiece& value) {
if (!CanFoldedInLine(key)) {
// Add a new Set-Cookie header field.
std::string& slot = GetNewHeader(key);
std::string& slot = AddHeader(key);
slot.assign(value.data(), value.size());
} else {
std::string& slot = GetOrAddHeader(key);
Expand Down Expand Up @@ -133,26 +131,26 @@ std::string& HttpHeader::GetOrAddHeader(const std::string& key) {

bool is_set_cookie = IsSetCookie(key);
// Only returns the first Set-Cookie header field for compatibility.
if (is_set_cookie && _first_set_cookie_iter != _headers.end()) {
return _first_set_cookie_iter->second;
if (is_set_cookie && NULL != _first_set_cookie) {
return *_first_set_cookie;
}

auto iter = _headers.find(key);
if (iter == _headers.end()) {
iter = _headers.insert({ key, "" });
}
if (is_set_cookie) {
_first_set_cookie_iter = iter;
std::string* val = _headers.seek(key);
if (NULL == val) {
val = _headers.insert({ key, "" });
if (is_set_cookie) {
_first_set_cookie = val;
}
}
return iter->second;
return *val;
}

std::string& HttpHeader::GetNewHeader(const std::string& key) {
auto iter = _headers.insert({ key, "" });
if (IsSetCookie(key) && _first_set_cookie_iter == _headers.end()) {
_first_set_cookie_iter = iter;
std::string& HttpHeader::AddHeader(const std::string& key) {
std::string* val = _headers.insert({ key, "" });
if (IsSetCookie(key) && NULL == _first_set_cookie) {
_first_set_cookie = val;
}
return iter->second;
return *val;
}

const HttpHeader& DefaultHttpHeader() {
Expand Down
9 changes: 3 additions & 6 deletions src/brpc/http_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ class H2StreamContext;
// Non-body part of a HTTP message.
class HttpHeader {
public:
typedef std::unordered_multimap<
std::string, std::string,
butil::CaseIgnoredHasher,
butil::CaseIgnoredEqual> HeaderMap;
typedef butil::CaseIgnoredMultiFlatMap<std::string> HeaderMap;
typedef HeaderMap::const_iterator HeaderIterator;
typedef HeaderMap::key_equal HeaderKeyEqual;

Expand Down Expand Up @@ -173,7 +170,7 @@ friend void policy::ProcessHttpRequest(InputMessageBase *msg);

std::string& GetOrAddHeader(const std::string& key);

std::string& GetNewHeader(const std::string& key);
std::string& AddHeader(const std::string& key);

bool IsSetCookie(const std::string& key) const {
return _header_key_equal(key, SET_COOKIE);
Expand Down Expand Up @@ -206,7 +203,7 @@ friend void policy::ProcessHttpRequest(InputMessageBase *msg);
std::string _content_type;
std::string _unresolved_path;
std::pair<int, int> _version;
HeaderMap::iterator _first_set_cookie_iter;
std::string* _first_set_cookie;
};

const HttpHeader& DefaultHttpHeader();
Expand Down
4 changes: 4 additions & 0 deletions src/butil/containers/case_ignored_flat_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ class CaseIgnoredFlatMap : public butil::FlatMap<
class CaseIgnoredFlatSet : public butil::FlatSet<
std::string, CaseIgnoredHasher, CaseIgnoredEqual> {};

template <typename T>
class CaseIgnoredMultiFlatMap : public butil::FlatMap<
std::string, T, CaseIgnoredHasher, CaseIgnoredEqual, false, PtAllocator, true> {};

} // namespace butil

#endif // BUTIL_CASE_IGNORED_FLAT_MAP_H
Loading

0 comments on commit 7abda2b

Please sign in to comment.