Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / web_request / upload_data_presenter.cc
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 "extensions/browser/api/web_request/upload_data_presenter.h"
6
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"
15
16 using base::BinaryValue;
17 using base::DictionaryValue;
18 using base::ListValue;
19 using base::StringValue;
20 using base::Value;
21
22 namespace keys = extension_web_request_api_constants;
23
24 namespace {
25
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);
34   }
35   return list;
36 }
37
38 }  // namespace
39
40 namespace extensions {
41
42 namespace subtle {
43
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);
50 }
51
52 }  // namespace subtle
53
54 UploadDataPresenter::~UploadDataPresenter() {}
55
56 RawDataPresenter::RawDataPresenter()
57   : success_(true),
58     list_(new base::ListValue) {
59 }
60 RawDataPresenter::~RawDataPresenter() {}
61
62 void RawDataPresenter::FeedNext(const net::UploadElementReader& reader) {
63   if (!success_)
64     return;
65
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();
75   }
76 }
77
78 bool RawDataPresenter::Succeeded() {
79   return success_;
80 }
81
82 scoped_ptr<base::Value> RawDataPresenter::Result() {
83   if (!success_)
84     return nullptr;
85
86   return list_.Pass();
87 }
88
89 void RawDataPresenter::FeedNextBytes(const char* bytes, size_t size) {
90   subtle::AppendKeyValuePair(keys::kRequestBodyRawBytesKey,
91                              BinaryValue::CreateWithCopiedBuffer(bytes, size),
92                              list_.get());
93 }
94
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());
100 }
101
102 ParsedDataPresenter::ParsedDataPresenter(const net::URLRequest& request)
103   : parser_(FormDataParser::Create(request)),
104     success_(parser_.get() != NULL),
105     dictionary_(success_ ? new base::DictionaryValue() : NULL) {
106 }
107
108 ParsedDataPresenter::~ParsedDataPresenter() {}
109
110 void ParsedDataPresenter::FeedNext(const net::UploadElementReader& reader) {
111   if (!success_)
112     return;
113
114   const net::UploadBytesElementReader* bytes_reader = reader.AsBytesReader();
115   if (!bytes_reader) {
116     return;
117   }
118   if (!parser_->SetSource(base::StringPiece(bytes_reader->bytes(),
119                                             bytes_reader->length()))) {
120     Abort();
121     return;
122   }
123
124   FormDataParser::Result result;
125   while (parser_->GetNextNameValue(&result)) {
126     GetOrCreateList(dictionary_.get(), result.name())->Append(
127         new base::StringValue(result.value()));
128   }
129 }
130
131 bool ParsedDataPresenter::Succeeded() {
132   if (success_ && !parser_->AllDataReadOK())
133     Abort();
134   return success_;
135 }
136
137 scoped_ptr<base::Value> ParsedDataPresenter::Result() {
138   if (!success_)
139     return nullptr;
140
141   return dictionary_.Pass();
142 }
143
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));
148 }
149
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) {
154 }
155
156 void ParsedDataPresenter::Abort() {
157   success_ = false;
158   dictionary_.reset();
159   parser_.reset();
160 }
161
162 }  // namespace extensions