Chromium Code Reviews| 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 |