abortable_http_response.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #pragma once
  2. #include "http.h"
  3. #include <util/generic/intrlist.h>
  4. namespace NYT {
  5. ////////////////////////////////////////////////////////////////////////////////
  6. class TAbortableHttpResponseRegistry;
  7. using TOutageId = size_t;
  8. ////////////////////////////////////////////////////////////////////////////////
  9. class TAbortedForTestPurpose
  10. : public yexception
  11. { };
  12. struct TOutageOptions
  13. {
  14. using TSelf = TOutageOptions;
  15. /// @brief Number of responses to abort.
  16. FLUENT_FIELD_DEFAULT(size_t, ResponseCount, std::numeric_limits<size_t>::max());
  17. /// @brief Number of bytes to read before abortion. If zero, abort immediately.
  18. FLUENT_FIELD_DEFAULT(size_t, LengthLimit, 0);
  19. };
  20. ////////////////////////////////////////////////////////////////////////////////
  21. class IAbortableHttpResponse
  22. : public TIntrusiveListItem<IAbortableHttpResponse>
  23. {
  24. public:
  25. virtual void Abort() = 0;
  26. virtual const TString& GetUrl() const = 0;
  27. virtual bool IsAborted() const = 0;
  28. virtual void SetLengthLimit(size_t limit) = 0;
  29. virtual ~IAbortableHttpResponse() = default;
  30. };
  31. class TAbortableHttpResponseBase
  32. : public IAbortableHttpResponse
  33. {
  34. public:
  35. TAbortableHttpResponseBase(const TString& url);
  36. ~TAbortableHttpResponseBase();
  37. void Abort() override;
  38. const TString& GetUrl() const override;
  39. bool IsAborted() const override;
  40. void SetLengthLimit(size_t limit) override;
  41. protected:
  42. TString Url_;
  43. std::atomic<bool> Aborted_ = {false};
  44. size_t LengthLimit_ = std::numeric_limits<size_t>::max();
  45. };
  46. ////////////////////////////////////////////////////////////////////////////////
  47. /// @brief Stream wrapper for @ref NYT::NHttpClient::TCoreHttpResponse with possibility to emulate errors.
  48. class TAbortableCoreHttpResponse
  49. : public IInputStream
  50. , public TAbortableHttpResponseBase
  51. {
  52. public:
  53. TAbortableCoreHttpResponse(
  54. std::unique_ptr<IInputStream> stream,
  55. const TString& url);
  56. private:
  57. size_t DoRead(void* buf, size_t len) override;
  58. size_t DoSkip(size_t len) override;
  59. private:
  60. std::unique_ptr<IInputStream> Stream_;
  61. };
  62. ////////////////////////////////////////////////////////////////////////////////
  63. /// @brief Class extends @ref NYT::THttpResponse with possibility to emulate errors.
  64. class TAbortableHttpResponse
  65. : public THttpResponse
  66. , public TAbortableHttpResponseBase
  67. {
  68. public:
  69. class TOutage
  70. {
  71. public:
  72. TOutage(TString urlPattern, TAbortableHttpResponseRegistry& registry, const TOutageOptions& options);
  73. TOutage(TOutage&&) = default;
  74. TOutage(const TOutage&) = delete;
  75. ~TOutage();
  76. void Stop();
  77. private:
  78. TString UrlPattern_;
  79. TAbortableHttpResponseRegistry& Registry_;
  80. TOutageId Id_;
  81. bool Stopped_ = false;
  82. };
  83. public:
  84. TAbortableHttpResponse(
  85. IInputStream* socketStream,
  86. const TString& requestId,
  87. const TString& hostName,
  88. const TString& url);
  89. /// @brief Abort any responses which match `urlPattern` (i.e. contain it in url).
  90. ///
  91. /// @return number of aborted responses.
  92. static int AbortAll(const TString& urlPattern);
  93. /// @brief Start outage. Future responses which match `urlPattern` (i.e. contain it in url) will fail.
  94. ///
  95. /// @return outage object controlling the lifetime of outage (outage stops when object is destroyed)
  96. [[nodiscard]] static TOutage StartOutage(
  97. const TString& urlPattern,
  98. const TOutageOptions& options = TOutageOptions());
  99. /// @brief Start outage. Future `responseCount` responses which match `urlPattern` (i.e. contain it in url) will fail.
  100. ///
  101. /// @return outage object controlling the lifetime of outage (outage stops when object is destroyed)
  102. [[nodiscard]] static TOutage StartOutage(
  103. const TString& urlPattern,
  104. size_t responseCount);
  105. private:
  106. size_t DoRead(void* buf, size_t len) override;
  107. size_t DoSkip(size_t len) override;
  108. };
  109. ////////////////////////////////////////////////////////////////////////////////
  110. } // namespace NYT