Link v2.0
[link.git] / Source / Request.cpp
blob657f530672486f2a2351f2d0488add3d44d25779
1 #include <Link.hpp>
2 #include <iostream>
3 #include <sstream>
5 Link::Request::Request(std::string headers, std::string body) {
6 std::string line;
7 std::stringstream stream(headers);
8 std::map<std::string, std::string> headerMap;
9 int i = 0;
10 std::string path;
11 while (std::getline(stream, line)) {
12 if (i == 0) {
13 path = line.substr(line.find(" ") + 1);
14 path = path.substr(0, path.find(" "));
15 } else {
16 std::string val = line.substr(line.find(": ") + 2);
17 headerMap[line.substr(0, line.find(": "))] = val.substr(0, val.length()-1);
19 i++;
21 this->SetURL("http://"+headerMap["Host"]+path);
22 this->SetHeadersRaw(headers)->SetBody(body);
23 this->SetRawHeader("Host", headerMap["Host"]);
26 std::string decodeHTTP(std::string &src) {
27 std::replace(src.begin(), src.end(), '+', ' ');
28 std::string ret;
29 char ch;
30 int i, ii;
31 for (i=0;i<src.length();i++) {
32 if (int(src[i])=='%') {
33 switch (src[i+1]) {
34 case '0'...'9':
35 case 'a'...'f':
36 case 'A'...'F':
37 break;
38 default:
39 ret += '%';
40 continue;
42 sscanf(src.substr(i+1,2).c_str(), "%x", &ii);
43 ch=static_cast<char>(ii);
44 ret+=ch;
45 i=i+2;
46 } else ret+=src[i];
48 return (ret);
51 std::map<std::string, std::string> Link::Request::GetParams() {
52 return this->params;
55 Link::Request* Link::Request::SetHeadersRaw(std::string headersRaw) {
56 std::string line;
57 std::stringstream stream(headersRaw);
58 int i = 0;
59 while (std::getline(stream, line)) {
60 if (i == 0) {
61 this->SetMethod(line.substr(0, line.find(" ")));
62 this->SetVersion(line.substr(line.find("HTTP/") + 5));
63 std::string path = line.substr(line.find(" ") + 1);
64 this->SetPath(path.substr(0, path.find(" ")));
65 } else {
66 this->SetRawHeader(line.substr(0, line.find(": ")), line.substr(line.find(": ") + 2, line.find("\r")));
68 i++;
70 if (this->path.find("?") != std::string::npos) {
71 std::string queries = this->path.substr(this->path.find("?") + 1);
72 std::stringstream stream(queries);
73 while (std::getline(stream, line, '&')) {
74 std::string key = line.substr(0, line.find("="));
75 std::string value = line.substr(line.find("=") + 1);
76 this->SetParam(decodeHTTP(key), decodeHTTP(value));
78 SetPath(this->path.substr(0, this->path.find("?")));
80 if (this->GetHeader("Cookie") != "") {
81 std::string cookies = this->GetHeader("Cookie");
82 std::stringstream stream(cookies);
83 while (std::getline(stream, line, ';')) {
84 std::string key = line.substr(0, line.find("="));
85 if (key[0] == ' ') key = key.substr(1);
86 std::string value = line.substr(line.find("=") + 1);
87 this->SetCookie(decodeHTTP(key), decodeHTTP(value));
90 return this;
93 Link::Request::Request(std::string url) {
94 this->version = "1.1";
95 this->port = 0;
96 this->SetURL(url)->SetMethod("GET");
99 Link::Request* Link::Request::SetURL(std::string url) {
100 this->url = url;
101 this->protocol = url.substr(0, url.find("://"));
102 this->domain = url.substr(url.find("://") + 3);
103 this->domain = this->domain.substr(0, this->domain.find("/"));
104 if (port == 0 && this->domain.find(":") == std::string::npos) {
105 this->SetPort(this->protocol == "https"?443:80);
106 } else if (port == 0) {
107 this->SetPort(std::stoi(this->domain.substr(this->domain.find(":") + 1)));
108 this->domain = this->domain.substr(0, this->domain.find(":"));
110 this->path = url.substr(url.find("://") + 3);
111 this->path = this->path.substr(this->path.find("/"));
112 this->headers["Host"] = domain + (port == 80?"":":" + std::to_string(port));
113 return this;
116 Link::Request* Link::Request::SetPort(int d) {
117 this->port = d;
118 return this;
121 int Link::Request::GetPort() {
122 return port;
125 Link::Request* Link::Request::SetMethod(std::string method) {
126 this->method = method;
127 return this;
130 Link::Request* Link::Request::SetHeader(std::string key, std::string value) {
131 std::string lower = key;
132 std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
133 this->headers[lower] = value;
134 return this;
137 Link::Request* Link::Request::SetCookie(std::string key, std::string value) {
138 this->cookies[key] = value;
139 return this;
142 Link::Request* Link::Request::SetParam(std::string key, std::string value) {
143 this->params[key] = value;
144 return this;
147 Link::Request* Link::Request::SetBody(std::string body) {
148 this->body = body;
149 return this;
152 Link::Request* Link::Request::SetPath(std::string path) {
153 if (path[0] != '/') path = "/" + path;
154 path = decodeHTTP(path);
155 this->SetURL(this->protocol + "://" + this->domain + path);
156 return this;
159 Link::Request* Link::Request::SetProtocol(std::string protocol) {
160 this->SetURL(protocol + "://" + this->domain + this->path);
161 return this;
164 Link::Request* Link::Request::SetDomain(std::string domain) {
165 this->SetURL(this->protocol + "://" + domain + this->path);
166 return this;
169 std::string Link::Request::GetPath() {
170 return this->path;
173 std::string Link::Request::GetProtocol() {
174 return this->protocol;
177 std::string Link::Request::GetDomain() {
178 return this->domain;
181 std::string Link::Request::GetURL() {
182 return this->url;
185 std::string Link::Request::GetMethod() {
186 return this->method;
189 std::string Link::Request::GetHeader(std::string key) {
190 std::string lower = key;
191 std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
192 return this->headers[lower];
195 std::string Link::Request::GetRawHeader(std::string key) {
196 return key + ": " + this->headers[key];
199 Link::Request* Link::Request::SetRawHeader(std::string key, std::string value) {
200 this->headers[key] = value;
201 return this;
204 std::string Link::Request::GetCookie(std::string key) {
205 return this->cookies[key];
208 std::string Link::Request::GetParam(std::string key) {
209 return this->params[key];
212 std::string Link::Request::GetBody() {
213 return this->body;
216 std::string Link::Request::GetRawHeaders() {
217 std::string headers = this->GetMethod() + " " + this->GetURL()
218 .substr(this->GetURL().find(this->domain)+this->domain.length() +
219 (this->port == 80 || this->port == 443?0:std::to_string(this->port).length() + 1))
220 + " HTTP/" + this->GetVersion() + "\r\n";
221 for (auto const& x : this->headers) {
222 if (x.second != "") headers += x.first + ": " + x.second + "\r\n";
224 return headers;
227 std::string Link::Request::GetRawParams() {
228 std::string res = "";
229 res += this->method + " " + this->path + " " + this->version + "\r\n";
230 for (auto it = this->params.begin(); it != this->params.end(); it++) res += it->first + "=" + it->second + "&";
231 return res.substr(0, res.length() - 1);
234 std::string Link::Request::GetRawBody() {
235 return this->body;
238 std::string Link::Request::GetVersion() {
239 return this->version;
242 Link::Request* Link::Request::SetVersion(std::string version) {
243 this->version = version;
244 return this;
247 Link::Request* Link::Request::SetIP(std::string ip) {
248 this->ip = ip;
249 return this;
252 std::string Link::Request::GetIP() {
253 return this->ip;