SecurityOrigin.cpp [plain text]
#include "config.h"
#include "SecurityOrigin.h"
#include "Document.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameTree.h"
#include "KURL.h"
#include "PlatformString.h"
namespace WebCore {
static bool isDefaultPortForProtocol(unsigned short port, String protocol)
{
if (protocol.isEmpty())
return false;
static HashMap<String, unsigned> defaultPorts;
if (defaultPorts.isEmpty()) {
defaultPorts.set("http", 80);
defaultPorts.set("https", 443);
defaultPorts.set("ftp", 21);
defaultPorts.set("ftps", 990);
}
return defaultPorts.get(protocol) == port;
}
SecurityOrigin::SecurityOrigin(const String& protocol, const String& host, unsigned short port)
: m_protocol(protocol.isNull() ? "" : protocol.lower())
, m_host(host.isNull() ? "" : host.lower())
, m_port(port)
, m_portSet(port)
, m_noAccess(false)
, m_domainWasSetInDOM(false)
{
if (m_protocol == "about" || m_protocol == "javascript")
m_protocol = "";
if (m_protocol == "data")
m_noAccess = true;
if (isDefaultPortForProtocol(m_port, m_protocol)) {
m_port = 0;
m_portSet = false;
}
}
bool SecurityOrigin::isEmpty() const
{
return m_protocol.isEmpty();
}
PassRefPtr<SecurityOrigin> SecurityOrigin::create(const String& protocol, const String& host, unsigned short port, SecurityOrigin* ownerFrameOrigin)
{
RefPtr<SecurityOrigin> origin = new SecurityOrigin(protocol, host, port);
if (origin->isEmpty() && ownerFrameOrigin)
return ownerFrameOrigin;
return origin.release();
}
PassRefPtr<SecurityOrigin> SecurityOrigin::createForFrame(Frame* frame)
{
if (!frame)
return create("", "", 0, 0);
FrameLoader* loader = frame->loader();
KURL url = loader->url();
Frame* ownerFrame = frame->tree()->parent();
if (!ownerFrame)
ownerFrame = loader->opener();
SecurityOrigin* ownerFrameOrigin = 0;
if (ownerFrame && ownerFrame->document())
ownerFrameOrigin = ownerFrame->document()->securityOrigin();
return create(url.protocol(), url.host(), url.port(), ownerFrameOrigin);
}
PassRefPtr<SecurityOrigin> SecurityOrigin::copy()
{
return create(m_protocol.copy(), m_host.copy(), m_port, 0);
}
void SecurityOrigin::setDomainFromDOM(const String& newDomain)
{
m_domainWasSetInDOM = true;
m_host = newDomain.lower();
}
bool SecurityOrigin::canAccess(const SecurityOrigin* other, Reason& reason) const
{
if (FrameLoader::shouldTreatSchemeAsLocal(m_protocol))
return true;
if (m_noAccess || other->m_noAccess) {
reason = SecurityOrigin::GenericMismatch;
return false;
}
if (m_protocol == other->m_protocol) {
if (!m_domainWasSetInDOM && !other->m_domainWasSetInDOM) {
if (m_host == other->m_host && m_port == other->m_port)
return true;
} else if (m_domainWasSetInDOM && other->m_domainWasSetInDOM) {
if (m_host == other->m_host)
return true;
} else {
if (m_host == other->m_host && m_port == other->m_port) {
reason = DomainSetInDOMMismatch;
return false;
}
}
}
reason = SecurityOrigin::GenericMismatch;
return false;
}
bool SecurityOrigin::isSecureTransitionTo(const KURL& url) const
{
if (isEmpty())
return true;
if (FrameLoader::shouldTreatSchemeAsLocal(m_protocol))
return true;
return equalIgnoringCase(m_host, String(url.host())) && equalIgnoringCase(m_protocol, String(url.protocol())) && m_port == url.port();
}
String SecurityOrigin::toString() const
{
return m_protocol + ":" + m_host + ":" + String::number(m_port);
}
static const char SeparatorCharacter = '_';
PassRefPtr<SecurityOrigin> SecurityOrigin::createFromIdentifier(const String& stringIdentifier)
{
int separator1 = stringIdentifier.find(SeparatorCharacter);
if (separator1 == -1)
return create("", "", 0, 0);
int separator2 = stringIdentifier.find(SeparatorCharacter, separator1 + 1);
if (separator2 == -1)
return create("", "", 0, 0);
if (stringIdentifier.reverseFind(SeparatorCharacter) != separator2)
return create("", "", 0, 0);
bool portOkay;
int port = stringIdentifier.right(stringIdentifier.length() - separator2 - 1).toInt(&portOkay);
if (!portOkay && separator2 + 1 == static_cast<int>(stringIdentifier.length()))
return create("", "", 0, 0);
if (port < 0 || port > 65535)
return create("", "", 0, 0);
String protocol = stringIdentifier.substring(0, separator1);
String host = stringIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
return create(protocol, host, port, 0);
}
String SecurityOrigin::stringIdentifier() const
{
static String separatorString = String(&SeparatorCharacter, 1);
return m_protocol + separatorString + m_host + separatorString + String::number(m_port);
}
}