aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/http/cookies
diff options
context:
space:
mode:
authorqrort <qrort@yandex-team.com>2022-11-30 23:47:12 +0300
committerqrort <qrort@yandex-team.com>2022-11-30 23:47:12 +0300
commit22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch)
treebffa27765faf54126ad44bcafa89fadecb7a73d7 /library/cpp/http/cookies
parent332b99e2173f0425444abb759eebcb2fafaa9209 (diff)
downloadydb-22f8ae0e3f5d68b92aecccdf96c1d841a0334311.tar.gz
validate canons without yatest_common
Diffstat (limited to 'library/cpp/http/cookies')
-rw-r--r--library/cpp/http/cookies/cookies.cpp33
-rw-r--r--library/cpp/http/cookies/cookies.h17
-rw-r--r--library/cpp/http/cookies/lctable.h86
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);
+ }
+};