Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(937)

Side by Side Diff: chrome/browser/extensions/api/web_request/post_data_parser.h

Issue 10694055: Add read-only access to POST data for webRequest's onBeforeRequest (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebased + some corrections Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698