Yet Another HTTP Library: /home/cmouse/projects/libyahttp/yahttp/url.hpp Source File

Yet Another HTTP Library yahttp

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
url.hpp
Go to the documentation of this file.
1 #ifndef _YAHTTP_URL_HPP
2 #define _YAHTTP_URL_HPP 1
3 #include <sstream>
4 #include <string>
5
6 #include "utility.hpp"
7
8 #ifndef YAHTTP_MAX_URL_LENGTH
9 #define YAHTTP_MAX_URL_LENGTH 2048
10 #endif
11
12 namespace YaHTTP {
14 class URL {
15 private:
16 bool parseSchema(const std::string& url, size_t &pos) {
17 size_t pos1;
18 if (pos >= url.size()) return false; // no data
19 if ( (pos1 = url.find_first_of(":",pos)) == std::string::npos ) return false; // schema is mandatory
20 protocol = url.substr(pos, pos1-pos);
21 if (protocol == "http") port = 80;
22 if (protocol == "https") port = 443;
23 pos = pos1+1; // after :
24 if (url.compare(pos, 2, "//") == 0) {
25 pathless = false; // if this is true we put rest into parameters
26 pos += 2;
27 }
28 return true;
29 }; //<! parse schema/protocol part
30
31 bool parseHost(const std::string& url, size_t &pos) {
32 size_t pos1;
33 if (pos >= url.size()) return true; // no data
34 if ( (pos1 = url.find_first_of("/", pos)) == std::string::npos ) {
35 host = url.substr(pos);
36 path = "/";
37 pos = url.size();
38 } else {
39 host = url.substr(pos, pos1-pos);
40 pos = pos1;
41 }
42 if ( (pos1 = host.find_first_of(":")) != std::string::npos ) {
43 std::istringstream tmp(host.substr(pos1+1));
44 tmp >> port;
45 host = host.substr(0, pos1);
46 }
47 return true;
48 }; //<! parse host and port
49
50 bool parseUserPass(const std::string& url, size_t &pos) {
51 size_t pos1,pos2;
52 if (pos >= url.size()) return true; // no data
53
54 if ( (pos1 = url.find_first_of("@",pos)) == std::string::npos ) return true; // no userinfo
55 pos2 = url.find_first_of(":",pos);
56
57 if (pos2 != std::string::npos) { // comes with password
58 username = url.substr(pos, pos2 - pos);
59 password = url.substr(pos2+1, pos1 - pos2 - 1);
60 password = Utility::decodeURL(password);
61 } else {
62 username = url.substr(pos+1, pos1 - pos);
63 }
64 pos = pos1+1;
65 username = Utility::decodeURL(username);
66 return true;
67 }; //<! parse possible username and password
68
69 bool parsePath(const std::string& url, size_t &pos) {
70 size_t pos1;
71 if (pos >= url.size()) return true; // no data
72 if (url[pos] != '/') return false; // not an url
73 if ( (pos1 = url.find_first_of("?", pos)) == std::string::npos ) {
74 path = url.substr(pos);
75 pos = url.size();
76 } else {
77 path = url.substr(pos, pos1-pos);
78 pos = pos1;
79 }
80 return true;
81 }; //<! parse path component
82
83 bool parseParameters(const std::string& url, size_t &pos) {
84 size_t pos1;
85 if (pos >= url.size()) return true; // no data
86 if (url[pos] == '#') return true; // anchor starts here
87 if (url[pos] != '?') return false; // not a parameter
88 if ( (pos1 = url.find_first_of("#", pos)) == std::string::npos ) {
89 parameters = url.substr(pos+1);;
90 pos = url.size();
91 } else {
92 parameters = url.substr(pos+1, pos1-pos-1);
93 pos = pos1;
94 }
95 if (parameters.size()>0 && *(parameters.end()-1) == '&') parameters.resize(parameters.size()-1);
96 return true;
97 }; //<! parse url parameters
98
99 bool parseAnchor(const std::string& url, size_t &pos) {
100 if (pos >= url.size()) return true; // no data
101 if (url[pos] != '#') return false; // not anchor
102 anchor = url.substr(pos+1);
103 return true;
104 }; //<! parse anchor
105
106 void initialize() {
107 protocol = ""; host = ""; port = 0; username = ""; password = ""; path = ""; parameters = ""; anchor =""; pathless = true;
108 }; //<! initialize to empty URL
109
110 public:
111 std::string to_string() const {
112 std::string tmp;
113 std::ostringstream oss;
114
115 if (protocol.empty() == false) {
116 oss << protocol << ":";
117 if (host.empty() == false) {
118 oss << "//";
119 }
120 }
121
122 if (username.empty() == false) {
123 if (password.empty() == false)
124 oss << Utility::encodeURL(username) << ":" << Utility::encodeURL(password) << "@";
125 else
126 oss << Utility::encodeURL(username) << "@";
127 }
128 if (host.empty() == false)
129 oss << host;
130 if (!(protocol == "http" && port == 80) &&
131 !(protocol == "https" && port == 443) &&
132 port > 0)
133 oss << ":" << port;
134
135 oss << path;
136 if (parameters.empty() == false) {
137 if (!pathless)
138 oss << "?";
139 oss << parameters;
140 }
141 if (anchor.empty() == false)
142 oss << "#" << anchor;
143 return oss.str();
144 }; //<! convert this URL to string
145
146 std::string protocol; //<! schema/protocol
147 std::string host; //<! host
148 int port; //<! port
149 std::string username; //<! username
150 std::string password; //<! password
151 std::string path; //<! path
152 std::string parameters; //<! url parameters
153 std::string anchor; //<! anchor
154 bool pathless; //<! whether this url has no path
155
156 URL() { initialize(); }; //<! construct empty url
157 URL(const std::string& url) {
158 parse(url);
159 }; //<! calls parse with url
160
161 URL(const char *url) {
162 parse(std::string(url));
163 }; //<! calls parse with url
164
165 bool parse(const std::string& url) {
166 // setup
167 initialize();
168
169 if (url.size() > YAHTTP_MAX_URL_LENGTH) return false;
170 size_t pos = 0;
171 if (*(url.begin()) != '/') { // full url?
172 if (parseSchema(url, pos) == false) return false;
173 if (pathless) {
174 parameters = url.substr(pos);
175 return true;
176 }
177 if (parseUserPass(url, pos) == false) return false;
178 if (parseHost(url, pos) == false) return false;
179 }
180 if (parsePath(url, pos) == false) return false;
181 if (parseParameters(url, pos) == false) return false;
182 return parseAnchor(url, pos);
183 }; //<! parse various formats of urls ranging from http://example.com/foo?bar=baz into data:base64:d089swt64wt...
184
185 friend std::ostream & operator<<(std::ostream& os, const URL& url) {
186 os<<url.to_string();
187 return os;
188 };
189 };
190 };
191 #endif
YaHTTP::URL::password
std::string password
Definition: url.hpp:150
YaHTTP::Utility::encodeURL
static std::string encodeURL(const std::string &component, bool asUrl=true)
Definition: utility.hpp:233
YaHTTP::URL::parse
bool parse(const std::string &url)
Definition: url.hpp:165
YaHTTP::URL::host
std::string host
Definition: url.hpp:147
YaHTTP::URL::pathless
bool pathless
Definition: url.hpp:154
YaHTTP::Utility::decodeURL
static std::string decodeURL(const std::string &component)
Definition: utility.hpp:204
YaHTTP::URL::parsePath
bool parsePath(const std::string &url, size_t &pos)
Definition: url.hpp:69
YaHTTP::URL::parseSchema
bool parseSchema(const std::string &url, size_t &pos)
Definition: url.hpp:16
YaHTTP::URL::parseAnchor
bool parseAnchor(const std::string &url, size_t &pos)
Definition: url.hpp:99
YaHTTP::URL::port
int port
Definition: url.hpp:148
YaHTTP::URL::URL
URL(const char *url)
Definition: url.hpp:161
YaHTTP::URL::operator<<
friend std::ostream & operator<<(std::ostream &os, const URL &url)
Definition: url.hpp:185
utility.hpp
YaHTTP::URL::parameters
std::string parameters
Definition: url.hpp:152
YaHTTP::URL::parseParameters
bool parseParameters(const std::string &url, size_t &pos)
Definition: url.hpp:83
YaHTTP::URL::parseUserPass
bool parseUserPass(const std::string &url, size_t &pos)
Definition: url.hpp:50
YaHTTP::URL::protocol
std::string protocol
Definition: url.hpp:144
YAHTTP_MAX_URL_LENGTH
#define YAHTTP_MAX_URL_LENGTH
Definition: url.hpp:9
YaHTTP::URL::URL
URL()
Definition: url.hpp:156
YaHTTP::URL::anchor
std::string anchor
Definition: url.hpp:153
YaHTTP::URL::path
std::string path
Definition: url.hpp:151
YaHTTP::URL::parseHost
bool parseHost(const std::string &url, size_t &pos)
Definition: url.hpp:31
YaHTTP::URL::URL
URL(const std::string &url)
Definition: url.hpp:157
YaHTTP::URL::username
std::string username
Definition: url.hpp:149
YaHTTP::URL::to_string
std::string to_string() const
Definition: url.hpp:111
YaHTTP::URL
Definition: url.hpp:14
YaHTTP::URL::initialize
void initialize()
Definition: url.hpp:106