| 173 | } |
| 174 | |
| 175 | bool UrlParser::ParseUrlKey(const StringValue& url, UrlPart part, |
| 176 | const StringValue& key, StringValue* result) { |
| 177 | // Part must be query to ask for a specific query key. |
| 178 | if (part != QUERY) { |
| 179 | return false; |
| 180 | } |
| 181 | // Remove leading and trailing spaces. |
| 182 | StringValue trimmed_url = url.Trim(); |
| 183 | |
| 184 | // Search for the key in the url, ignoring malformed URLs for now. |
| 185 | StringSearch key_search(&key); |
| 186 | while(trimmed_url.Len() > 0) { |
| 187 | // Search for the key in the current substring. |
| 188 | int32_t key_pos = key_search.Search(&trimmed_url); |
| 189 | bool match = true; |
| 190 | if (key_pos < 0) { |
| 191 | return false; |
| 192 | } |
| 193 | // Key pos must be != 0 because it must be preceded by a '?' or a '&'. |
| 194 | // Check that the char before key_pos is either '?' or '&'. |
| 195 | if (key_pos == 0 || |
| 196 | (trimmed_url.Ptr()[key_pos - 1] != '?' && |
| 197 | trimmed_url.Ptr()[key_pos - 1] != '&')) { |
| 198 | match = false; |
| 199 | } |
| 200 | // Advance substring beyond matching key. |
| 201 | trimmed_url = trimmed_url.Substring(key_pos + key.Len()); |
| 202 | if (!match) { |
| 203 | continue; |
| 204 | } |
| 205 | if (trimmed_url.Len() <= 0) { |
| 206 | break; |
| 207 | } |
| 208 | // Next character must be '=', otherwise the match cannot be a key in the query part. |
| 209 | if (trimmed_url.Ptr()[0] != '=') { |
| 210 | continue; |
| 211 | } |
| 212 | int32_t pos = 1; |
| 213 | // Find ending position of key's value by matching '#' or '&'. |
| 214 | while(pos < trimmed_url.Len()) { |
| 215 | switch(trimmed_url.Ptr()[pos]) { |
| 216 | case '#': |
| 217 | case '&': |
| 218 | *result = trimmed_url.Substring(1, pos - 1); |
| 219 | return true; |
| 220 | } |
| 221 | ++pos; |
| 222 | } |
| 223 | // Ending position is end of string. |
| 224 | *result = trimmed_url.Substring(1); |
| 225 | return true; |
| 226 | } |
| 227 | return false; |
| 228 | } |
| 229 | |
| 230 | UrlParser::UrlPart UrlParser::GetUrlPart(const StringValue& part) { |
| 231 | // Quick filter on requested URL part, based on first character. |