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 #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 "chrome/browser/extensions/api/web_request/web_request_api_constants.h" | |
12 #include "net/base/upload_element.h" | |
13 #include "net/url_request/url_request.h" | |
14 | |
15 using base::BinaryValue; | |
16 using base::DictionaryValue; | |
17 using base::ListValue; | |
18 using base::StringValue; | |
19 using base::Value; | |
20 | |
21 namespace keys = extension_web_request_api_constants; | |
22 | |
23 namespace { | |
24 | |
25 // Takes |dictionary| of <string, list of strings> pairs, and gets the list | |
26 // for |key|, creating it if necessary. | |
27 ListValue* GetOrCreateList(DictionaryValue* dictionary, | |
28 const std::string& key) { | |
29 ListValue* list = NULL; | |
30 if (!dictionary->GetList(key, &list)) { | |
31 list = new ListValue(); | |
32 dictionary->Set(key, list); | |
33 } | |
34 return list; | |
35 } | |
36 | |
37 } // namespace | |
38 | |
39 namespace extensions { | |
40 | |
41 // Implementation of UploadDataPresenter. | |
42 | |
43 UploadDataPresenter::~UploadDataPresenter() {} | |
44 | |
45 // Implementation of RawDataPresenter. | |
46 | |
47 RawDataPresenter::RawDataPresenter() | |
48 : success_(true), | |
49 list_(new base::ListValue) { | |
50 } | |
51 RawDataPresenter::~RawDataPresenter() {} | |
52 | |
53 void RawDataPresenter::FeedNext(const net::UploadElement& element) { | |
54 if (!success_) | |
55 return; | |
56 | |
57 switch (element.type()) { | |
58 case net::UploadElement::TYPE_BYTES: | |
59 FeedNextBytes(element.bytes(), element.bytes_length()); | |
60 break; | |
61 case net::UploadElement::TYPE_FILE: | |
62 // Insert the file path instead of the contents, which may be too large. | |
63 FeedNextFile(element.file_path().AsUTF8Unsafe()); | |
64 break; | |
65 } | |
66 } | |
67 | |
68 bool RawDataPresenter::Succeeded() { | |
69 return success_; | |
70 } | |
71 | |
72 scoped_ptr<Value> RawDataPresenter::Result() { | |
73 if (!success_) | |
74 return scoped_ptr<Value>(); | |
75 | |
76 return list_.PassAs<Value>(); | |
77 } | |
78 | |
79 // static | |
80 void RawDataPresenter::AppendResultWithKey( | |
81 ListValue* list, const char* key, Value* value) { | |
82 DictionaryValue* dictionary = new DictionaryValue; | |
83 dictionary->Set(key, value); | |
84 list->Append(dictionary); | |
85 } | |
86 | |
87 void RawDataPresenter::Abort() { | |
88 success_ = false; | |
89 list_.reset(); | |
90 } | |
91 | |
92 void RawDataPresenter::FeedNextBytes(const char* bytes, size_t size) { | |
93 AppendResultWithKey(list_.get(), keys::kRequestBodyRawBytesKey, | |
94 BinaryValue::CreateWithCopiedBuffer(bytes, size)); | |
95 } | |
96 | |
97 void RawDataPresenter::FeedNextFile(const std::string& filename) { | |
98 // Insert the file path instead of the contents, which may be too large. | |
99 AppendResultWithKey(list_.get(), keys::kRequestBodyRawFileKey, | |
100 Value::CreateStringValue(filename)); | |
101 } | |
102 | |
103 // Implementation of ParsedDataPresenter. | |
104 | |
105 ParsedDataPresenter::ParsedDataPresenter(const net::URLRequest* request) | |
106 : parser_(FormDataParser::Create(request)), | |
107 success_(parser_.get() != NULL), | |
108 dictionary_(success_ ? new DictionaryValue() : NULL) { | |
109 } | |
110 | |
111 ParsedDataPresenter::~ParsedDataPresenter() {} | |
112 | |
113 void ParsedDataPresenter::FeedNext(const net::UploadElement& element) { | |
114 if (!success_) | |
115 return; | |
116 | |
117 if (element.type() != net::UploadElement::TYPE_BYTES) { | |
118 return; | |
119 } | |
120 if (!parser_->SetSource(base::StringPiece(element.bytes(), | |
121 element.bytes_length()))) { | |
122 Abort(); | |
123 return; | |
124 } | |
125 | |
126 FormDataParser::Result result; | |
127 while (parser_->GetNextNameValue(&result)) { | |
128 GetOrCreateList(dictionary_.get(), result.name())->Append( | |
129 new StringValue(result.value())); | |
130 } | |
131 } | |
132 | |
133 bool ParsedDataPresenter::Succeeded() { | |
134 if (success_ && !parser_->AllDataReadOK()) | |
135 Abort(); | |
136 return success_; | |
137 } | |
138 | |
139 scoped_ptr<Value> ParsedDataPresenter::Result() { | |
140 if (success_) | |
141 return dictionary_.PassAs<Value>(); | |
142 else | |
143 return scoped_ptr<Value>(); | |
battre
2012/09/09 22:08:35
Style guide says not to have return in else branch
vabr (Chromium)
2012/09/12 11:18:08
Done.
Thanks for pointing me to the style guide he
| |
144 } | |
145 | |
146 void ParsedDataPresenter::Abort() { | |
147 success_ = false; | |
148 dictionary_.reset(); | |
149 parser_.reset(); | |
150 } | |
151 | |
152 } // namespace extensions | |
OLD | NEW |