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 scoped_ptr<Value>(); |
| 142 |
| 143 return dictionary_.PassAs<Value>(); |
| 144 } |
| 145 |
| 146 void ParsedDataPresenter::Abort() { |
| 147 success_ = false; |
| 148 dictionary_.reset(); |
| 149 parser_.reset(); |
| 150 } |
| 151 |
| 152 } // namespace extensions |
OLD | NEW |