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 |
| 15 namespace base { |
| 16 class DictionaryValue; |
| 17 } |
| 18 |
| 19 namespace net { |
| 20 class URLRequest; |
| 21 } |
| 22 |
| 23 namespace extensions { |
| 24 |
| 25 // Interface for parsers for the POST data. |
| 26 class PostDataParser { |
| 27 public: |
| 28 class Result { |
| 29 public: |
| 30 Result(); |
| 31 ~Result(); |
| 32 const std::string& key() const { |
| 33 return key_; |
| 34 } |
| 35 const std::string& val() const { |
| 36 return val_; |
| 37 } |
| 38 void Reset(); |
| 39 void SetKey(const base::StringPiece& str); |
| 40 void SetKey(const std::string& str); |
| 41 void SetVal(const base::StringPiece& str); |
| 42 void SetVal(const std::string& str); |
| 43 |
| 44 private: |
| 45 std::string key_; |
| 46 std::string val_; |
| 47 }; |
| 48 |
| 49 // Creates a correct parser instance based on the |request|. Returns NULL |
| 50 // on failure. |
| 51 static scoped_ptr<PostDataParser> CreatePostDataParser( |
| 52 const net::URLRequest* request); |
| 53 |
| 54 // Creates a correct parser instance based on the |content_type| of |
| 55 // "Content-Type" URLRequest headers. If |content_type| is NULL, it defaults |
| 56 // to "application/x-www-form-urlencoded". Returns NULL on failure. |
| 57 static scoped_ptr<PostDataParser> CreatePostDataParser( |
| 58 const std::string* content_type); |
| 59 |
| 60 // Tries to parse the POST data of |request| to extract encoded forms. |
| 61 // On success returns the parsed data, otherwise NULL. |
| 62 static scoped_ptr<base::DictionaryValue> ParseURLRequestData( |
| 63 const net::URLRequest* request); |
| 64 |
| 65 virtual ~PostDataParser(); |
| 66 |
| 67 // Returns true if there was some data, it was well formed and all was read. |
| 68 virtual bool AllDataReadOK() = 0; |
| 69 |
| 70 // Returns the next key-value pair as |result|. After SetSource has succeeded, |
| 71 // this allows to iterate over all pairs in the source. |
| 72 // Returns true as long as a new pair was successfully found. |
| 73 virtual bool GetNextPair(Result* result) = 0; |
| 74 |
| 75 // Sets the |source| of the data to be parsed. The ownership is let with the |
| 76 // caller and the source should live until |this| dies or |this->SetSource()| |
| 77 // is called again, whatever comes sooner. Returns true on success. |
| 78 virtual bool SetSource(const std::vector<char>* source) = 0; |
| 79 |
| 80 protected: |
| 81 PostDataParser() {} |
| 82 |
| 83 private: |
| 84 DISALLOW_COPY_AND_ASSIGN(PostDataParser); |
| 85 }; |
| 86 |
| 87 // Parses URLencoded forms, see |
| 88 // http://www.w3.org/TR/REC-html40-971218/interact/forms.html#h-17.13.4.1 . |
| 89 class PostDataParserUrlEncoded : public PostDataParser { |
| 90 public: |
| 91 PostDataParserUrlEncoded(); |
| 92 virtual ~PostDataParserUrlEncoded(); |
| 93 |
| 94 // Implementation of PostDataParser. |
| 95 virtual bool AllDataReadOK() OVERRIDE; |
| 96 virtual bool GetNextPair(Result* result) OVERRIDE; |
| 97 virtual bool SetSource(const std::vector<char>* source) OVERRIDE; |
| 98 |
| 99 private: |
| 100 const std::vector<char>* source_; |
| 101 std::vector<char>::const_iterator offset_; |
| 102 DISALLOW_COPY_AND_ASSIGN(PostDataParserUrlEncoded); |
| 103 }; |
| 104 |
| 105 // Parses forms encoded as multipart, see RFC2388. |
| 106 class PostDataParserMultipart : public PostDataParser { |
| 107 public: |
| 108 explicit PostDataParserMultipart(const std::string& boundary_separator); |
| 109 virtual ~PostDataParserMultipart(); |
| 110 // Implementation of PostDataParser. |
| 111 virtual bool AllDataReadOK() OVERRIDE; |
| 112 virtual bool GetNextPair(Result* result) OVERRIDE; |
| 113 virtual bool SetSource(const std::vector<char>* source) OVERRIDE; |
| 114 |
| 115 private: |
| 116 // Note on implementation: |
| 117 // This parser reads the source line by line. There are four types of lines: |
| 118 // - "Boundary" line, separating entries. |
| 119 // - "End boundary" line, ends the data. |
| 120 // - "Content-Disposition" line, containing the "key" for |result|. |
| 121 // - Empty lines. |
| 122 // - Other non-empty lines. |
| 123 enum LineType {kBoundary, kEndBoundary, kDisposition, kEmpty, kOther}; |
| 124 |
| 125 // The parser uses the following 7-state automaton to check for structure: |
| 126 // kInit --Boundary--> kHeadStart, kInit --not(Boundary)--> kError |
| 127 // kHeadStart --Disposition--> kHeadRead, |
| 128 // kHeadStart --not(Disposition)--> kHead |
| 129 // kHead --Disposition--> kHeadRead, kHead --not(Disposition)-->kHead |
| 130 // kHeadRead --Empty-->kBody, kHeadRead --not(Empty)--> kHeadRead |
| 131 // kBody --Boundary--> kHeadStart, kBody --EndBoundary--> kFinal, |
| 132 // kBody --not(Boundary OR EndBoundary)--> kBody |
| 133 enum State {kInit, kHeadStart, kHead, kHeadRead, kBody, kFinal, kError}; |
| 134 |
| 135 // One-step of the automaton, based on |state_| and |line_type_|. |
| 136 // This calls SeekNextLine() and returns it return value. |
| 137 bool DoStep(); |
| 138 |
| 139 // Determine the |line_type_| of the current line_start_. |
| 140 LineType GetLineType(); |
| 141 |
| 142 // Read one more line from |source_|, update line pointers. |
| 143 bool SeekNextLine(); |
| 144 |
| 145 // Extracts "key" and possibly "val" from a DISP line. Returns success. |
| 146 bool ParseHead(Result* result, bool* val_extracted); |
| 147 |
| 148 // We parse the first |length_| bytes from |source_|. |
| 149 const char* source_; |
| 150 size_t length_; |
| 151 |
| 152 // Offset of the current and next line from |source_|: |
| 153 // [line_start_]...line... [line_end_]EOL [next_line_]...line... |
| 154 size_t line_start_; // Points at the first character of the current line. |
| 155 size_t line_end_; // Points right beyond the last character of the line. |
| 156 size_t next_line_; // First char. of the next line, or beyond source length. |
| 157 const std::string boundary_; |
| 158 const std::string final_boundary_; |
| 159 State state_; |
| 160 LineType line_type_; |
| 161 DISALLOW_COPY_AND_ASSIGN(PostDataParserMultipart); |
| 162 }; |
| 163 |
| 164 } // namespace extensions |
| 165 |
| 166 #endif // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_POST_DATA_PARSER_H_ |
OLD | NEW |