2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * This file have been implemented in compliance with W3C WARP SPEC.
18 * but there are some patent issue between W3C WARP SPEC and APPLE.
19 * so if you want to use this file, refer to the README file in root directory
25 #include <dpl/utils/warp_iri.h>
26 #include <dpl/string.h>
27 #include <dpl/auto_ptr.h>
28 #include <dpl/foreach.h>
32 //#include <ValidatorCommon.h>
35 // All schemes which are supported by external application should be ignored
38 // Warp specification require from iri to have host element. File protocol
39 // does not contain host element so it's always denied by warp.
40 // Unfortunatly all widgets are using file protocol to load its data from
41 // hard drive. What's why we cannot check any iri with file schema.
43 const char *IRI_IGNORED_SCHEME[] = { "file://", "widget://", "tel:", "sms:",
44 "mmsto:", "mailto:", "data:", "blob:", 0 };
46 const DPL::String SCHEMA_HTTP = DPL::FromUTF8String("http");
47 const DPL::String SCHEMA_HTTPS = DPL::FromUTF8String("https");
48 const DPL::String SCHEMA_FTP = DPL::FromUTF8String("ftp");
49 } // namespace anonymous
51 // This will create AutoPtr deleter for iri_struct.
52 // Deleter must be in the same namespace as definition of AutoPtr.
55 DECLARE_DELETER(iri_struct, iri_destroy)
61 m_isAccessDefinition(false),
66 void WarpIRI::set(const char *p_iri,
70 m_isAccessDefinition = m_isIRIValid = false;
75 m_isAccessDefinition = true;
79 if (strcmp(p_iri, "*") == 0) {
83 DPL::AutoPtr<iri_struct> iri(iri_parse(p_iri));
86 LogError("Error in iri_parse!");
88 m_isAccessDefinition = false;
92 if (iri->scheme == NULL || iri->host == NULL) {
94 m_isAccessDefinition = false;
98 // all of this must be NULL in WARP definition
99 if (iri->user || iri->path || iri->query || iri->anchor) {
100 m_isAccessDefinition = false;
103 m_schema = DPL::FromASCIIString(std::string(iri->scheme));
104 m_port = static_cast<unsigned int>(iri->port);
107 m_port = getPort(m_schema);
108 if (m_port == UNKNOWN_PORT) {
109 m_isAccessDefinition = false;
114 DPL::String str = DPL::FromASCIIString(std::string(iri->host));
116 std::string utf8host = iri->host;
117 std::list<std::string> hostTokenList;
118 DPL::Tokenize(utf8host, ".", std::front_inserter(hostTokenList));
120 if (SCHEMA_HTTP == m_schema || SCHEMA_HTTPS == m_schema) {
121 FOREACH(i, hostTokenList) {
123 int rc = idna_to_ascii_8z(i->c_str(),
125 IDNA_USE_STD3_ASCII_RULES);
127 if (IDNA_SUCCESS != rc) {
128 LogWarning("libidn error: " << rc << " " <<
129 idna_strerror((Idna_rc)rc));
130 m_isIRIValid = false;
131 m_isAccessDefinition = false;
133 std::string token(output);
134 std::transform(token.begin(),
138 m_host.push_back(DPL::FromUTF8String(token));
143 FOREACH(i, hostTokenList){
144 m_host.push_back(DPL::FromUTF8String(*i));
149 void WarpIRI::set(const DPL::String &iristring,
152 set(DPL::ToUTF8String(iristring).c_str(), domain);
155 unsigned int WarpIRI::getPort(const DPL::String &schema) const
157 unsigned int port = UNKNOWN_PORT;
158 if (schema == SCHEMA_HTTP) {
160 } else if (schema == SCHEMA_HTTPS) {
162 } else if (schema == SCHEMA_FTP) {
168 bool WarpIRI::isSubDomain(const WarpIRI &second) const
170 if (!m_isAccessDefinition || !second.m_isIRIValid) { return false; }
171 if (m_schema != second.m_schema) { return false; }
172 if (m_port != second.m_port) { return false; }
174 size_t size = m_host.size() < second.m_host.size() ?
175 m_host.size() : second.m_host.size();
177 if (m_host.size() > second.m_host.size()) {
181 if (!m_domain && (m_host.size() != second.m_host.size())) {
185 for (size_t i = 0; i < size; ++i) {
186 if (DPL::StringCompare(m_host[i], second.m_host[i])) {
193 bool WarpIRI::isAccessDefinition() const
195 return m_isAccessDefinition;
198 bool WarpIRI::getSubDomain() const
203 bool WarpIRI::isIRISchemaIgnored(const char *iri)
205 for (int i = 0; IRI_IGNORED_SCHEME[i]; ++i) {
207 strncmp(iri, IRI_IGNORED_SCHEME[i],
208 strlen(IRI_IGNORED_SCHEME[i]))) {