Line data Source code
1 : #pragma once 2 : 3 : #include <memory> 4 : 5 : #include "source/extensions/common/async_files/async_file_handle.h" 6 : #include "source/extensions/filters/http/cache/http_cache.h" 7 : #include "source/extensions/http/cache/file_system_http_cache/cache_file_fixed_block.h" 8 : #include "source/extensions/http/cache/file_system_http_cache/cache_file_header.pb.h" 9 : 10 : namespace Envoy { 11 : namespace Extensions { 12 : namespace HttpFilters { 13 : namespace Cache { 14 : namespace FileSystemHttpCache { 15 : 16 : using ::Envoy::Extensions::Common::AsyncFiles::AsyncFileHandle; 17 : using ::Envoy::Extensions::Common::AsyncFiles::CancelFunction; 18 : 19 : class FileLookupContext; 20 : class FileSystemHttpCache; 21 : 22 : class DontInsertContext : public InsertContext { 23 : public: 24 : void insertHeaders(const Http::ResponseHeaderMap&, const ResponseMetadata&, 25 0 : InsertCallback insert_complete, bool) override { 26 0 : insert_complete(false); 27 0 : } 28 0 : void insertBody(const Buffer::Instance&, InsertCallback ready_for_next_chunk, bool) override { 29 0 : ready_for_next_chunk(false); 30 0 : } 31 0 : void insertTrailers(const Http::ResponseTrailerMap&, InsertCallback insert_complete) override { 32 0 : insert_complete(false); 33 0 : } 34 0 : void onDestroy() override{}; 35 : }; 36 : 37 : class FileInsertContext : public InsertContext, public Logger::Loggable<Logger::Id::cache_filter> { 38 : public: 39 : FileInsertContext(std::shared_ptr<FileSystemHttpCache> cache, 40 : std::unique_ptr<FileLookupContext> lookup_context); 41 : void insertHeaders(const Http::ResponseHeaderMap& response_headers, 42 : const ResponseMetadata& metadata, InsertCallback insert_complete, 43 : bool end_stream) override; 44 : void insertBody(const Buffer::Instance& chunk, InsertCallback ready_for_next_chunk, 45 : bool end_stream) override; 46 : void insertTrailers(const Http::ResponseTrailerMap& trailers, 47 : InsertCallback insert_complete) override; 48 : void onDestroy() override; 49 : 50 : private: 51 : std::unique_ptr<FileLookupContext> lookup_context_; 52 : Key key_; 53 : std::shared_ptr<FileSystemHttpCache> cache_; 54 : absl::Mutex mu_; // guards file operations 55 : std::shared_ptr<Cleanup> cleanup_ ABSL_GUARDED_BY(mu_); 56 : AsyncFileHandle file_handle_ ABSL_GUARDED_BY(mu_); 57 : std::function<void(bool)> callback_in_flight_ ABSL_GUARDED_BY(mu_); 58 : CancelFunction cancel_action_in_flight_ ABSL_GUARDED_BY(mu_); 59 : CacheFileFixedBlock header_block_ ABSL_GUARDED_BY(mu_); 60 : 61 : /** 62 : * If seen_end_stream_ is not true (i.e. InsertContext has not yet delivered the 63 : * entire response), cancel insertion. Called by InsertContext onDestroy. 64 : */ 65 : void cancelIfIncomplete(); 66 : 67 : /** 68 : * Cancels any action in flight, calls any uncalled completion callbacks with false, 69 : * and closes the file if open. 70 : * @param err a string to log with the failure. 71 : */ 72 : void cancelInsert(absl::string_view err = "") ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); 73 : 74 : /** 75 : * Starts asynchronously performing the final write operations for the cache file; 76 : * writing the correct FixedCacheHeaderBlock, and giving the file its name. 77 : * On success, removes cleanup_, so the subsequent call to cancelInsert during 78 : * the destructor does not act as an error. 79 : * @param p a shared_ptr to 'this', so it can be captured in lambdas to ensure 80 : * 'this' still exists when the lambda is called. 81 : * @param callback is called with true if the commit completes successfully, 82 : * with false if failed or cancelled. 83 : */ 84 : void commit(InsertCallback callback) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); 85 : }; 86 : 87 : } // namespace FileSystemHttpCache 88 : } // namespace Cache 89 : } // namespace HttpFilters 90 : } // namespace Extensions 91 : } // namespace Envoy