Meta: Only build linktest if BUILD_LINKTEST is on.
[link.git] / Source / Response.cpp
blob2a2f0ac8bd9de84913fb388679734199582acc91
1 #include <Link.hpp>
2 #include <iostream>
3 #include <sstream>
4 #include <zlib.h>
6 Link::Response::Response() {
7 this->SetHeadersRaw("HTTP/1.1 200 OK\r\n")->SetBody("");
8 this->SetInstanceType("Server");
9 this->closed = false;
12 Link::Response::Response(std::string header, std::string body) {
13 this->SetHeadersRaw(header);
14 this->SetBody(body);
15 this->SetInstanceType("Client");
16 this->closed = false;
19 Link::Response* Link::Response::SetInstanceType(std::string type) {
20 this->instanceType = type;
21 return this;
24 bool Link::Response::InstanceOf(std::string type) {
25 return this->instanceType == type;
28 Link::Response* Link::Response::Close() {
29 this->closed = true;
30 return this;
33 bool Link::Response::isClosed() {
34 return this->closed;
37 Link::Response* Link::Response::SetHeader(std::string key, std::string value) {
38 std::transform(key.begin(), key.end(), key.begin(), ::tolower);
39 this->headers[key] = value;
40 return this;
43 std::string decompress(std::string data) {
44 z_stream strm;
45 strm.zalloc = Z_NULL;
46 strm.zfree = Z_NULL;
47 strm.opaque = Z_NULL;
48 strm.avail_in = data.size();
49 strm.next_in = (Bytef*)data.data();
50 inflateInit2(&strm, 16 + MAX_WBITS);
51 char outbuffer[32768];
52 std::string outstring;
53 do {
54 strm.avail_out = 32768;
55 strm.next_out = (Bytef*)outbuffer;
56 inflate(&strm, Z_NO_FLUSH);
57 if (outstring.size() < strm.total_out) {
58 outstring.append(outbuffer, strm.total_out - outstring.size());
60 } while (strm.avail_out == 0);
61 inflateEnd(&strm);
62 return outstring;
65 std::string deflate(std::string data) {
66 z_stream strm;
67 strm.zalloc = Z_NULL;
68 strm.zfree = Z_NULL;
69 strm.opaque = Z_NULL;
70 strm.avail_in = data.size();
71 strm.next_in = (Bytef*)data.data();
72 deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 16 + MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
73 char outbuffer[32768];
74 std::string outstring;
75 do {
76 strm.avail_out = 32768;
77 strm.next_out = (Bytef*)outbuffer;
78 deflate(&strm, Z_FINISH);
79 if (outstring.size() < strm.total_out) {
80 outstring.append(outbuffer, strm.total_out - outstring.size());
82 } while (strm.avail_out == 0);
83 deflateEnd(&strm);
84 return outstring;
87 Link::Response* Link::Response::SetBody(std::string body) {
88 this->SetHeader("Content-Length", std::to_string(body.size()));
89 this->SetHeader("Transfer-Encoding", "");
90 this->body = body;
91 if (this->InstanceOf("Server")) {
92 this->SetHeader("Content-Encoding", "");
93 return this;
95 if (this->GetHeader("Content-Encoding") == "gzip") {
96 this->body = decompress(body);
97 return this;
99 if (this->GetHeader("Content-Encoding") == "deflate") {
100 this->body = deflate(body);
101 return this;
103 return this;
106 Link::Response* Link::Response::SetRawHeader(std::string key, std::string value) {
107 this->headers[key] = value;
108 return this;
111 Link::Response* Link::Response::SetHeadersRaw(std::string headersRaw) {
112 this->headersRaw = headersRaw;
113 std::string line = headersRaw.substr(0, headersRaw.find("\r\n"));
114 this->version = line.substr(0, line.find(" "));
115 line = line.substr(line.find(" ") + 1);
116 this->status = std::stoi(line);
118 std::istringstream iss(headersRaw.substr(headersRaw.find("\r\n") + 2));
119 std::string l;
120 while (std::getline(iss, l)) {
121 if (l == "") break;
122 std::string key = l.substr(0, l.find(":"));
123 std::string value = l.substr(l.find(":") + 2);
124 value = value.substr(0, value.find("\r"));
125 this->SetHeader(key, value);
127 return this;
130 Link::Response* Link::Response::SetStatus(int status) {
131 this->status = status;
132 return this;
135 Link::Response* Link::Response::SetVersion(std::string version) {
136 this->version = version;
137 return this;
140 std::string Link::Response::GetHeader(std::string key) {
141 std::string lower = key;
142 std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
143 return this->headers[lower];
146 std::string Link::Response::GetBody() {
147 return this->body;
150 std::string Link::Response::GetHeadersRaw() {
151 std::string headers = this->version + " " + std::to_string(this->status) + " " + Link::Status(this->status) + "\r\n";
152 for (auto const& x : this->headers) {
153 if (x.second != "") headers += x.first + ": " + x.second + "\r\n";
155 return headers;
158 std::string Link::Response::GetVersion() {
159 return this->version;
162 int Link::Response::GetStatus() {
163 return this->status;