Index: third_party/WebKit/Source/modules/fetch/MultipartParser.h |
diff --git a/third_party/WebKit/Source/modules/fetch/MultipartParser.h b/third_party/WebKit/Source/modules/fetch/MultipartParser.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f24d5f813d91a09fa44554bc496793afac569b30 |
--- /dev/null |
+++ b/third_party/WebKit/Source/modules/fetch/MultipartParser.h |
@@ -0,0 +1,113 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef MultipartParser_h |
+#define MultipartParser_h |
+ |
+#include "modules/ModulesExport.h" |
+#include "platform/heap/Handle.h" |
+#include "platform/network/HTTPHeaderMap.h" |
+#include "platform/wtf/Assertions.h" |
+#include "platform/wtf/Vector.h" |
+ |
+namespace blink { |
+ |
+// This class parses a multipart message which is supplied (possible in chunks) |
+// to MultipartParser::appendData which parses the data and passes resulting |
+// part header fields and data to Client. |
+// |
+// - MultipartParser::appendData does not accept base64, quoted-printable nor |
+// otherwise transfer encoded multipart message parts (no-op transfer |
+// encodings "binary", "7bit" and "8bit" are OK). |
+// - If MultipartParser::cancel() is called, Client's methods will not be |
+// called anymore. |
+class MODULES_EXPORT MultipartParser final |
+ : public GarbageCollectedFinalized<MultipartParser> { |
+ WTF_MAKE_NONCOPYABLE(MultipartParser); |
+ |
+ public: |
+ // Client recieves parsed part header fields and data. |
+ class MODULES_EXPORT Client : public GarbageCollectedMixin { |
+ public: |
+ virtual ~Client() = default; |
+ // The method is called whenever header fields of a part are parsed. |
+ virtual void PartHeaderFieldsInMultipartReceived( |
+ const HTTPHeaderMap& header_fields) = 0; |
+ // The method is called whenever some data of a part is parsed which |
+ // can happen zero or more times per each part. It always holds that |
+ // |size| > 0. |
+ virtual void PartDataInMultipartReceived(const char* bytes, size_t) = 0; |
+ // The method is called whenever all data of a complete part is parsed. |
+ virtual void PartDataInMultipartFullyReceived() = 0; |
+ DEFINE_INLINE_VIRTUAL_TRACE() {} |
+ }; |
+ |
+ MultipartParser(Vector<char> boundary, Client*); |
+ bool AppendData(const char* bytes, size_t); |
+ void Cancel(); |
+ bool Finish(); |
+ |
+ bool IsCancelled() const { return state_ == State::kCancelled; } |
+ |
+ DECLARE_TRACE(); |
+ |
+ private: |
+ class Matcher { |
+ public: |
+ Matcher(); |
+ Matcher(const char* data, size_t num_matched_bytes, size_t); |
+ |
+ bool Match(char value) { |
+ DCHECK_LT(num_matched_bytes_, size_); |
+ if (value != data_[num_matched_bytes_]) |
+ return false; |
+ ++num_matched_bytes_; |
+ return true; |
+ } |
+ bool Match(const char* first, const char* last); |
+ bool IsMatchComplete() const { return num_matched_bytes_ == size_; } |
+ size_t NumMatchedBytes() const { return num_matched_bytes_; } |
+ void SetNumMatchedBytes(size_t); |
+ |
+ const char* Data() const { return data_; } |
+ |
+ private: |
+ const char* data_ = nullptr; |
+ size_t num_matched_bytes_ = 0u; |
+ size_t size_ = 0u; |
+ }; |
+ |
+ Matcher CloseDelimiterSuffixMatcher() const; |
+ Matcher DelimiterMatcher(size_t num_already_matched_bytes = 0u) const; |
+ Matcher DelimiterSuffixMatcher() const; |
+ |
+ void ParseDataAndDelimiter(const char** bytes_pointer, const char* bytes_end); |
+ void ParseDelimiter(const char** bytes_pointer, const char* bytes_end); |
+ bool ParseHeaderFields(const char** bytes_pointer, |
+ const char* bytes_end, |
+ HTTPHeaderMap* header_fields); |
+ void ParseTransportPadding(const char** bytes_pointer, |
+ const char* bytes_end) const; |
+ |
+ Matcher matcher_; |
+ Vector<char> buffered_header_bytes_; |
+ Member<Client> client_; |
+ Vector<char> delimiter_; |
+ |
+ enum class State { |
+ kParsingPreamble, |
+ kParsingDelimiterSuffix, |
+ kParsingPartHeaderFields, |
+ kParsingPartOctets, |
+ kParsingDelimiterOrCloseDelimiterSuffix, |
+ kParsingCloseDelimiterSuffix, |
+ kParsingEpilogue, |
+ kCancelled, |
+ kFinished |
+ } state_; |
+}; |
+ |
+} // namespace blink |
+ |
+#endif // MultipartParser_h |