1 /*
2  * Copyright (C) 2004, 2006, 2008, 2011 Apple Inc. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB. If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_H_
21 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_H_
22 
23 // This file is required via encoded_form_data.typemap. To avoid build
24 // circularity issues, it should not transitively include anything that is
25 // generated from a mojom_blink target.
26 //
27 // This requires some gymnastics below, to explicitly forward-declare the
28 // required types without reference to the generator output headers.
29 
30 #include <utility>
31 
32 #include "base/optional.h"
33 #include "base/time/time.h"
34 #include "mojo/public/cpp/bindings/struct_traits.h"
35 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
36 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
37 #include "third_party/blink/renderer/platform/wtf/forward.h"
38 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
39 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
40 #include "third_party/blink/renderer/platform/wtf/vector.h"
41 
42 namespace blink {
43 
44 namespace mojom {
45 class FetchAPIRequestBodyDataView;
46 }  // namespace mojom
47 
48 class BlobDataHandle;
49 class WrappedDataPipeGetter;
50 
51 class PLATFORM_EXPORT FormDataElement final {
52   DISALLOW_NEW();
53 
54  public:
55   FormDataElement();
56   explicit FormDataElement(const Vector<char>&);
57   FormDataElement(
58       const String& filename,
59       int64_t file_start,
60       int64_t file_length,
61       const base::Optional<base::Time>& expected_file_modification_time);
62   FormDataElement(const String& blob_uuid,
63                   scoped_refptr<BlobDataHandle> optional_handle);
64   explicit FormDataElement(scoped_refptr<WrappedDataPipeGetter>);
65 
66   FormDataElement(const FormDataElement&);
67   FormDataElement(FormDataElement&&);
68 
69   ~FormDataElement();
70 
71   FormDataElement& operator=(const FormDataElement&);
72   FormDataElement& operator=(FormDataElement&&);
73 
74   bool IsSafeToSendToAnotherThread() const;
75 
76   enum Type { kData, kEncodedFile, kEncodedBlob, kDataPipe } type_;
77   Vector<char> data_;
78   String filename_;
79   String blob_uuid_;
80   scoped_refptr<BlobDataHandle> optional_blob_data_handle_;
81   int64_t file_start_;
82   int64_t file_length_;
83   base::Optional<base::Time> expected_file_modification_time_;
84   scoped_refptr<WrappedDataPipeGetter> data_pipe_getter_;
85 };
86 
87 PLATFORM_EXPORT bool operator==(const FormDataElement& a,
88                                 const FormDataElement& b);
89 
90 inline bool operator!=(const FormDataElement& a, const FormDataElement& b) {
91   return !(a == b);
92 }
93 
94 class PLATFORM_EXPORT EncodedFormData : public RefCounted<EncodedFormData> {
95   USING_FAST_MALLOC(EncodedFormData);
96 
97  public:
98   enum EncodingType {
99     kFormURLEncoded,    // for application/x-www-form-urlencoded
100     kTextPlain,         // for text/plain
101     kMultipartFormData  // for multipart/form-data
102   };
103 
104   static scoped_refptr<EncodedFormData> Create();
105   static scoped_refptr<EncodedFormData> Create(const void*, wtf_size_t);
106   static scoped_refptr<EncodedFormData> Create(base::span<const char>);
107   static scoped_refptr<EncodedFormData> Create(const Vector<char>&);
108   scoped_refptr<EncodedFormData> Copy() const;
109   scoped_refptr<EncodedFormData> DeepCopy() const;
110   ~EncodedFormData();
111 
112   void AppendData(const void* data, wtf_size_t);
113   void AppendFile(const String& file_path,
114                   const base::Optional<base::Time>& expected_modification_time);
115   void AppendFileRange(
116       const String& filename,
117       int64_t start,
118       int64_t length,
119       const base::Optional<base::Time>& expected_modification_time);
120   void AppendBlob(const String& blob_uuid,
121                   scoped_refptr<BlobDataHandle> optional_handle);
122   void AppendDataPipe(scoped_refptr<WrappedDataPipeGetter> handle);
123 
124   void Flatten(Vector<char>&) const;  // omits files
125   String FlattenToString() const;     // omits files
126 
IsEmpty()127   bool IsEmpty() const { return elements_.IsEmpty(); }
Elements()128   const Vector<FormDataElement>& Elements() const { return elements_; }
MutableElements()129   Vector<FormDataElement>& MutableElements() { return elements_; }
130 
Boundary()131   const Vector<char>& Boundary() const { return boundary_; }
SetBoundary(Vector<char> boundary)132   void SetBoundary(Vector<char> boundary) { boundary_ = boundary; }
133 
134   // Identifies a particular form submission instance.  A value of 0 is used
135   // to indicate an unspecified identifier.
SetIdentifier(int64_t identifier)136   void SetIdentifier(int64_t identifier) { identifier_ = identifier; }
Identifier()137   int64_t Identifier() const { return identifier_; }
138 
ContainsPasswordData()139   bool ContainsPasswordData() const { return contains_password_data_; }
SetContainsPasswordData(bool contains_password_data)140   void SetContainsPasswordData(bool contains_password_data) {
141     contains_password_data_ = contains_password_data;
142   }
143 
ParseEncodingType(const String & type)144   static EncodingType ParseEncodingType(const String& type) {
145     if (EqualIgnoringASCIICase(type, "text/plain"))
146       return kTextPlain;
147     if (EqualIgnoringASCIICase(type, "multipart/form-data"))
148       return kMultipartFormData;
149     return kFormURLEncoded;
150   }
151 
152   // Size of the elements making up the EncodedFormData.
153   uint64_t SizeInBytes() const;
154 
155   bool IsSafeToSendToAnotherThread() const;
156 
157  private:
158   friend struct mojo::StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
159                                    scoped_refptr<blink::EncodedFormData>>;
160   EncodedFormData();
161   EncodedFormData(const EncodedFormData&);
162 
163   Vector<FormDataElement> elements_;
164 
165   int64_t identifier_;
166   Vector<char> boundary_;
167   bool contains_password_data_;
168 };
169 
170 inline bool operator==(const EncodedFormData& a, const EncodedFormData& b) {
171   return a.Elements() == b.Elements();
172 }
173 
174 inline bool operator!=(const EncodedFormData& a, const EncodedFormData& b) {
175   return !(a == b);
176 }
177 
178 }  // namespace blink
179 
180 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_H_
181