headers.h 5.0 KB

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