OLD | NEW |
(Empty) | |
| 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 MultipartParser_h |
| 6 #define MultipartParser_h |
| 7 |
| 8 #include "modules/ModulesExport.h" |
| 9 #include "platform/heap/Handle.h" |
| 10 #include "platform/network/HTTPHeaderMap.h" |
| 11 #include "platform/wtf/Assertions.h" |
| 12 #include "platform/wtf/Vector.h" |
| 13 |
| 14 namespace blink { |
| 15 |
| 16 // This class parses a multipart message which is supplied (possible in chunks) |
| 17 // to MultipartParser::appendData which parses the data and passes resulting |
| 18 // part header fields and data to Client. |
| 19 // |
| 20 // - MultipartParser::appendData does not accept base64, quoted-printable nor |
| 21 // otherwise transfer encoded multipart message parts (no-op transfer |
| 22 // encodings "binary", "7bit" and "8bit" are OK). |
| 23 // - If MultipartParser::cancel() is called, Client's methods will not be |
| 24 // called anymore. |
| 25 class MODULES_EXPORT MultipartParser final |
| 26 : public GarbageCollectedFinalized<MultipartParser> { |
| 27 WTF_MAKE_NONCOPYABLE(MultipartParser); |
| 28 |
| 29 public: |
| 30 // Client recieves parsed part header fields and data. |
| 31 class MODULES_EXPORT Client : public GarbageCollectedMixin { |
| 32 public: |
| 33 virtual ~Client() = default; |
| 34 // The method is called whenever header fields of a part are parsed. |
| 35 virtual void PartHeaderFieldsInMultipartReceived( |
| 36 const HTTPHeaderMap& header_fields) = 0; |
| 37 // The method is called whenever some data of a part is parsed which |
| 38 // can happen zero or more times per each part. It always holds that |
| 39 // |size| > 0. |
| 40 virtual void PartDataInMultipartReceived(const char* bytes, size_t) = 0; |
| 41 // The method is called whenever all data of a complete part is parsed. |
| 42 virtual void PartDataInMultipartFullyReceived() = 0; |
| 43 DEFINE_INLINE_VIRTUAL_TRACE() {} |
| 44 }; |
| 45 |
| 46 MultipartParser(Vector<char> boundary, Client*); |
| 47 bool AppendData(const char* bytes, size_t); |
| 48 void Cancel(); |
| 49 bool Finish(); |
| 50 |
| 51 bool IsCancelled() const { return state_ == State::kCancelled; } |
| 52 |
| 53 DECLARE_TRACE(); |
| 54 |
| 55 private: |
| 56 class Matcher { |
| 57 public: |
| 58 Matcher(); |
| 59 Matcher(const char* data, size_t num_matched_bytes, size_t); |
| 60 |
| 61 bool Match(char value) { |
| 62 DCHECK_LT(num_matched_bytes_, size_); |
| 63 if (value != data_[num_matched_bytes_]) |
| 64 return false; |
| 65 ++num_matched_bytes_; |
| 66 return true; |
| 67 } |
| 68 bool Match(const char* first, const char* last); |
| 69 bool IsMatchComplete() const { return num_matched_bytes_ == size_; } |
| 70 size_t NumMatchedBytes() const { return num_matched_bytes_; } |
| 71 void SetNumMatchedBytes(size_t); |
| 72 |
| 73 const char* Data() const { return data_; } |
| 74 |
| 75 private: |
| 76 const char* data_ = nullptr; |
| 77 size_t num_matched_bytes_ = 0u; |
| 78 size_t size_ = 0u; |
| 79 }; |
| 80 |
| 81 Matcher CloseDelimiterSuffixMatcher() const; |
| 82 Matcher DelimiterMatcher(size_t num_already_matched_bytes = 0u) const; |
| 83 Matcher DelimiterSuffixMatcher() const; |
| 84 |
| 85 void ParseDataAndDelimiter(const char** bytes_pointer, const char* bytes_end); |
| 86 void ParseDelimiter(const char** bytes_pointer, const char* bytes_end); |
| 87 bool ParseHeaderFields(const char** bytes_pointer, |
| 88 const char* bytes_end, |
| 89 HTTPHeaderMap* header_fields); |
| 90 void ParseTransportPadding(const char** bytes_pointer, |
| 91 const char* bytes_end) const; |
| 92 |
| 93 Matcher matcher_; |
| 94 Vector<char> buffered_header_bytes_; |
| 95 Member<Client> client_; |
| 96 Vector<char> delimiter_; |
| 97 |
| 98 enum class State { |
| 99 kParsingPreamble, |
| 100 kParsingDelimiterSuffix, |
| 101 kParsingPartHeaderFields, |
| 102 kParsingPartOctets, |
| 103 kParsingDelimiterOrCloseDelimiterSuffix, |
| 104 kParsingCloseDelimiterSuffix, |
| 105 kParsingEpilogue, |
| 106 kCancelled, |
| 107 kFinished |
| 108 } state_; |
| 109 }; |
| 110 |
| 111 } // namespace blink |
| 112 |
| 113 #endif // MultipartParser_h |
OLD | NEW |