/src/mozilla-central/dom/html/HTMLFormSubmission.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef mozilla_dom_HTMLFormSubmission_h |
8 | | #define mozilla_dom_HTMLFormSubmission_h |
9 | | |
10 | | #include "mozilla/Attributes.h" |
11 | | #include "mozilla/dom/Element.h" |
12 | | #include "nsCOMPtr.h" |
13 | | #include "mozilla/Encoding.h" |
14 | | #include "nsString.h" |
15 | | |
16 | | class nsIURI; |
17 | | class nsIInputStream; |
18 | | class nsGenericHTMLElement; |
19 | | class nsIMultiplexInputStream; |
20 | | |
21 | | namespace mozilla { |
22 | | namespace dom { |
23 | | |
24 | | class Blob; |
25 | | class Directory; |
26 | | class HTMLFormElement; |
27 | | |
28 | | /** |
29 | | * Class for form submissions; encompasses the function to call to submit as |
30 | | * well as the form submission name/value pairs |
31 | | */ |
32 | | class HTMLFormSubmission |
33 | | { |
34 | | public: |
35 | | /** |
36 | | * Get a submission object based on attributes in the form (ENCTYPE and |
37 | | * METHOD) |
38 | | * |
39 | | * @param aForm the form to get a submission object based on |
40 | | * @param aOriginatingElement the originating element (can be null) |
41 | | * @param aFormSubmission the form submission object (out param) |
42 | | */ |
43 | | static nsresult |
44 | | GetFromForm(HTMLFormElement* aForm, |
45 | | nsGenericHTMLElement* aOriginatingElement, |
46 | | HTMLFormSubmission** aFormSubmission); |
47 | | |
48 | | virtual ~HTMLFormSubmission() |
49 | | { |
50 | | MOZ_COUNT_DTOR(HTMLFormSubmission); |
51 | | } |
52 | | |
53 | | /** |
54 | | * Submit a name/value pair |
55 | | * |
56 | | * @param aName the name of the parameter |
57 | | * @param aValue the value of the parameter |
58 | | */ |
59 | | virtual nsresult |
60 | | AddNameValuePair(const nsAString& aName, const nsAString& aValue) = 0; |
61 | | |
62 | | /** |
63 | | * Submit a name/blob pair |
64 | | * |
65 | | * @param aName the name of the parameter |
66 | | * @param aBlob the blob to submit. The file's name will be used if the Blob |
67 | | * is actually a File, otherwise 'blob' string is used instead if the aBlob is |
68 | | * not null. |
69 | | */ |
70 | | virtual nsresult |
71 | | AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob) = 0; |
72 | | |
73 | | /** |
74 | | * Submit a name/directory pair |
75 | | * |
76 | | * @param aName the name of the parameter |
77 | | * @param aBlob the directory to submit. |
78 | | */ |
79 | | virtual nsresult AddNameDirectoryPair(const nsAString& aName, |
80 | | Directory* aDirectory) = 0; |
81 | | |
82 | | /** |
83 | | * Given a URI and the current submission, create the final URI and data |
84 | | * stream that will be submitted. Subclasses *must* implement this. |
85 | | * |
86 | | * @param aURI the URI being submitted to [IN] |
87 | | * @param aPostDataStream a data stream for POST data [OUT] |
88 | | * @param aOutURI the resulting URI. May be the same as aURI [OUT] |
89 | | */ |
90 | | virtual nsresult |
91 | | GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream, |
92 | | nsCOMPtr<nsIURI>& aOutURI) = 0; |
93 | | |
94 | | /** |
95 | | * Get the charset that will be used for submission. |
96 | | */ |
97 | 0 | void GetCharset(nsACString& aCharset) { mEncoding->Name(aCharset); } |
98 | | |
99 | | Element* GetOriginatingElement() const |
100 | | { |
101 | | return mOriginatingElement.get(); |
102 | | } |
103 | | |
104 | | /** |
105 | | * Get the action URI that will be used for submission. |
106 | | */ |
107 | | nsIURI* GetActionURL() const |
108 | 0 | { |
109 | 0 | return mActionURL; |
110 | 0 | } |
111 | | |
112 | | /** |
113 | | * Get the target that will be used for submission. |
114 | | */ |
115 | | void GetTarget(nsAString& aTarget) |
116 | 0 | { |
117 | 0 | aTarget = mTarget; |
118 | 0 | } |
119 | | |
120 | | protected: |
121 | | /** |
122 | | * Can only be constructed by subclasses. |
123 | | * |
124 | | * @param aEncoding the character encoding of the form |
125 | | * @param aOriginatingElement the originating element (can be null) |
126 | | */ |
127 | | HTMLFormSubmission(nsIURI* aActionURL, |
128 | | const nsAString& aTarget, |
129 | | mozilla::NotNull<const mozilla::Encoding*> aEncoding, |
130 | | Element* aOriginatingElement) |
131 | | : mActionURL(aActionURL) |
132 | | , mTarget(aTarget) |
133 | | , mEncoding(aEncoding) |
134 | | , mOriginatingElement(aOriginatingElement) |
135 | | { |
136 | | MOZ_COUNT_CTOR(HTMLFormSubmission); |
137 | | } |
138 | | |
139 | | // The action url. |
140 | | nsCOMPtr<nsIURI> mActionURL; |
141 | | |
142 | | // The target. |
143 | | nsString mTarget; |
144 | | |
145 | | // The character encoding of this form submission |
146 | | mozilla::NotNull<const mozilla::Encoding*> mEncoding; |
147 | | |
148 | | // Originating element. |
149 | | RefPtr<Element> mOriginatingElement; |
150 | | }; |
151 | | |
152 | | class EncodingFormSubmission : public HTMLFormSubmission |
153 | | { |
154 | | public: |
155 | | EncodingFormSubmission(nsIURI* aActionURL, |
156 | | const nsAString& aTarget, |
157 | | mozilla::NotNull<const mozilla::Encoding*> aEncoding, |
158 | | Element* aOriginatingElement); |
159 | | |
160 | | virtual ~EncodingFormSubmission(); |
161 | | |
162 | | /** |
163 | | * Encode a Unicode string to bytes using the encoder (or just copy the input |
164 | | * if there is no encoder). |
165 | | * @param aStr the string to encode |
166 | | * @param aResult the encoded string [OUT] |
167 | | * @param aHeaderEncode If true, turns all linebreaks into spaces and escapes |
168 | | * all quotes |
169 | | * @throws an error if UnicodeToNewBytes fails |
170 | | */ |
171 | | nsresult EncodeVal(const nsAString& aStr, nsCString& aResult, |
172 | | bool aHeaderEncode); |
173 | | }; |
174 | | |
175 | | /** |
176 | | * Handle multipart/form-data encoding, which does files as well as normal |
177 | | * inputs. This always does POST. |
178 | | */ |
179 | | class FSMultipartFormData : public EncodingFormSubmission |
180 | | { |
181 | | public: |
182 | | /** |
183 | | * @param aEncoding the character encoding of the form |
184 | | */ |
185 | | FSMultipartFormData(nsIURI* aActionURL, |
186 | | const nsAString& aTarget, |
187 | | mozilla::NotNull<const mozilla::Encoding*> aEncoding, |
188 | | Element* aOriginatingElement); |
189 | | ~FSMultipartFormData(); |
190 | | |
191 | | virtual nsresult |
192 | | AddNameValuePair(const nsAString& aName, const nsAString& aValue) override; |
193 | | |
194 | | virtual nsresult |
195 | | AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob) override; |
196 | | |
197 | | virtual nsresult |
198 | | AddNameDirectoryPair(const nsAString& aName, Directory* aDirectory) override; |
199 | | |
200 | | virtual nsresult |
201 | | GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream, |
202 | | nsCOMPtr<nsIURI>& aOutURI) override; |
203 | | |
204 | | void GetContentType(nsACString& aContentType) |
205 | | { |
206 | | aContentType = |
207 | | NS_LITERAL_CSTRING("multipart/form-data; boundary=") + mBoundary; |
208 | | } |
209 | | |
210 | | nsIInputStream* GetSubmissionBody(uint64_t* aContentLength); |
211 | | |
212 | | protected: |
213 | | |
214 | | /** |
215 | | * Roll up the data we have so far and add it to the multiplexed data stream. |
216 | | */ |
217 | | nsresult AddPostDataStream(); |
218 | | |
219 | | private: |
220 | | void AddDataChunk(const nsACString& aName, |
221 | | const nsACString& aFilename, |
222 | | const nsACString& aContentType, |
223 | | nsIInputStream* aInputStream, |
224 | | uint64_t aInputStreamSize); |
225 | | /** |
226 | | * The post data stream as it is so far. This is a collection of smaller |
227 | | * chunks--string streams and file streams interleaved to make one big POST |
228 | | * stream. |
229 | | */ |
230 | | nsCOMPtr<nsIMultiplexInputStream> mPostData; |
231 | | |
232 | | /** |
233 | | * The same stream, but as an nsIInputStream. |
234 | | * Raw pointers because it is just QI of mInputStream. |
235 | | */ |
236 | | nsIInputStream* mPostDataStream; |
237 | | |
238 | | /** |
239 | | * The current string chunk. When a file is hit, the string chunk gets |
240 | | * wrapped up into an input stream and put into mPostDataStream so that the |
241 | | * file input stream can then be appended and everything is in the right |
242 | | * order. Then the string chunk gets appended to again as we process more |
243 | | * name/value pairs. |
244 | | */ |
245 | | nsCString mPostDataChunk; |
246 | | |
247 | | /** |
248 | | * The boundary string to use after each "part" (the boundary that marks the |
249 | | * end of a value). This is computed randomly and is different for each |
250 | | * submission. |
251 | | */ |
252 | | nsCString mBoundary; |
253 | | |
254 | | /** |
255 | | * The total length in bytes of the streams that make up mPostDataStream |
256 | | */ |
257 | | uint64_t mTotalLength; |
258 | | }; |
259 | | |
260 | | } // namespace dom |
261 | | } // namespace mozilla |
262 | | |
263 | | #endif /* mozilla_dom_HTMLFormSubmission_h */ |