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

Side by Side Diff: chrome/browser/extensions/api/web_request/upload_data_presenter.cc

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: Corrected the multipart parser + parsedForm->formData 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 #include "chrome/browser/extensions/api/web_request/upload_data_presenter.h"
6
7 #include "base/base64.h"
8 #include "base/file_path.h"
9 #include "base/string_util.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/api/web_request/form_data_parser.h"
12 #include "net/url_request/url_request.h"
13
14 using base::BinaryValue;
15 using base::DictionaryValue;
16 using base::ListValue;
17 using base::StringValue;
18 using base::Value;
19
20 namespace {
21
22 // Takes |dictionary| of <string, list of strings> pairs, and gets the list
23 // for |key|, creating it if necessary.
24 ListValue* GetOrCreateList(DictionaryValue* dictionary,
25 const std::string& key) {
26 ListValue* list = NULL;
27 if (!dictionary->GetList(key, &list)) {
28 list = new ListValue();
29 dictionary->Set(key, list);
30 }
31 return list;
32 }
33
34 } // namespace
35
36 namespace extensions {
37
38 // Implementation of UploadDataPresenter.
39
40 UploadDataPresenter::~UploadDataPresenter() {}
41
42 // Implementation of ChunkedErrorPresenter.
43
44 ChunkedErrorPresenter::ChunkedErrorPresenter(const net::URLRequest* request)
45 : chunks_found_(TransferEncodingChunked(request)) {
46 }
47
48 ChunkedErrorPresenter::~ChunkedErrorPresenter() {}
49
50 // static
51 bool ChunkedErrorPresenter::TransferEncodingChunked(
52 const net::URLRequest* request){
53 std::string transfer_encoding;
54 if (!request->extra_request_headers().GetHeader(
55 net::HttpRequestHeaders::kTransferEncoding, &transfer_encoding))
battre 2012/08/16 19:18:03 nit: +4 indent
vabr (Chromium) 2012/08/17 18:29:57 Are you sure? Does the +4 indent rule here apply t
battre 2012/08/20 12:09:38 The reasoning is that the line would usually conti
vabr (Chromium) 2012/08/23 15:41:54 :) I sacrificed one more line to get the headers f
56 return false;
57 return base::strcasecmp(transfer_encoding.c_str(), "chunked") == 0;
58 }
59
60 void ChunkedErrorPresenter::FeedNext(const net::UploadData::Element& element) {
61 if (chunks_found_)
62 return; // We already found a reason to report an error.
63
64 if (element.type() == net::UploadData::TYPE_CHUNK)
65 chunks_found_ = true;
66 }
67
68 bool ChunkedErrorPresenter::Succeeded() {
69 return chunks_found_;
battre 2012/08/16 19:18:03 is this correct? Shouldn't this always return true
vabr (Chromium) 2012/08/17 18:29:57 It should only return true if there were some elem
70 }
71
72 scoped_ptr<Value> ChunkedErrorPresenter::Result() {
73 if (!chunks_found_)
74 return scoped_ptr<Value>();
75
76 scoped_ptr<StringValue> error_string(new StringValue(
77 "Not supported: data is uploaded chunked."));
78 return error_string.PassAs<Value>();
79 }
80
81 // Implementation of RawDataPresenter.
82
83 RawDataPresenter::RawDataPresenter()
84 : success_(true),
85 list_(new base::ListValue) {
86 }
87 RawDataPresenter::~RawDataPresenter() {}
88
89 void RawDataPresenter::FeedNext(const net::UploadData::Element& element) {
90 if (!success_)
91 return;
92
93 if (element.type() == net::UploadData::TYPE_BYTES) {
94 FeedNextBytes(element.bytes());
95 } else if (element.type() == net::UploadData::TYPE_CHUNK) {
96 Abort(); // Chunks are not supported (yet).
97 } else if (element.type() == net::UploadData::TYPE_FILE) {
98 // Insert the file path instead of the contents, which may be too large.
99 FeedNextFile(element.file_path().AsUTF8Unsafe());
100 } // TYPE_BLOB is silently ignored.
battre 2012/08/16 19:18:03 how about: switch (element.type()) { case TYPE_B
battre 2012/08/16 19:18:03 Why silently ignored? Should we not generate a str
vabr (Chromium) 2012/08/17 18:29:57 Good idea.
vabr (Chromium) 2012/08/17 18:29:57 Given the comment at UploadData::Element::SetToBlo
battre 2012/08/20 12:09:38 Add a NOTREACHED()?
vabr (Chromium) 2012/08/23 15:41:54 Well, CL https://chromiumcodereview.appspot.com/10
101 }
102
103 bool RawDataPresenter::Succeeded() {
104 return success_;
105 }
106
107 scoped_ptr<Value> RawDataPresenter::Result() {
108 if (!success_)
109 return scoped_ptr<Value>();
110
111 return list_.PassAs<Value>();
112 }
113
114 void RawDataPresenter::Abort() {
115 success_ = false;
116 list_.reset();
117 }
118
119 void RawDataPresenter::FeedNextBytes(const std::vector<char>& bytes) {
120 list_->Append(
121 BinaryValue::CreateWithCopiedBuffer(&(bytes[0]), bytes.size()));
122 }
123
124 void RawDataPresenter::FeedNextFile(const std::string& filename) {
125 // Insert the file path instead of the contents, which may be too large.
126 std::string bytes_encoded;
127 success_ = base::Base64Encode(filename, &bytes_encoded);
battre 2012/08/16 19:18:03 Why do you pass the file path as base64 encoded da
vabr (Chromium) 2012/08/17 18:29:57 I removed the encoding. At some point I saw it tra
128 if (success_)
129 list_->Append(new StringValue(bytes_encoded));
130 }
131
132 // Implementation of ParsedDataPresenter.
133
134 ParsedDataPresenter::ParsedDataPresenter(const net::URLRequest* request)
135 : parser_(FormDataParser::Create(request).release()),
battre 2012/08/16 19:18:03 is this .release() necessary?
vabr (Chromium) 2012/08/17 18:29:57 No :). Removed.
136 success_(parser_.get() != NULL),
137 dictionary_(success_ ? new DictionaryValue() : NULL) {
138 }
139
140 ParsedDataPresenter::~ParsedDataPresenter() {}
141
142 void ParsedDataPresenter::FeedNext(const net::UploadData::Element& element) {
143 if (!success_)
144 return;
145
146 if (element.type() != net::UploadData::TYPE_BYTES) {
147 if (element.type() != net::UploadData::TYPE_FILE) {
148 Abort(); // We do not handle blobs nor chunks.
149 }
150 return; // But we just ignore files.
151 }
152 if (!parser_->SetSource(&(element.bytes()))) {
153 Abort();
154 return;
155 }
156
157 FormDataParser::Result result;
158 while (parser_->GetNextNameValue(&result)) {
159 GetOrCreateList(dictionary_.get(), result.name())->Append(
160 new StringValue(result.value()));
161 }
162 }
163
164 bool ParsedDataPresenter::Succeeded() {
165 if (success_ && !parser_->AllDataReadOK())
166 Abort();
167 return success_;
168 }
169
170 scoped_ptr<Value> ParsedDataPresenter::Result() {
171 if (success_)
172 return dictionary_.PassAs<Value>();
battre 2012/08/16 19:18:03 I think this looks wrong. You return the ownership
vabr (Chromium) 2012/08/17 18:29:57 I start with dictionary_, which is a scoped_ptr<Di
battre 2012/08/20 12:09:38 Never mind. I misunderstood your code in web_reque
173 else
174 return scoped_ptr<Value>();
175 }
176
177 void ParsedDataPresenter::Abort() {
178 success_ = false;
179 dictionary_.reset();
180 parser_.reset();
181 }
182
183 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698