headers.h 5.1 KB

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