1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#pragma once
#include <util/generic/string.h>
#include <util/generic/strbuf.h>
#include <util/generic/deque.h>
#include <util/generic/vector.h>
#include <util/string/cast.h>
class IInputStream;
class IOutputStream;
/// @addtogroup Streams_HTTP
/// @{
/// Объект, содержащий информацию о HTTP-заголовке.
class THttpInputHeader {
public:
/// @param[in] header - строка вида 'параметр: значение'.
THttpInputHeader(TStringBuf header);
/// @param[in] name - имя параметра.
/// @param[in] value - значение параметра.
THttpInputHeader(TString name, TString value);
/// Возвращает имя параметра.
inline const TString& Name() const noexcept {
return Name_;
}
/// Возвращает значение параметра.
inline const TString& Value() const noexcept {
return Value_;
}
/// Записывает заголовок вида "имя параметра: значение\r\n" в поток.
void OutTo(IOutputStream* stream) const;
/// Возвращает строку "имя параметра: значение".
inline TString ToString() const {
return Name_ + TStringBuf(": ") + Value_;
}
private:
TString Name_;
TString Value_;
};
/// Контейнер для хранения HTTP-заголовков
class THttpHeaders {
using THeaders = TDeque<THttpInputHeader>;
public:
using TConstIterator = THeaders::const_iterator;
THttpHeaders() = default;
/// Добавляет каждую строку из потока в контейнер, считая ее правильным заголовком.
THttpHeaders(IInputStream* stream);
/// Стандартный итератор.
inline TConstIterator Begin() const noexcept {
return Headers_.begin();
}
inline TConstIterator begin() const noexcept {
return Headers_.begin();
}
/// Стандартный итератор.
inline TConstIterator End() const noexcept {
return Headers_.end();
}
inline TConstIterator end() const noexcept {
return Headers_.end();
}
/// Возвращает количество заголовков в контейнере.
inline size_t Count() const noexcept {
return Headers_.size();
}
/// Проверяет, содержит ли контейнер хотя бы один заголовок.
inline bool Empty() const noexcept {
return Headers_.empty();
}
/// Добавляет заголовок в контейнер.
void AddHeader(THttpInputHeader header);
template <typename ValueType>
void AddHeader(TString name, const ValueType& value) {
AddHeader(THttpInputHeader(std::move(name), ToString(value)));
}
/// Добавляет заголовок в контейнер, если тот не содержит заголовка
/// c таким же параметром. В противном случае, заменяет существующий
/// заголовок на новый.
void AddOrReplaceHeader(const THttpInputHeader& header);
template <typename ValueType>
void AddOrReplaceHeader(TString name, const ValueType& value) {
AddOrReplaceHeader(THttpInputHeader(std::move(name), ToString(value)));
}
// Проверяет, есть ли такой заголовок
bool HasHeader(TStringBuf header) const;
/// Удаляет заголовок, если он есть.
void RemoveHeader(TStringBuf header);
/// Ищет заголовок по указанному имени
/// Возвращает nullptr, если не нашел
const THttpInputHeader* FindHeader(TStringBuf header) const;
/// Записывает все заголовки контейнера в поток.
/// @details Каждый заголовк записывается в виде "имя параметра: значение\r\n".
void OutTo(IOutputStream* stream) const;
/// Обменивает наборы заголовков двух контейнеров.
void Swap(THttpHeaders& headers) noexcept {
Headers_.swap(headers.Headers_);
}
private:
THeaders Headers_;
};
/// @}
|