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
;
22 namespace keys
= extension_web_request_api_constants
;
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
);
40 namespace extensions
{
44 void AppendKeyValuePair(const char* key
,
46 base::ListValue
* list
) {
47 base::DictionaryValue
* dictionary
= new base::DictionaryValue
;
48 dictionary
->SetWithoutPathExpansion(key
, value
);
49 list
->Append(dictionary
);
54 UploadDataPresenter::~UploadDataPresenter() {}
56 RawDataPresenter::RawDataPresenter()
58 list_(new base::ListValue
) {
60 RawDataPresenter::~RawDataPresenter() {}
62 void RawDataPresenter::FeedNext(const net::UploadElementReader
& reader
) {
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());
78 bool RawDataPresenter::Succeeded() {
82 scoped_ptr
<base::Value
> RawDataPresenter::Result() {
89 void RawDataPresenter::FeedNextBytes(const char* bytes
, size_t size
) {
90 subtle::AppendKeyValuePair(keys::kRequestBodyRawBytesKey
,
91 BinaryValue::CreateWithCopiedBuffer(bytes
, size
),
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
),
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
) {
114 const net::UploadBytesElementReader
* bytes_reader
= reader
.AsBytesReader();
118 if (!parser_
->SetSource(base::StringPiece(bytes_reader
->bytes(),
119 bytes_reader
->length()))) {
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())
137 scoped_ptr
<base::Value
> ParsedDataPresenter::Result() {
141 return dictionary_
.Pass();
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() {
162 } // namespace extensions