1 #pragma once
2 #ifndef URI_HPP_INCLUDED
3 #define URI_HPP_INCLUDED
4 
5 #include <string>
6 #include <algorithm>
7 
8 namespace uri {
9 
10 struct uri
11 {
12 public:
query_stringuri::uri13 	std::string query_string() const { return query_string_; }
pathuri::uri14 	std::string path()  const { return path_; }
protocoluri::uri15 	std::string protocol()  const { return protocol_; }
hosturi::uri16 	std::string host() const { return host_; }
porturi::uri17 	std::string port() const { return port_; }
18 
parseuri::uri19 	static uri parse(const std::string &url)
20 	{
21 		uri result;
22 
23 		typedef std::string::const_iterator iterator_t;
24 
25 		if (url.length() == 0)
26 			return result;
27 
28 		iterator_t uriEnd = url.end();
29 
30 		// get query start
31 		iterator_t queryStart = std::find(url.begin(), uriEnd, '?');
32 
33 		// protocol
34 		iterator_t protocolStart = url.begin();
35 		iterator_t protocolEnd = std::find(protocolStart, uriEnd, ':');            //"://");
36 
37 		if (protocolEnd != uriEnd)
38 		{
39 			std::string prot = &*(protocolEnd);
40 			if ((prot.length() > 3) && (prot.substr(0, 3) == "://"))
41 			{
42 				result.protocol_ = std::string(protocolStart, protocolEnd);
43 				protocolEnd += 3;   //      ://
44 			}
45 			else
46 				protocolEnd = url.begin();  // no protocol
47 		}
48 		else
49 			protocolEnd = url.begin();  // no protocol
50 
51 		// host
52 		iterator_t hostStart = protocolEnd;
53 		iterator_t pathStart = std::find(hostStart, uriEnd, '/');  // get pathStart
54 
55 		iterator_t hostEnd = std::find(protocolEnd,
56 			(pathStart != uriEnd) ? pathStart : queryStart,
57 			':');  // check for port
58 
59 		result.host_ = std::string(hostStart, hostEnd);
60 
61 		// port
62 		if ((hostEnd != uriEnd) && ((&*(hostEnd))[0] == ':'))  // we have a port
63 		{
64 			hostEnd++;
65 			iterator_t portEnd = (pathStart != uriEnd) ? pathStart : queryStart;
66 			result.port_ = std::string(hostEnd, portEnd);
67 		} else {
68 			result.port_ = "80";
69 		}
70 
71 		// path
72 		if (pathStart != uriEnd)
73 			result.path_ = std::string(pathStart, queryStart);
74 
75 		// query
76 		if (queryStart != uriEnd)
77 			result.query_string_ = std::string(queryStart, url.end());
78 
79 		return result;
80 	}   // Parse
81 
82 private:
83 	std::string query_string_, path_, protocol_, host_, port_;
84 };  // uri
85 
86 }
87 
88 #endif
89