1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2016 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "nel/misc/common.h"
22 #include "nel/gui/url_parser.h"
32 // ***************************************************************************
33 CUrlParser::CUrlParser(const std::string
&uri
)
38 // ***************************************************************************
39 void CUrlParser::parse(std::string uri
)
41 const size_t npos
= std::string::npos
;
45 // strip fragment if present
49 hash
= uri
.substr(pos
+ 1);
50 uri
= uri
.substr(0, pos
);
55 if (pos
!= npos
&& pos
>= 1)
57 for (uint i
=0; i
<pos
; i
++)
67 scheme
= uri
.substr(0, pos
);
68 uri
= uri
.substr(pos
+ 1);
73 if (uri
.substr(0, 2) == "//")
75 pos
= uri
.find_first_of("/?", 2);
76 authority
= uri
.substr(0, pos
);
78 uri
= uri
.substr(pos
);
82 // strip empty port from authority
83 if (authority
.find_last_of(":") == authority
.length() - 1)
84 authority
= authority
.substr(0, authority
.length() - 1);
86 // extract host from user:pass@host:port
87 pos
= authority
.find("@");
89 host
= authority
.substr(pos
+ 1);
91 host
= authority
.substr(2);
94 host
= NLMISC::toLowerAscii(host
);
98 host
= host
.substr(0, pos
);
105 query
= uri
.substr(pos
);
106 uri
= uri
.substr(0, pos
);
109 // all that is remaining is path
113 void CUrlParser::inherit(const std::string
&url
)
115 // we have scheme, so we already absolute url
119 const size_t npos
= std::string::npos
;
122 CUrlParser
base(url
);
124 scheme
= base
.scheme
;
126 // if we already have authority, then ignore base path
127 if (!authority
.empty())
130 authority
= base
.authority
;
140 // find start of last path segment from base path
141 // if not found, then dont inherit base path at all
142 pos
= base
.path
.find_last_of("/");
144 path
= base
.path
.substr(0, pos
) + "/" + path
;
147 resolveRelativePath(path
);
150 void CUrlParser::resolveRelativePath(std::string
&path
)
152 const size_t npos
= std::string::npos
;
154 // no relative components in path. filename.ext is also matched, but that's fine
155 size_t pos
= path
.find(".");
161 while(pos
< path
.size())
163 if (path
[pos
] == '.')
165 // scan ahead to see what we have
166 std::string sub
= path
.substr(pos
, 2);
167 if (sub
== "./" || sub
== ".")
171 path
.replace(pos
, sub
.size(), "/");
174 // full or last segment
175 sub
= path
.substr(pos
-1, 3);
176 if (sub
== "/./" || sub
== "/.")
178 path
.replace(pos
, sub
.size()-1, "");
179 // we just removed char that pos was pointing, so rewind
188 if (pos
== 0 && path
.substr(pos
, 3) == "../")
189 path
.replace(pos
, 3, "/");
193 // full or last segment
194 sub
= path
.substr(pos
-1, 4);
195 if (sub
== "/../" || sub
== "/..")
198 lhp
= path
.find_last_of("/", pos
- 2);
202 // pos points to first dot in ..
203 // lhp points to start slash (/) of last segment
204 pos
+= sub
.size() - 1;
205 path
.replace(lhp
, pos
- lhp
, "/");
210 } // path[pos] == '.'
215 bool CUrlParser::isAbsolute() const
217 return !scheme
.empty() && !authority
.empty();
220 // serialize URL back to string
221 std::string
CUrlParser::toString() const
225 result
+= scheme
+ ":";
227 if (!authority
.empty())
232 // path already has leading slash
240 if (query
.find_first_of("?") != 0) result
+= "?";
247 result
+= "#" + hash
;