Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / api / web_request / upload_data_presenter.cc
blob4c5e1008cda3be7011f074531739486cfc2875ba
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.
5 #include "extensions/browser/api/web_request/upload_data_presenter.h"
7 #include "base/files/file_path.h"
8 #include "base/strings/string_util.h"
9 #include "base/values.h"
10 #include "extensions/browser/api/web_request/form_data_parser.h"
11 #include "extensions/browser/api/web_request/web_request_api_constants.h"
12 #include "net/base/upload_bytes_element_reader.h"
13 #include "net/base/upload_file_element_reader.h"
14 #include "net/url_request/url_request.h"
16 using base::BinaryValue;
17 using base::DictionaryValue;
18 using base::ListValue;
19 using base::StringValue;
20 using base::Value;
22 namespace keys = extension_web_request_api_constants;
24 namespace {
26 // Takes |dictionary| of <string, list of strings> pairs, and gets the list
27 // for |key|, creating it if necessary.
28 base::ListValue* GetOrCreateList(base::DictionaryValue* dictionary,
29 const std::string& key) {
30 base::ListValue* list = NULL;
31 if (!dictionary->GetList(key, &list)) {
32 list = new base::ListValue();
33 dictionary->SetWithoutPathExpansion(key, list);
35 return list;
38 } // namespace
40 namespace extensions {
42 namespace subtle {
44 void AppendKeyValuePair(const char* key,
45 base::Value* value,
46 base::ListValue* list) {
47 base::DictionaryValue* dictionary = new base::DictionaryValue;
48 dictionary->SetWithoutPathExpansion(key, value);
49 list->Append(dictionary);
52 } // namespace subtle
54 UploadDataPresenter::~UploadDataPresenter() {}
56 RawDataPresenter::RawDataPresenter()
57 : success_(true),
58 list_(new base::ListValue) {
60 RawDataPresenter::~RawDataPresenter() {}
62 void RawDataPresenter::FeedNext(const net::UploadElementReader& reader) {
63 if (!success_)
64 return;
66 if (reader.AsBytesReader()) {
67 const net::UploadBytesElementReader* bytes_reader = reader.AsBytesReader();
68 FeedNextBytes(bytes_reader->bytes(), bytes_reader->length());
69 } else if (reader.AsFileReader()) {
70 // Insert the file path instead of the contents, which may be too large.
71 const net::UploadFileElementReader* file_reader = reader.AsFileReader();
72 FeedNextFile(file_reader->path().AsUTF8Unsafe());
73 } else {
74 NOTIMPLEMENTED();
78 bool RawDataPresenter::Succeeded() {
79 return success_;
82 scoped_ptr<base::Value> RawDataPresenter::Result() {
83 if (!success_)
84 return nullptr;
86 return list_.Pass();
89 void RawDataPresenter::FeedNextBytes(const char* bytes, size_t size) {
90 subtle::AppendKeyValuePair(keys::kRequestBodyRawBytesKey,
91 BinaryValue::CreateWithCopiedBuffer(bytes, size),
92 list_.get());
95 void RawDataPresenter::FeedNextFile(const std::string& filename) {
96 // Insert the file path instead of the contents, which may be too large.
97 subtle::AppendKeyValuePair(keys::kRequestBodyRawFileKey,
98 new base::StringValue(filename),
99 list_.get());
102 ParsedDataPresenter::ParsedDataPresenter(const net::URLRequest& request)
103 : parser_(FormDataParser::Create(request)),
104 success_(parser_.get() != NULL),
105 dictionary_(success_ ? new base::DictionaryValue() : NULL) {
108 ParsedDataPresenter::~ParsedDataPresenter() {}
110 void ParsedDataPresenter::FeedNext(const net::UploadElementReader& reader) {
111 if (!success_)
112 return;
114 const net::UploadBytesElementReader* bytes_reader = reader.AsBytesReader();
115 if (!bytes_reader) {
116 return;
118 if (!parser_->SetSource(base::StringPiece(bytes_reader->bytes(),
119 bytes_reader->length()))) {
120 Abort();
121 return;
124 FormDataParser::Result result;
125 while (parser_->GetNextNameValue(&result)) {
126 GetOrCreateList(dictionary_.get(), result.name())->Append(
127 new base::StringValue(result.value()));
131 bool ParsedDataPresenter::Succeeded() {
132 if (success_ && !parser_->AllDataReadOK())
133 Abort();
134 return success_;
137 scoped_ptr<base::Value> ParsedDataPresenter::Result() {
138 if (!success_)
139 return nullptr;
141 return dictionary_.Pass();
144 // static
145 scoped_ptr<ParsedDataPresenter> ParsedDataPresenter::CreateForTests() {
146 const std::string form_type("application/x-www-form-urlencoded");
147 return scoped_ptr<ParsedDataPresenter>(new ParsedDataPresenter(form_type));
150 ParsedDataPresenter::ParsedDataPresenter(const std::string& form_type)
151 : parser_(FormDataParser::CreateFromContentTypeHeader(&form_type)),
152 success_(parser_.get() != NULL),
153 dictionary_(success_ ? new base::DictionaryValue() : NULL) {
156 void ParsedDataPresenter::Abort() {
157 success_ = false;
158 dictionary_.reset();
159 parser_.reset();
162 } // namespace extensions