OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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 "net/tools/flip_server/url_utilities.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/strings/string_number_conversions.h" | |
9 #include "base/strings/string_util.h" | |
10 | |
11 namespace net { | |
12 | |
13 std::string UrlUtilities::GetUrlHost(const std::string& url) { | |
14 size_t b = url.find("//"); | |
15 if (b == std::string::npos) | |
16 b = 0; | |
17 else | |
18 b += 2; | |
19 size_t next_slash = url.find_first_of('/', b); | |
20 size_t next_colon = url.find_first_of(':', b); | |
21 if (next_slash != std::string::npos && next_colon != std::string::npos && | |
22 next_colon < next_slash) { | |
23 return std::string(url, b, next_colon - b); | |
24 } | |
25 if (next_slash == std::string::npos) { | |
26 if (next_colon != std::string::npos) { | |
27 return std::string(url, b, next_colon - b); | |
28 } else { | |
29 next_slash = url.size(); | |
30 } | |
31 } | |
32 return std::string(url, b, next_slash - b); | |
33 } | |
34 | |
35 std::string UrlUtilities::GetUrlHostPath(const std::string& url) { | |
36 size_t b = url.find("//"); | |
37 if (b == std::string::npos) | |
38 b = 0; | |
39 else | |
40 b += 2; | |
41 return std::string(url, b); | |
42 } | |
43 | |
44 std::string UrlUtilities::GetUrlPath(const std::string& url) { | |
45 size_t b = url.find("//"); | |
46 if (b == std::string::npos) | |
47 b = 0; | |
48 else | |
49 b += 2; | |
50 b = url.find("/", b); | |
51 if (b == std::string::npos) | |
52 return "/"; | |
53 | |
54 size_t e = url.find("#", b + 1); | |
55 if (e != std::string::npos) | |
56 return std::string(url, b, (e - b)); | |
57 return std::string(url, b); | |
58 } | |
59 | |
60 namespace { | |
61 | |
62 // Parsing states for UrlUtilities::Unescape | |
63 enum UnescapeState { | |
64 NORMAL, // We are not in the middle of parsing an escape. | |
65 ESCAPE1, // We just parsed % . | |
66 ESCAPE2 // We just parsed %X for some hex digit X. | |
67 }; | |
68 | |
69 } // namespace | |
70 | |
71 std::string UrlUtilities::Unescape(const std::string& escaped_url) { | |
72 std::string unescaped_url, escape_text; | |
73 int escape_value; | |
74 UnescapeState state = NORMAL; | |
75 std::string::const_iterator iter = escaped_url.begin(); | |
76 while (iter < escaped_url.end()) { | |
77 char c = *iter; | |
78 switch (state) { | |
79 case NORMAL: | |
80 if (c == '%') { | |
81 escape_text.clear(); | |
82 state = ESCAPE1; | |
83 } else { | |
84 unescaped_url.push_back(c); | |
85 } | |
86 ++iter; | |
87 break; | |
88 case ESCAPE1: | |
89 if (base::IsHexDigit(c)) { | |
90 escape_text.push_back(c); | |
91 state = ESCAPE2; | |
92 ++iter; | |
93 } else { | |
94 // Unexpected, % followed by non-hex chars, pass it through. | |
95 unescaped_url.push_back('%'); | |
96 state = NORMAL; | |
97 } | |
98 break; | |
99 case ESCAPE2: | |
100 if (base::IsHexDigit(c)) { | |
101 escape_text.push_back(c); | |
102 bool ok = base::HexStringToInt(escape_text, &escape_value); | |
103 DCHECK(ok); | |
104 unescaped_url.push_back(static_cast<unsigned char>(escape_value)); | |
105 state = NORMAL; | |
106 ++iter; | |
107 } else { | |
108 // Unexpected, % followed by non-hex chars, pass it through. | |
109 unescaped_url.push_back('%'); | |
110 unescaped_url.append(escape_text); | |
111 state = NORMAL; | |
112 } | |
113 break; | |
114 } | |
115 } | |
116 // Unexpected, % followed by end of string, pass it through. | |
117 if (state == ESCAPE1 || state == ESCAPE2) { | |
118 unescaped_url.push_back('%'); | |
119 unescaped_url.append(escape_text); | |
120 } | |
121 return unescaped_url; | |
122 } | |
123 | |
124 } // namespace net | |
OLD | NEW |