diff options
author | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
---|---|---|
committer | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /library/cpp/http/cookies | |
parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) | |
download | ydb-22f8ae0e3f5d68b92aecccdf96c1d841a0334311.tar.gz |
validate canons without yatest_common
Diffstat (limited to 'library/cpp/http/cookies')
-rw-r--r-- | library/cpp/http/cookies/cookies.cpp | 33 | ||||
-rw-r--r-- | library/cpp/http/cookies/cookies.h | 17 | ||||
-rw-r--r-- | library/cpp/http/cookies/lctable.h | 86 |
3 files changed, 136 insertions, 0 deletions
diff --git a/library/cpp/http/cookies/cookies.cpp b/library/cpp/http/cookies/cookies.cpp new file mode 100644 index 00000000000..12b66c7f9df --- /dev/null +++ b/library/cpp/http/cookies/cookies.cpp @@ -0,0 +1,33 @@ +#include "cookies.h" + +#include <library/cpp/string_utils/scan/scan.h> +#include <util/string/strip.h> +#include <util/string/builder.h> + +namespace { + struct TCookiesScanner { + THttpCookies* C; + + inline void operator()(const TStringBuf& key, const TStringBuf& val) { + C->Add(StripString(key), StripString(val)); + } + }; +} + +void THttpCookies::Scan(const TStringBuf& s) { + Clear(); + TCookiesScanner scan = {this}; + ScanKeyValue<true, ';', '='>(s, scan); +} + +/*** https://datatracker.ietf.org/doc/html/rfc6265#section-5.4 ***/ +TString THttpCookies::ToString() const { + TStringBuilder result; + for (const auto& [key, value] : *this) { + if (!result.empty()) { + result << "; "; + } + result << key << "=" << value; + } + return result; +} diff --git a/library/cpp/http/cookies/cookies.h b/library/cpp/http/cookies/cookies.h new file mode 100644 index 00000000000..d7a0030c8ba --- /dev/null +++ b/library/cpp/http/cookies/cookies.h @@ -0,0 +1,17 @@ +#pragma once + +#include "lctable.h" + +class THttpCookies: public TLowerCaseTable<TStringBuf> { +public: + inline THttpCookies(const TStringBuf& cookieString) { + Scan(cookieString); + } + + inline THttpCookies() noexcept { + } + + void Scan(const TStringBuf& cookieString); + + TString ToString() const; +}; diff --git a/library/cpp/http/cookies/lctable.h b/library/cpp/http/cookies/lctable.h new file mode 100644 index 00000000000..09c88eafb80 --- /dev/null +++ b/library/cpp/http/cookies/lctable.h @@ -0,0 +1,86 @@ +#pragma once + +#include <library/cpp/digest/lower_case/lchash.h> + +#include <util/generic/hash_multi_map.h> +#include <util/generic/strbuf.h> +#include <util/generic/algorithm.h> +#include <util/generic/singleton.h> + +struct TStrBufHash { + inline size_t operator()(const TStringBuf& s) const noexcept { + return FnvCaseLess<size_t>(s); + } +}; + +struct TStrBufEqualToCaseLess { + inline bool operator()(const TStringBuf& c1, const TStringBuf& c2) const noexcept { + typedef TLowerCaseIterator<const TStringBuf::TChar> TIter; + + return (c1.size() == c2.size()) && std::equal(TIter(c1.begin()), TIter(c1.end()), TIter(c2.begin())); + } +}; + +template <class T> +class TLowerCaseTable: private THashMultiMap<TStringBuf, T, TStrBufHash, TStrBufEqualToCaseLess> { + typedef THashMultiMap<TStringBuf, T, TStrBufHash, TStrBufEqualToCaseLess> TBase; + +public: + typedef typename TBase::const_iterator const_iterator; + typedef std::pair<const_iterator, const_iterator> TConstIteratorPair; + + using TBase::TBase; + using TBase::begin; + using TBase::end; + + inline TConstIteratorPair EqualRange(const TStringBuf& name) const { + return TBase::equal_range(name); + } + + inline const T& Get(const TStringBuf& name, size_t numOfValue = 0) const { + TConstIteratorPair range = EqualRange(name); + + if (range.first == TBase::end()) + return Default<T>(); + + if (numOfValue == 0) + return range.first->second; + + const_iterator next = range.first; + for (size_t c = 0; c < numOfValue; ++c) { + ++next; + if (next == range.second) + return Default<T>(); + } + + return next->second; + } + + inline bool Has(const TStringBuf& name) const { + return TBase::find(name) != TBase::end(); + } + + size_t NumOfValues(const TStringBuf& name) const { + return TBase::count(name); + } + + inline size_t Size() const noexcept { + return TBase::size(); + } + + inline bool Empty() const noexcept { + return TBase::empty(); + } + + inline void Add(const TStringBuf& key, const T& val) { + TBase::insert(typename TBase::value_type(key, val)); + } + + inline void Clear() noexcept { + TBase::clear(); + } + + inline size_t Erase(const TStringBuf& key) { + return TBase::erase(key); + } +}; |