OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "core/loader/LinkHeader.h" | |
7 | |
8 #include "platform/ParsingUtilities.h" | |
9 | |
10 namespace blink { | |
11 | |
12 // LWSP definition in https://www.ietf.org/rfc/rfc0822.txt | |
13 template <typename CharType> | |
14 static bool isWhitespace(CharType chr) | |
15 { | |
16 return (chr == ' ') || (chr == '\t'); | |
17 } | |
18 | |
19 template <typename CharType> | |
20 static bool isValidURLChar(CharType chr) | |
21 { | |
22 return !isWhitespace(chr) && chr != '>'; | |
23 } | |
24 | |
25 template <typename CharType> | |
26 static bool isValidParameterNameChar(CharType chr) | |
27 { | |
28 return !isWhitespace(chr) && chr != '='; | |
29 } | |
30 | |
31 template <typename CharType> | |
32 static bool isValidParameterValueChar(CharType chr) | |
33 { | |
34 return !isWhitespace(chr) && chr != ';'; | |
35 } | |
36 | |
37 // Before: | |
38 // | |
39 // <cat.jpg>; rel=preload | |
40 // ^ ^ | |
41 // position end | |
42 // | |
43 // After (if successful: otherwise the method returns false) | |
44 // | |
45 // <cat.jpg>; rel=preload | |
46 // ^ ^ | |
47 // position end | |
48 template <typename CharType> | |
49 static bool parseURL(CharType*& position, CharType* end, String& url) | |
50 { | |
51 skipWhile<CharType, isWhitespace>(position, end); | |
52 if (!skipExactly<CharType>(position, end, '<')) | |
53 return false; | |
54 skipWhile<CharType, isWhitespace>(position, end); | |
55 | |
56 CharType* urlStart = position; | |
57 skipWhile<CharType, isValidURLChar>(position, end); | |
58 CharType* urlEnd = position; | |
59 skipUntil<CharType>(position, end, '>'); | |
60 if (!skipExactly<CharType>(position, end, '>')) | |
61 return false; | |
62 | |
63 url = String(urlStart, urlEnd - urlStart); | |
64 return true; | |
65 } | |
66 | |
67 // Before: | |
68 // | |
69 // <cat.jpg>; rel=preload | |
70 // ^ ^ | |
71 // position end | |
72 // | |
73 // After (if successful: otherwise the method returns false, and modifies the is
Valid boolean accordingly) | |
74 // | |
75 // <cat.jpg>; rel=preload | |
76 // ^ ^ | |
77 // position end | |
78 template <typename CharType> | |
79 static bool parseParameterDelimiter(CharType*& position, CharType* end, bool& is
ValidDelimiter) | |
80 { | |
81 isValidDelimiter = true; | |
82 skipWhile<CharType, isWhitespace>(position, end); | |
83 if (!skipExactly<CharType>(position, end, ';') && (position < end)) { | |
84 isValidDelimiter = false; | |
85 return false; | |
86 } | |
87 skipWhile<CharType, isWhitespace>(position, end); | |
88 if (position == end) | |
89 return false; | |
90 return true; | |
91 } | |
92 | |
93 static LinkHeader::LinkParameterName paramterNameFromString(String name) | |
94 { | |
95 // FIXME: Add support for more header parameters as neccessary. | |
96 if (name == "rel") | |
97 return LinkHeader::LinkParameterRel; | |
98 return LinkHeader::LinkParameterUnknown; | |
99 } | |
100 | |
101 // Before: | |
102 // | |
103 // <cat.jpg>; rel=preload | |
104 // ^ ^ | |
105 // position end | |
106 // | |
107 // After (if successful: otherwise the method returns false) | |
108 // | |
109 // <cat.jpg>; rel=preload | |
110 // ^ ^ | |
111 // position end | |
112 template <typename CharType> | |
113 static bool parseParameterName(CharType*& position, CharType* end, LinkHeader::L
inkParameterName& name) | |
114 { | |
115 CharType* nameStart = position; | |
116 skipWhile<CharType, isValidParameterNameChar>(position, end); | |
117 CharType* nameEnd = position; | |
118 skipWhile<CharType, isWhitespace>(position, end); | |
119 if (!skipExactly<CharType>(position, end, '=')) | |
120 return false; | |
121 skipWhile<CharType, isWhitespace>(position, end); | |
122 name = paramterNameFromString(String(nameStart, nameEnd - nameStart)); | |
123 return true; | |
124 } | |
125 | |
126 // Before: | |
127 // | |
128 // <cat.jpg>; rel=preload; foo=bar | |
129 // ^ ^ | |
130 // position end | |
131 // | |
132 // After (if successful: otherwise the method returns false) | |
133 // | |
134 // <cat.jpg>; rel=preload; foo=bar | |
135 // ^ ^ | |
136 // position end | |
137 template <typename CharType> | |
138 static bool parseParameterValue(CharType*& position, CharType* end, String& valu
e) | |
139 { | |
140 CharType* valueStart = position; | |
141 skipWhile<CharType, isValidParameterValueChar>(position, end); | |
142 CharType* valueEnd = position; | |
143 skipWhile<CharType, isWhitespace>(position, end); | |
144 if ((valueEnd == valueStart) || (*position != ';' && position != end)) | |
145 return false; | |
146 value = String(valueStart, valueEnd - valueStart); | |
147 return true; | |
148 } | |
149 | |
150 void LinkHeader::setValue(LinkParameterName name, String value) | |
151 { | |
152 // FIXME: Add support for more header parameters as neccessary. | |
153 if (name == LinkParameterRel) | |
154 m_rel = value; | |
155 } | |
156 | |
157 template <typename CharType> | |
158 bool LinkHeader::init(CharType* headerValue, unsigned len) | |
159 { | |
160 CharType* position = headerValue; | |
161 CharType* end = headerValue + len; | |
162 | |
163 if (!parseURL(position, end, m_url)) | |
164 return false; | |
165 | |
166 while (position < end) { | |
167 bool isValidDelimiter; | |
168 if (!parseParameterDelimiter(position, end, isValidDelimiter)) | |
169 return isValidDelimiter; | |
170 | |
171 LinkParameterName parameterName; | |
172 if (!parseParameterName(position, end, parameterName)) | |
173 return false; | |
174 | |
175 String parameterValue; | |
176 if (!parseParameterValue(position, end, parameterValue)) | |
177 return false; | |
178 | |
179 setValue(parameterName, parameterValue); | |
180 } | |
181 | |
182 return true; | |
183 } | |
184 | |
185 LinkHeader::LinkHeader(const String& header) | |
186 { | |
187 if (header.isNull()) { | |
188 m_isValid = false; | |
189 return; | |
190 } | |
191 | |
192 if (header.is8Bit()) | |
193 m_isValid = init(header.characters8(), header.length()); | |
194 else | |
195 m_isValid = init(header.characters16(), header.length()); | |
196 } | |
197 | |
198 } | |
OLD | NEW |