Coverage Report

Created: 2018-09-25 14:53

/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 */