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

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: Dominic's comments 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/file_path.h"
8 #include "base/string_util.h"
9 #include "base/values.h"
10 #include "chrome/browser/extensions/api/web_request/form_data_parser.h"
11 #include "net/url_request/url_request.h"
12
13 using base::BinaryValue;
14 using base::DictionaryValue;
15 using base::ListValue;
16 using base::StringValue;
17 using base::Value;
18
19 namespace {
20
21 // Takes |dictionary| of <string, list of strings> pairs, and gets the list
22 // for |key|, creating it if necessary.
23 ListValue* GetOrCreateList(DictionaryValue* dictionary,
24 const std::string& key) {
25 ListValue* list = NULL;
26 if (!dictionary->GetList(key, &list)) {
27 list = new ListValue();
28 dictionary->Set(key, list);
29 }
30 return list;
31 }
32
33 } // namespace
34
35 namespace extensions {
36
37 // Implementation of UploadDataPresenter.
38
39 UploadDataPresenter::~UploadDataPresenter() {}
40
41 // Implementation of ChunkedErrorPresenter.
42
43 ChunkedErrorPresenter::ChunkedErrorPresenter(const net::URLRequest* request)
44 : chunks_found_(IsTransferEncodingChunked(request)) {
45 }
46
47 ChunkedErrorPresenter::~ChunkedErrorPresenter() {}
48
49 // static
50 bool ChunkedErrorPresenter::IsTransferEncodingChunked(
51 const net::URLRequest* request){
52 std::string transfer_encoding;
53 if (!request->extra_request_headers().GetHeader(
54 net::HttpRequestHeaders::kTransferEncoding, &transfer_encoding)) {
55 return false;
56 }
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_;
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 switch (element.type()) {
94 case net::UploadData::TYPE_BYTES:
95 FeedNextBytes(element.bytes());
96 break;
97 case net::UploadData::TYPE_CHUNK:
98 Abort(); // Chunks are not supported (yet).
99 break;
100 case net::UploadData::TYPE_FILE:
101 // Insert the file path instead of the contents, which may be too large.
102 FeedNextFile(element.file_path().AsUTF8Unsafe());
103 break;
104 case net::UploadData::TYPE_BLOB:
105 // TYPE_BLOB is silently ignored.
106 break;
107 }
108 }
109
110 bool RawDataPresenter::Succeeded() {
111 return success_;
112 }
113
114 scoped_ptr<Value> RawDataPresenter::Result() {
115 if (!success_)
116 return scoped_ptr<Value>();
117
118 return list_.PassAs<Value>();
119 }
120
121 void RawDataPresenter::Abort() {
122 success_ = false;
123 list_.reset();
124 }
125
126 void RawDataPresenter::FeedNextBytes(const std::vector<char>& bytes) {
127 list_->Append(
128 BinaryValue::CreateWithCopiedBuffer(&(bytes[0]), bytes.size()));
129 }
130
131 void RawDataPresenter::FeedNextFile(const std::string& filename) {
132 // Insert the file path instead of the contents, which may be too large.
133 list_->Append(Value::CreateStringValue(filename));
134 }
135
136 // Implementation of ParsedDataPresenter.
137
138 ParsedDataPresenter::ParsedDataPresenter(const net::URLRequest* request)
139 : parser_(FormDataParser::Create(request)),
140 success_(parser_.get() != NULL),
141 dictionary_(success_ ? new DictionaryValue() : NULL) {
142 }
143
144 ParsedDataPresenter::~ParsedDataPresenter() {}
145
146 void ParsedDataPresenter::FeedNext(const net::UploadData::Element& element) {
147 if (!success_)
148 return;
149
150 if (element.type() != net::UploadData::TYPE_BYTES) {
151 if (element.type() != net::UploadData::TYPE_FILE) {
152 Abort(); // We do not handle blobs nor chunks.
153 }
154 return; // But we just ignore files.
155 }
156 if (!parser_->SetSource(&(element.bytes()))) {
157 Abort();
158 return;
159 }
160
161 FormDataParser::Result result;
162 while (parser_->GetNextNameValue(&result)) {
163 GetOrCreateList(dictionary_.get(), result.name())->Append(
164 new StringValue(result.value()));
165 }
166 }
167
168 bool ParsedDataPresenter::Succeeded() {
169 if (success_ && !parser_->AllDataReadOK())
170 Abort();
171 return success_;
172 }
173
174 scoped_ptr<Value> ParsedDataPresenter::Result() {
175 if (success_)
176 return dictionary_.PassAs<Value>();
177 else
178 return scoped_ptr<Value>();
179 }
180
181 void ParsedDataPresenter::Abort() {
182 success_ = false;
183 dictionary_.reset();
184 parser_.reset();
185 }
186
187 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698