| 149 | : DataEncoder(encode(response, request)) {} |
| 150 | |
| 151 | static std::string encode( |
| 152 | const http::Response& response, |
| 153 | const http::Request& request) |
| 154 | { |
| 155 | std::ostringstream out; |
| 156 | |
| 157 | // TODO(benh): Check version? |
| 158 | |
| 159 | out << "HTTP/1.1 " << response.status << "\r\n"; |
| 160 | |
| 161 | auto headers = response.headers; |
| 162 | |
| 163 | // HTTP 1.1 requires the "Date" header. In the future once we |
| 164 | // start checking the version (above) then we can conditionally |
| 165 | // add this header, but for now, we always do. |
| 166 | time_t rawtime; |
| 167 | time(&rawtime); |
| 168 | |
| 169 | char date[256]; |
| 170 | |
| 171 | tm tm_; |
| 172 | PCHECK(os::gmtime_r(&rawtime, &tm_) != nullptr) |
| 173 | << "Failed to convert the current time to a tm struct " |
| 174 | << "using os::gmtime_r()"; |
| 175 | |
| 176 | // TODO(benh): Check return code of strftime! |
| 177 | strftime(date, 256, "%a, %d %b %Y %H:%M:%S GMT", &tm_); |
| 178 | |
| 179 | headers["Date"] = date; |
| 180 | |
| 181 | // Should we compress this response? |
| 182 | std::string body = response.body; |
| 183 | |
| 184 | if (response.type == http::Response::BODY && |
| 185 | response.body.length() >= GZIP_MINIMUM_BODY_LENGTH && |
| 186 | !headers.contains("Content-Encoding") && |
| 187 | request.acceptsEncoding("gzip")) { |
| 188 | Try<std::string> compressed = gzip::compress(body); |
| 189 | if (compressed.isError()) { |
| 190 | LOG(WARNING) << "Failed to gzip response body: " << compressed.error(); |
| 191 | } else { |
| 192 | body = std::move(compressed.get()); |
| 193 | |
| 194 | headers["Content-Length"] = stringify(body.length()); |
| 195 | headers["Content-Encoding"] = "gzip"; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | foreachpair (const std::string& key, const std::string& value, headers) { |
| 200 | out << key << ": " << value << "\r\n"; |
| 201 | } |
| 202 | |
| 203 | // Add a Content-Length header if the response is of type "none" |
| 204 | // or "body" and no Content-Length header has been supplied. |
| 205 | if (response.type == http::Response::NONE && |
| 206 | !headers.contains("Content-Length")) { |
| 207 | out << "Content-Length: 0\r\n"; |
| 208 | } else if (response.type == http::Response::BODY && |
nothing calls this directly
no test coverage detected