OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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 CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_POST_DATA_PARSER_H_ | |
6 #define CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_POST_DATA_PARSER_H_ | |
7 | |
8 #include <string> | |
9 #include <vector> | |
10 | |
11 #include "base/compiler_specific.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/string_piece.h" | |
14 // Need to include this, because UploadData::Element cannot be forward declared. | |
15 #include "net/base/upload_data.h" | |
16 | |
17 namespace base { | |
18 class DictionaryValue; | |
19 class Value; | |
20 } | |
21 | |
22 namespace net { | |
23 class URLRequest; | |
24 } | |
25 | |
26 namespace extensions { | |
27 | |
28 // Interface for parsers for the POST data. | |
wtc
2012/08/09 23:39:40
Nit: POST data => form data
vabr (Chromium)
2012/08/10 17:12:55
Done.
| |
29 class FormDataParser { | |
30 public: | |
31 class Result { | |
32 public: | |
33 Result(); | |
34 ~Result(); | |
35 const std::string& name() const { | |
36 return name_; | |
37 } | |
38 const std::string& value() const { | |
39 return value_; | |
40 } | |
41 void Reset(); | |
42 void set_name(const base::StringPiece& str); | |
43 void set_name(const std::string& str); | |
44 void set_value(const base::StringPiece& str); | |
45 void set_value(const std::string& str); | |
wtc
2012/08/09 23:39:40
Nit: since we define the getters in the header, pe
vabr (Chromium)
2012/08/10 17:12:55
Done.
| |
46 | |
47 private: | |
48 std::string name_; | |
49 std::string value_; | |
50 }; | |
51 | |
52 virtual ~FormDataParser(); | |
53 | |
54 // Creates a correct parser instance based on the |request|. Returns NULL | |
55 // on failure. | |
56 static scoped_ptr<FormDataParser> Create(const net::URLRequest* request); | |
57 | |
58 // Creates a correct parser instance based on |content_type_header|, the | |
59 // "Content-Type" request header value. If |content_type_header| is NULL, it | |
60 // defaults to "application/x-www-form-urlencoded". Returns NULL on failure. | |
61 static scoped_ptr<FormDataParser> Create( | |
62 const std::string* content_type_header); | |
63 | |
64 // Returns true if there was some data, it was well formed and all was read. | |
65 virtual bool AllDataReadOK() = 0; | |
66 | |
67 // Returns the next name-value pair as |result|. After SetSource has | |
68 // succeeded, this allows to iterate over all pairs in the source. | |
69 // Returns true as long as a new pair was successfully found. | |
70 virtual bool GetNextNameValue(Result* result) = 0; | |
71 | |
72 // Sets the |source| of the data to be parsed. The ownership is left with the | |
73 // caller and the source should live until |this| dies or |this->SetSource()| | |
74 // is called again, whichever comes sooner. Returns true on success. | |
75 virtual bool SetSource(const std::vector<char>* source) = 0; | |
76 | |
77 protected: | |
78 FormDataParser(); | |
79 | |
80 private: | |
81 DISALLOW_COPY_AND_ASSIGN(FormDataParser); | |
82 }; | |
83 | |
84 // Parses URLencoded forms, see | |
85 // http://www.w3.org/TR/REC-html40-971218/interact/forms.html#h-17.13.4.1 . | |
86 class FormDataParserUrlEncoded : public FormDataParser { | |
87 public: | |
88 FormDataParserUrlEncoded(); | |
89 virtual ~FormDataParserUrlEncoded(); | |
90 | |
91 // Implementation of FormDataParser. | |
92 virtual bool AllDataReadOK() OVERRIDE; | |
93 virtual bool GetNextNameValue(Result* result) OVERRIDE; | |
94 virtual bool SetSource(const std::vector<char>* source) OVERRIDE; | |
95 | |
96 private: | |
97 // Gets next char from |source_|, seeks, and does book-keeping of = and &. | |
98 // Returns false if end of |source_| was reached, otherwise true. | |
99 bool GetNextChar(char* c); | |
100 // Once called the parser gives up and claims any results so far invalid. | |
101 void Abort(); | |
102 | |
103 const std::vector<char>* source_; | |
104 bool aborted_; | |
105 | |
106 // Variables from this block are only to be written to by GetNextChar. | |
107 std::vector<char>::const_iterator offset_; // Next char to be read. | |
108 size_t equality_signs_; // How many '=' were read so far. | |
109 size_t amp_signs_; // How many '&' were read so far. | |
110 bool expect_equality_; // Is the next trailing sign '=' (as opposed to '&')? | |
111 | |
112 DISALLOW_COPY_AND_ASSIGN(FormDataParserUrlEncoded); | |
113 }; | |
114 | |
115 // Parses forms encoded as multipart, see RFC 2388. | |
116 class FormDataParserMultipart : public FormDataParser { | |
117 public: | |
118 explicit FormDataParserMultipart(const std::string& boundary_separator); | |
119 virtual ~FormDataParserMultipart(); | |
120 | |
121 // Implementation of FormDataParser. | |
122 virtual bool AllDataReadOK() OVERRIDE; | |
123 virtual bool GetNextNameValue(Result* result) OVERRIDE; | |
124 virtual bool SetSource(const std::vector<char>* source) OVERRIDE; | |
125 | |
126 private: | |
127 // Note on implementation: | |
128 // This parser reads the source line by line. These are the types of lines: | |
129 // - "Boundary" line, separating entries. | |
130 // - "End boundary" line, ends the data. | |
131 // - "Content-Disposition" line, containing the "name" for |result|. | |
132 // - Empty lines. | |
133 // - Other non-empty lines. | |
134 enum LineType {kBoundary, kEndBoundary, kDisposition, kEmpty, kOther}; | |
135 | |
136 // The parser uses the following 7-state automaton to check for structure: | |
137 // kInit --Boundary--> kHeaderStart, kInit --not(Boundary)--> kError | |
138 // kHeaderStart --Disposition--> kHeaderRead, | |
139 // kHeaderStart --not(Disposition)--> kHeader | |
140 // kHeader --Disposition--> kHeaderRead, kHeader --not(Disposition)-->kHeader | |
141 // kHeaderRead --Empty-->kBody, kHeaderRead --not(Empty)--> kHeaderRead | |
142 // kBody --Boundary--> kHeaderStart, kBody --EndBoundary--> kFinal, | |
143 // kBody --not(Boundary OR EndBoundary)--> kBody | |
144 enum State {kInit, kHeaderStart, kHeader, kHeaderRead, kBody, kFinal, kError}; | |
145 | |
146 // One step of the automaton, based on |state_| and |line_type_|. | |
147 // This calls SeekNextLine() and returns its return value. | |
148 bool DoStep(); | |
149 | |
150 // Determine the |line_type_| of the current line_start_. | |
151 LineType GetLineType(); | |
152 | |
153 // Read one more line from |source_|, update line pointers. | |
154 bool SeekNextLine(); | |
155 | |
156 // Extracts "name" and possibly "value" from a line with type kDisposition. | |
157 // Returns true on success and false otherwise. | |
158 bool ParseHeader(Result* result, bool* value_extracted); | |
159 | |
160 // We parse the first |length_| bytes from |source_|. | |
161 const char* source_; | |
162 size_t length_; | |
163 | |
164 // Offset of the current and next line from |source_|: | |
165 // [line_start_]...line... [line_end_]EOL [next_line_]...line... | |
166 size_t line_start_; // Points at the first character of the current line. | |
167 size_t line_end_; // Points right beyond the last character of the line. | |
168 size_t next_line_; // First char. of the next line, or beyond source length. | |
169 const std::string boundary_; | |
170 const std::string end_boundary_; | |
171 State state_; | |
172 LineType line_type_; | |
173 | |
174 DISALLOW_COPY_AND_ASSIGN(FormDataParserMultipart); | |
175 }; | |
176 | |
177 // Workflow for objects implementing this interface: | |
wtc
2012/08/09 23:39:40
Nit: first define what this interface is or does.
vabr (Chromium)
2012/08/10 17:12:55
Done.
| |
178 // 1. Call object->FeedNext(element) for each element from the request's body. | |
179 // 2. Check if object->Succeeded(). | |
180 // 3. If that check passed then retrieve object->Result(). | |
181 class RequestDataRepresentationProducer { | |
182 public: | |
183 virtual ~RequestDataRepresentationProducer(); | |
184 virtual void FeedNext(const net::UploadData::Element& element) = 0; | |
185 virtual bool Succeeded() = 0; | |
186 virtual scoped_ptr<base::Value> Result() = 0; | |
187 | |
188 protected: | |
189 RequestDataRepresentationProducer() {} | |
190 | |
191 private: | |
192 DISALLOW_COPY_AND_ASSIGN(RequestDataRepresentationProducer); | |
193 }; | |
194 | |
195 // This class checks that chunked transfer encoding (defined in RFC 2616) | |
196 // is not used. If it is, an error string is generated. | |
197 class ChunkedErrorProducer : public RequestDataRepresentationProducer { | |
198 public: | |
199 explicit ChunkedErrorProducer(const net::URLRequest* request); | |
200 virtual ~ChunkedErrorProducer(); | |
201 | |
202 // Tests the headers of |request| for transfer encoding. | |
203 static bool TransferEncodingChunked(const net::URLRequest* request); | |
204 | |
205 // Implementation of RequestDataRepresentationProducer. | |
206 virtual void FeedNext(const net::UploadData::Element& element) OVERRIDE; | |
207 virtual bool Succeeded() OVERRIDE; | |
208 virtual scoped_ptr<base::Value> Result() OVERRIDE; | |
209 | |
210 private: | |
211 bool chunks_found_; | |
212 }; | |
213 | |
214 class RawDataProducer : public RequestDataRepresentationProducer { | |
215 public: | |
216 RawDataProducer(); | |
217 virtual ~RawDataProducer(); | |
218 | |
219 // Implementation of RequestDataRepresentationProducer. | |
220 virtual void FeedNext(const net::UploadData::Element& element) OVERRIDE; | |
221 virtual bool Succeeded() OVERRIDE; | |
222 virtual scoped_ptr<base::Value> Result() OVERRIDE; | |
223 | |
224 private: | |
225 // Clears resources and the success flag. | |
226 void Abort(); | |
227 std::vector<char> data_; | |
228 std::string data_string_; | |
229 bool success_; | |
230 }; | |
231 | |
232 class ParsedDataProducer : public RequestDataRepresentationProducer { | |
233 public: | |
234 explicit ParsedDataProducer(const net::URLRequest* request); | |
235 virtual ~ParsedDataProducer(); | |
236 | |
237 // Implementation of RequestDataRepresentationProducer. | |
238 virtual void FeedNext(const net::UploadData::Element& element) OVERRIDE; | |
239 virtual bool Succeeded() OVERRIDE; | |
240 virtual scoped_ptr<base::Value> Result() OVERRIDE; | |
241 | |
242 private: | |
243 // Clears resources and the success flag. | |
244 void Abort(); | |
245 scoped_ptr<FormDataParser> parser_; | |
246 bool success_; | |
247 scoped_ptr<base::DictionaryValue> dictionary_; | |
248 }; | |
249 | |
250 } // namespace extensions | |
251 | |
252 #endif // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_POST_DATA_PARSER_H_ | |
OLD | NEW |