1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_ 6 #define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_ 7 8 // FramePartsCollector is a base class for Http2FrameDecoderListener 9 // implementations that create one FrameParts instance for each decoded frame. 10 11 #include <stddef.h> 12 13 #include <memory> 14 #include <vector> 15 16 #include "quiche/http2/decoder/http2_frame_decoder_listener.h" 17 #include "quiche/http2/http2_structures.h" 18 #include "quiche/http2/test_tools/frame_parts.h" 19 #include "quiche/http2/test_tools/http2_frame_decoder_listener_test_util.h" 20 #include "quiche/common/platform/api/quiche_export.h" 21 22 namespace http2 { 23 namespace test { 24 25 class QUICHE_NO_EXPORT FramePartsCollector 26 : public FailingHttp2FrameDecoderListener { 27 public: 28 FramePartsCollector(); 29 ~FramePartsCollector() override; 30 31 // Toss out the collected data. 32 void Reset(); 33 34 // Returns true if has started recording the info for a frame and has not yet 35 // finished doing so. IsInProgress()36 bool IsInProgress() const { return current_frame_ != nullptr; } 37 38 // Returns the FrameParts instance into which we're currently recording 39 // callback info if IsInProgress, else nullptr. current_frame()40 const FrameParts* current_frame() const { return current_frame_.get(); } 41 42 // Returns the number of completely collected FrameParts instances. size()43 size_t size() const { return collected_frames_.size(); } 44 45 // Returns the n'th frame, where 0 is the oldest of the collected frames, 46 // and n==size() is the frame currently being collected, if there is one. 47 // Returns nullptr if the requested index is not valid. 48 const FrameParts* frame(size_t n) const; 49 50 protected: 51 // In support of OnFrameHeader, set the header that we expect to be used in 52 // the next call. 53 // TODO(jamessynge): Remove ExpectFrameHeader et al. once done with supporting 54 // SpdyFramer's exact states. 55 void ExpectFrameHeader(const Http2FrameHeader& header); 56 57 // For use in implementing On*Start methods of Http2FrameDecoderListener, 58 // returns a FrameParts instance, which will be newly created if 59 // IsInProgress==false (which the caller should ensure), else will be the 60 // current_frame(); never returns nullptr. 61 // If called when IsInProgress==true, a test failure will be recorded. 62 Http2FrameDecoderListener* StartFrame(const Http2FrameHeader& header); 63 64 // For use in implementing On* callbacks, such as OnPingAck, that are the only 65 // call expected for the frame being decoded; not for On*Start methods. 66 // Returns a FrameParts instance, which will be newly created if 67 // IsInProgress==false (which the caller should ensure), else will be the 68 // current_frame(); never returns nullptr. 69 // If called when IsInProgress==true, a test failure will be recorded. 70 Http2FrameDecoderListener* StartAndEndFrame(const Http2FrameHeader& header); 71 72 // If IsInProgress==true, returns the FrameParts into which the current 73 // frame is being recorded; else records a test failure and returns 74 // failing_listener_, which will record a test failure when any of its 75 // On* methods is called. 76 Http2FrameDecoderListener* CurrentFrame(); 77 78 // For use in implementing On*End methods, pushes the current frame onto 79 // the vector of completed frames, and returns a pointer to it for recording 80 // the info in the final call. If IsInProgress==false, records a test failure 81 // and returns failing_listener_, which will record a test failure when any 82 // of its On* methods is called. 83 Http2FrameDecoderListener* EndFrame(); 84 85 // For use in implementing OnPaddingTooLong and OnFrameSizeError, is 86 // equivalent to EndFrame() if IsInProgress==true, else equivalent to 87 // StartAndEndFrame(). 88 Http2FrameDecoderListener* FrameError(const Http2FrameHeader& header); 89 90 private: 91 // Returns the mutable FrameParts instance into which we're currently 92 // recording callback info if IsInProgress, else nullptr. current_frame()93 FrameParts* current_frame() { return current_frame_.get(); } 94 95 // If expected header is set, verify that it matches the header param. 96 // TODO(jamessynge): Remove TestExpectedHeader et al. once done 97 // with supporting SpdyFramer's exact states. 98 void TestExpectedHeader(const Http2FrameHeader& header); 99 100 std::unique_ptr<FrameParts> current_frame_; 101 std::vector<std::unique_ptr<FrameParts>> collected_frames_; 102 FailingHttp2FrameDecoderListener failing_listener_; 103 104 // TODO(jamessynge): Remove expected_header_ et al. once done with supporting 105 // SpdyFramer's exact states. 106 Http2FrameHeader expected_header_; 107 bool expected_header_set_ = false; 108 }; 109 110 } // namespace test 111 } // namespace http2 112 113 #endif // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_ 114