1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace keys = extensions::manifest_keys;
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = extensions::manifest_errors;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* const kMIMETypeHandlersWhitelist[] = {
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    extension_misc::kPdfExtensionId,
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    extension_misc::kQuickOfficeComponentExtensionId,
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    extension_misc::kQuickOfficeInternalExtensionId,
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    extension_misc::kQuickOfficeExtensionId,
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    extension_misc::kStreamsPrivateTestExtensionId};
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stored on the Extension.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct MimeTypesHandlerInfo : public extensions::Extension::ManifestData {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MimeTypesHandler handler_;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MimeTypesHandlerInfo();
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MimeTypesHandlerInfo();
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MimeTypesHandlerInfo::MimeTypesHandlerInfo() {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MimeTypesHandlerInfo::~MimeTypesHandlerInfo() {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<std::string> MimeTypesHandler::GetMIMETypeWhitelist() {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> whitelist;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kMIMETypeHandlersWhitelist); ++i)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    whitelist.push_back(kMIMETypeHandlersWhitelist[i]);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return whitelist;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MimeTypesHandler::MimeTypesHandler() {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MimeTypesHandler::~MimeTypesHandler() {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MimeTypesHandler::AddMIMEType(const std::string& mime_type) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mime_type_set_.insert(mime_type);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MimeTypesHandler::CanHandleMIMEType(const std::string& mime_type) const {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return mime_type_set_.find(mime_type) != mime_type_set_.end();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MimeTypesHandler* MimeTypesHandler::GetHandler(
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension* extension) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MimeTypesHandlerInfo* info = static_cast<MimeTypesHandlerInfo*>(
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension->GetManifestData(keys::kMimeTypesHandler));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (info)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &info->handler_;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MimeTypesHandlerParser::MimeTypesHandlerParser() {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MimeTypesHandlerParser::~MimeTypesHandlerParser() {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MimeTypesHandlerParser::Parse(extensions::Extension* extension,
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   base::string16* error) {
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const base::ListValue* mime_types_value = NULL;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!extension->manifest()->GetList(keys::kMIMETypes,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      &mime_types_value)) {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidMimeTypesHandler);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<MimeTypesHandlerInfo> info(new MimeTypesHandlerInfo);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info->handler_.set_extension_id(extension->id());
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < mime_types_value->GetSize(); ++i) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string filter;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!mime_types_value->GetString(i, &filter)) {
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidMIMETypes);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->handler_.AddMIMEType(filter);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::string mime_types_handler;
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (extension->manifest()->GetString(keys::kMimeTypesHandler,
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                       &mime_types_handler)) {
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    info->handler_.set_handler_url(mime_types_handler);
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extension->SetManifestData(keys::kMimeTypesHandler, info.release());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::vector<std::string> MimeTypesHandlerParser::Keys() const {
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::vector<std::string> keys;
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  keys.push_back(keys::kMIMETypes);
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  keys.push_back(keys::kMimeTypesHandler);
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return keys;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
118