15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/upload_data_presenter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/form_data_parser.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_api_constants.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_file_element_reader.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::BinaryValue;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::DictionaryValue;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::ListValue;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringValue;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Value;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extension_web_request_api_constants;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes |dictionary| of <string, list of strings> pairs, and gets the list
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for |key|, creating it if necessary.
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::ListValue* GetOrCreateList(base::DictionaryValue* dictionary,
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 const std::string& key) {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* list = NULL;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dictionary->GetList(key, &list)) {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    list = new base::ListValue();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dictionary->SetWithoutPathExpansion(key, list);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return list;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace subtle {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppendKeyValuePair(const char* key,
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        base::Value* value,
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        base::ListValue* list) {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* dictionary = new base::DictionaryValue;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary->SetWithoutPathExpansion(key, value);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list->Append(dictionary);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace subtle
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UploadDataPresenter::~UploadDataPresenter() {}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RawDataPresenter::RawDataPresenter()
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : success_(true),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list_(new base::ListValue) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RawDataPresenter::~RawDataPresenter() {}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RawDataPresenter::FeedNext(const net::UploadElementReader& reader) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success_)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (reader.AsBytesReader()) {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const net::UploadBytesElementReader* bytes_reader = reader.AsBytesReader();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FeedNextBytes(bytes_reader->bytes(), bytes_reader->length());
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (reader.AsFileReader()) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Insert the file path instead of the contents, which may be too large.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const net::UploadFileElementReader* file_reader = reader.AsFileReader();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FeedNextFile(file_reader->path().AsUTF8Unsafe());
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTIMPLEMENTED();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RawDataPresenter::Succeeded() {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<base::Value> RawDataPresenter::Result() {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success_)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return scoped_ptr<base::Value>();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return list_.PassAs<base::Value>();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RawDataPresenter::FeedNextBytes(const char* bytes, size_t size) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subtle::AppendKeyValuePair(keys::kRequestBodyRawBytesKey,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             BinaryValue::CreateWithCopiedBuffer(bytes, size),
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             list_.get());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RawDataPresenter::FeedNextFile(const std::string& filename) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Insert the file path instead of the contents, which may be too large.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subtle::AppendKeyValuePair(keys::kRequestBodyRawFileKey,
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             new base::StringValue(filename),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             list_.get());
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ParsedDataPresenter::ParsedDataPresenter(const net::URLRequest& request)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : parser_(FormDataParser::Create(request)),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success_(parser_.get() != NULL),
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dictionary_(success_ ? new base::DictionaryValue() : NULL) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ParsedDataPresenter::~ParsedDataPresenter() {}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParsedDataPresenter::FeedNext(const net::UploadElementReader& reader) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success_)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const net::UploadBytesElementReader* bytes_reader = reader.AsBytesReader();
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!bytes_reader) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!parser_->SetSource(base::StringPiece(bytes_reader->bytes(),
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            bytes_reader->length()))) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Abort();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FormDataParser::Result result;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (parser_->GetNextNameValue(&result)) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetOrCreateList(dictionary_.get(), result.name())->Append(
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new base::StringValue(result.value()));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsedDataPresenter::Succeeded() {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (success_ && !parser_->AllDataReadOK())
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Abort();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<base::Value> ParsedDataPresenter::Result() {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success_)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return scoped_ptr<base::Value>();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return dictionary_.PassAs<base::Value>();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<ParsedDataPresenter> ParsedDataPresenter::CreateForTests() {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string form_type("application/x-www-form-urlencoded");
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_ptr<ParsedDataPresenter>(new ParsedDataPresenter(form_type));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ParsedDataPresenter::ParsedDataPresenter(const std::string& form_type)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : parser_(FormDataParser::CreateFromContentTypeHeader(&form_type)),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success_(parser_.get() != NULL),
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dictionary_(success_ ? new base::DictionaryValue() : NULL) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ParsedDataPresenter::Abort() {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  success_ = false;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary_.reset();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parser_.reset();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
163