-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathresponse.cc
147 lines (135 loc) · 4.45 KB
/
response.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "response.hpp"
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
namespace http{
namespace server{
namespace status_strings {
const std::string ok =
"HTTP/1.1 200 OK";
const std::string created =
"HTTP/1.1 201 Created";
const std::string accepted =
"HTTP/1.1 202 Accepted";
const std::string no_content =
"HTTP/1.1 204 No Content";
const std::string multiple_choices =
"HTTP/1.1 300 Multiple Choices";
const std::string moved_permanently =
"HTTP/1.1 301 Moved Permanently";
const std::string moved_temporarily =
"HTTP/1.1 302 Moved Temporarily";
const std::string not_modified =
"HTTP/1.1 304 Not Modified";
const std::string bad_request =
"HTTP/1.1 400 Bad Request";
const std::string unauthorized =
"HTTP/1.1 401 Unauthorized";
const std::string forbidden =
"HTTP/1.1 403 Forbidden";
const std::string not_found =
"HTTP/1.1 404 Not Found";
const std::string internal_server_error =
"HTTP/1.1 500 Internal Server Error";
const std::string not_implemented =
"HTTP/1.1 501 Not Implemented";
const std::string bad_gateway =
"HTTP/1.1 502 Bad Gateway";
const std::string service_unavailable =
"HTTP/1.1 503 Service Unavailable";
std::string response_code_to_string(Response::ResponseCode status)
{
switch (status)
{
case Response::ok:
return ok;
case Response::created:
return created;
case Response::accepted:
return accepted;
case Response::no_content:
return no_content;
case Response::multiple_choices:
return multiple_choices;
case Response::moved_permanently:
return moved_permanently;
case Response::moved_temporarily:
return moved_temporarily;
case Response::not_modified:
return not_modified;
case Response::bad_request:
return bad_request;
case Response::unauthorized:
return unauthorized;
case Response::forbidden:
return forbidden;
case Response::not_found:
return not_found;
case Response::internal_server_error:
return internal_server_error;
case Response::not_implemented:
return not_implemented;
case Response::bad_gateway:
return bad_gateway;
case Response::service_unavailable:
return service_unavailable;
default:
return internal_server_error;
}
}
} // namespace status_strings
void Response::SetStatus(const ResponseCode response_code){
response_code_ = response_code;
}
void Response::AddHeader(const std::string& header_name, const std::string& header_value)
{
headers_.push_back(std::make_pair(header_name, header_value));
}
bool Response::SetHeader(const std::string header_name, const std::string header_value)
{
for (auto& header : headers_)
{
if (header.first == header_name)
{
header.second = header_value;
return true;
}
}
return false;
}
void Response::SetBody(const std::string& body){
body_ = body;
}
std::string Response::ToString(){
const std::string CRLF = "\r\n";
std::string response_str = status_strings::response_code_to_string(response_code_) + CRLF;
for (auto header : headers_)
{
response_str += header.first + ": " + header.second + CRLF;
}
response_str += CRLF; // there is an extra CRLF between last header and body of response
response_str += body_;
return response_str;
}
Response Response::stock_response(Response::ResponseCode status)
{
Response resp;
resp.response_code_ = status;
resp.body_ = status_strings::response_code_to_string(status);
resp.headers_.push_back(std::make_pair("Content-Length", std::to_string(resp.body_.size())));
resp.headers_.push_back(std::make_pair("Content-Type", "text/html"));
return resp;
}
void Response::ApplyGzip()
{
std::string compressedString;
boost::iostreams::filtering_ostream compressingStream;
compressingStream.push(boost::iostreams::gzip_compressor(boost::iostreams::gzip_params(boost::iostreams::gzip::best_compression)));
compressingStream.push(boost::iostreams::back_inserter(compressedString));
compressingStream << body_;
boost::iostreams::close(compressingStream);
SetBody(compressedString);
SetHeader("Content-Length", std::to_string(compressedString.size()));
AddHeader("Content-Encoding", "gzip");
}
}
}