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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/web_request/post_data_parser.h
diff --git a/chrome/browser/extensions/api/web_request/post_data_parser.h b/chrome/browser/extensions/api/web_request/post_data_parser.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f43f29b9cb5cee018d88beba7eaec39ffb8b5b1
--- /dev/null
+++ b/chrome/browser/extensions/api/web_request/post_data_parser.h
@@ -0,0 +1,252 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_POST_DATA_PARSER_H_
+#define CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_POST_DATA_PARSER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_piece.h"
+// Need to include this, because UploadData::Element cannot be forward declared.
+#include "net/base/upload_data.h"
+
+namespace base {
+class DictionaryValue;
+class Value;
+}
+
+namespace net {
+class URLRequest;
+}
+
+namespace extensions {
+
+// 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.
+class FormDataParser {
+ public:
+ class Result {
+ public:
+ Result();
+ ~Result();
+ const std::string& name() const {
+ return name_;
+ }
+ const std::string& value() const {
+ return value_;
+ }
+ void Reset();
+ void set_name(const base::StringPiece& str);
+ void set_name(const std::string& str);
+ void set_value(const base::StringPiece& str);
+ 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.
+
+ private:
+ std::string name_;
+ std::string value_;
+ };
+
+ virtual ~FormDataParser();
+
+ // Creates a correct parser instance based on the |request|. Returns NULL
+ // on failure.
+ static scoped_ptr<FormDataParser> Create(const net::URLRequest* request);
+
+ // Creates a correct parser instance based on |content_type_header|, the
+ // "Content-Type" request header value. If |content_type_header| is NULL, it
+ // defaults to "application/x-www-form-urlencoded". Returns NULL on failure.
+ static scoped_ptr<FormDataParser> Create(
+ const std::string* content_type_header);
+
+ // Returns true if there was some data, it was well formed and all was read.
+ virtual bool AllDataReadOK() = 0;
+
+ // Returns the next name-value pair as |result|. After SetSource has
+ // succeeded, this allows to iterate over all pairs in the source.
+ // Returns true as long as a new pair was successfully found.
+ virtual bool GetNextNameValue(Result* result) = 0;
+
+ // Sets the |source| of the data to be parsed. The ownership is left with the
+ // caller and the source should live until |this| dies or |this->SetSource()|
+ // is called again, whichever comes sooner. Returns true on success.
+ virtual bool SetSource(const std::vector<char>* source) = 0;
+
+ protected:
+ FormDataParser();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FormDataParser);
+};
+
+// Parses URLencoded forms, see
+// http://www.w3.org/TR/REC-html40-971218/interact/forms.html#h-17.13.4.1 .
+class FormDataParserUrlEncoded : public FormDataParser {
+ public:
+ FormDataParserUrlEncoded();
+ virtual ~FormDataParserUrlEncoded();
+
+ // Implementation of FormDataParser.
+ virtual bool AllDataReadOK() OVERRIDE;
+ virtual bool GetNextNameValue(Result* result) OVERRIDE;
+ virtual bool SetSource(const std::vector<char>* source) OVERRIDE;
+
+ private:
+ // Gets next char from |source_|, seeks, and does book-keeping of = and &.
+ // Returns false if end of |source_| was reached, otherwise true.
+ bool GetNextChar(char* c);
+ // Once called the parser gives up and claims any results so far invalid.
+ void Abort();
+
+ const std::vector<char>* source_;
+ bool aborted_;
+
+ // Variables from this block are only to be written to by GetNextChar.
+ std::vector<char>::const_iterator offset_; // Next char to be read.
+ size_t equality_signs_; // How many '=' were read so far.
+ size_t amp_signs_; // How many '&' were read so far.
+ bool expect_equality_; // Is the next trailing sign '=' (as opposed to '&')?
+
+ DISALLOW_COPY_AND_ASSIGN(FormDataParserUrlEncoded);
+};
+
+// Parses forms encoded as multipart, see RFC 2388.
+class FormDataParserMultipart : public FormDataParser {
+ public:
+ explicit FormDataParserMultipart(const std::string& boundary_separator);
+ virtual ~FormDataParserMultipart();
+
+ // Implementation of FormDataParser.
+ virtual bool AllDataReadOK() OVERRIDE;
+ virtual bool GetNextNameValue(Result* result) OVERRIDE;
+ virtual bool SetSource(const std::vector<char>* source) OVERRIDE;
+
+ private:
+ // Note on implementation:
+ // This parser reads the source line by line. These are the types of lines:
+ // - "Boundary" line, separating entries.
+ // - "End boundary" line, ends the data.
+ // - "Content-Disposition" line, containing the "name" for |result|.
+ // - Empty lines.
+ // - Other non-empty lines.
+ enum LineType {kBoundary, kEndBoundary, kDisposition, kEmpty, kOther};
+
+ // The parser uses the following 7-state automaton to check for structure:
+ // kInit --Boundary--> kHeaderStart, kInit --not(Boundary)--> kError
+ // kHeaderStart --Disposition--> kHeaderRead,
+ // kHeaderStart --not(Disposition)--> kHeader
+ // kHeader --Disposition--> kHeaderRead, kHeader --not(Disposition)-->kHeader
+ // kHeaderRead --Empty-->kBody, kHeaderRead --not(Empty)--> kHeaderRead
+ // kBody --Boundary--> kHeaderStart, kBody --EndBoundary--> kFinal,
+ // kBody --not(Boundary OR EndBoundary)--> kBody
+ enum State {kInit, kHeaderStart, kHeader, kHeaderRead, kBody, kFinal, kError};
+
+ // One step of the automaton, based on |state_| and |line_type_|.
+ // This calls SeekNextLine() and returns its return value.
+ bool DoStep();
+
+ // Determine the |line_type_| of the current line_start_.
+ LineType GetLineType();
+
+ // Read one more line from |source_|, update line pointers.
+ bool SeekNextLine();
+
+ // Extracts "name" and possibly "value" from a line with type kDisposition.
+ // Returns true on success and false otherwise.
+ bool ParseHeader(Result* result, bool* value_extracted);
+
+ // We parse the first |length_| bytes from |source_|.
+ const char* source_;
+ size_t length_;
+
+ // Offset of the current and next line from |source_|:
+ // [line_start_]...line... [line_end_]EOL [next_line_]...line...
+ size_t line_start_; // Points at the first character of the current line.
+ size_t line_end_; // Points right beyond the last character of the line.
+ size_t next_line_; // First char. of the next line, or beyond source length.
+ const std::string boundary_;
+ const std::string end_boundary_;
+ State state_;
+ LineType line_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(FormDataParserMultipart);
+};
+
+// 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.
+// 1. Call object->FeedNext(element) for each element from the request's body.
+// 2. Check if object->Succeeded().
+// 3. If that check passed then retrieve object->Result().
+class RequestDataRepresentationProducer {
+ public:
+ virtual ~RequestDataRepresentationProducer();
+ virtual void FeedNext(const net::UploadData::Element& element) = 0;
+ virtual bool Succeeded() = 0;
+ virtual scoped_ptr<base::Value> Result() = 0;
+
+ protected:
+ RequestDataRepresentationProducer() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RequestDataRepresentationProducer);
+};
+
+// This class checks that chunked transfer encoding (defined in RFC 2616)
+// is not used. If it is, an error string is generated.
+class ChunkedErrorProducer : public RequestDataRepresentationProducer {
+ public:
+ explicit ChunkedErrorProducer(const net::URLRequest* request);
+ virtual ~ChunkedErrorProducer();
+
+ // Tests the headers of |request| for transfer encoding.
+ static bool TransferEncodingChunked(const net::URLRequest* request);
+
+ // Implementation of RequestDataRepresentationProducer.
+ virtual void FeedNext(const net::UploadData::Element& element) OVERRIDE;
+ virtual bool Succeeded() OVERRIDE;
+ virtual scoped_ptr<base::Value> Result() OVERRIDE;
+
+ private:
+ bool chunks_found_;
+};
+
+class RawDataProducer : public RequestDataRepresentationProducer {
+ public:
+ RawDataProducer();
+ virtual ~RawDataProducer();
+
+ // Implementation of RequestDataRepresentationProducer.
+ virtual void FeedNext(const net::UploadData::Element& element) OVERRIDE;
+ virtual bool Succeeded() OVERRIDE;
+ virtual scoped_ptr<base::Value> Result() OVERRIDE;
+
+ private:
+ // Clears resources and the success flag.
+ void Abort();
+ std::vector<char> data_;
+ std::string data_string_;
+ bool success_;
+};
+
+class ParsedDataProducer : public RequestDataRepresentationProducer {
+ public:
+ explicit ParsedDataProducer(const net::URLRequest* request);
+ virtual ~ParsedDataProducer();
+
+ // Implementation of RequestDataRepresentationProducer.
+ virtual void FeedNext(const net::UploadData::Element& element) OVERRIDE;
+ virtual bool Succeeded() OVERRIDE;
+ virtual scoped_ptr<base::Value> Result() OVERRIDE;
+
+ private:
+ // Clears resources and the success flag.
+ void Abort();
+ scoped_ptr<FormDataParser> parser_;
+ bool success_;
+ scoped_ptr<base::DictionaryValue> dictionary_;
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_POST_DATA_PARSER_H_

Powered by Google App Engine
This is Rietveld 408576698