1
+ // Copyright Fredrik Olofsson 2012.
2
+ // Distributed under the Boost Software License, Version 1.0.
3
+ // (See accompanying file LICENSE_1_0.txt or copy at
4
+ // http://www.boost.org/LICENSE_1_0.txt)
5
+ #ifndef __CPPNETLIB_NETWORK_URI_UTILITY__
6
+ #define __CPPNETLIB_NETWORK_URI_UTILITY__
7
+
8
+ #include < string>
9
+
10
+ namespace boost
11
+ {
12
+ namespace network
13
+ {
14
+ namespace uri
15
+ {
16
+ /* *
17
+ * Normalize the given path and returns it. The path will be resolved and any attempt
18
+ * to point to an file above (www) root will be removed. The returned string will allways
19
+ * start with an slash ("/"). The implemenation in its current form does not handle procent
20
+ * coding (%20). Examples:
21
+ *
22
+ * "/test/test/../" : -> "/test"
23
+ * "../../../" : -> "/"
24
+ */
25
+ std::string normalize (std::string);
26
+ }
27
+ }
28
+ }
29
+
30
+
31
+
32
+ namespace boost
33
+ {
34
+ namespace network
35
+ {
36
+ namespace uri
37
+ {
38
+ std::string normalize (std::string path)
39
+ {
40
+ if (path.empty () || path.front () != ' /' )
41
+ path.insert (0 , " /" );
42
+
43
+ std::size_t query_offset = path.find (" ?" ),
44
+ temp = 0 ,
45
+ pos = 0 ,
46
+ counter = 0 ;
47
+
48
+ while ((pos = path.find (" //" )) != std::string::npos && pos < query_offset)
49
+ path.replace (pos,2 ," /" );
50
+
51
+
52
+ while ((pos = path.find (" ../" )) != std::string::npos && pos < query_offset)
53
+ {
54
+ temp = pos;
55
+ while (0 < temp && counter < 2 )
56
+ {
57
+ if (path[--temp] == ' /' )
58
+ ++counter;
59
+ }
60
+ path.replace (temp, pos-temp+3 ," /" ); // length of ../ is 3
61
+ counter = 0 ;// back to default
62
+ }
63
+
64
+ // remove the last '/' in the path section if not the last on.
65
+ pos = ((query_offset == std::string::npos) ? path.size () : query_offset) - 1 ;
66
+ if (path[pos] == ' /' && pos != 0 )
67
+ path.erase (pos,1 );
68
+
69
+ return path;
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+
76
+ #endif
0 commit comments