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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/custom_handlers/protocol_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandler::ProtocolHandler(const std::string& protocol,
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 const GURL& url)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : protocol_(protocol),
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url_(url) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandler ProtocolHandler::CreateProtocolHandler(
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& protocol,
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& url) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string lower_protocol = StringToLowerASCII(protocol);
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return ProtocolHandler(lower_protocol, url);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandler::ProtocolHandler() {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProtocolHandler::IsValidDict(const base::DictionaryValue* value) {
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Note that "title" parameter is ignored.
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return value->HasKey("protocol") && value->HasKey("url");
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandler::IsSameOrigin(
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProtocolHandler& handler) const {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handler.url().GetOrigin() == url_.GetOrigin();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProtocolHandler& ProtocolHandler::EmptyProtocolHandler() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const ProtocolHandler* const kEmpty = new ProtocolHandler();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *kEmpty;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandler ProtocolHandler::CreateProtocolHandler(
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::DictionaryValue* value) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsValidDict(value)) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return EmptyProtocolHandler();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string protocol, url;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  value->GetString("protocol", &protocol);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  value->GetString("url", &url);
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return ProtocolHandler::CreateProtocolHandler(protocol, GURL(url));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ProtocolHandler::TranslateUrl(const GURL& url) const {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string translatedUrlSpec(url_.spec());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReplaceSubstringsAfterOffset(&translatedUrlSpec, 0, "%s",
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::EscapeQueryParamValue(url.spec(), true));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL(translatedUrlSpec);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* ProtocolHandler::Encode() const {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue* d = new base::DictionaryValue();
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  d->Set("protocol", new base::StringValue(protocol_));
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  d->Set("url", new base::StringValue(url_.spec()));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return d;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(NDEBUG)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProtocolHandler::ToString() const {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "{ protocol=" + protocol_ +
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ", url=" + url_.spec() +
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         " }";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandler::operator==(const ProtocolHandler& other) const {
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return protocol_ == other.protocol_ && url_ == other.url_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandler::IsEquivalent(const ProtocolHandler& other) const {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return protocol_ == other.protocol_ && url_ == other.url_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandler::operator<(const ProtocolHandler& other) const {
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return url_ < other.url_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87