| 6389 | } |
| 6390 | |
| 6391 | inline bool Server::write_response_core(Stream &strm, bool close_connection, |
| 6392 | const Request &req, Response &res, |
| 6393 | bool need_apply_ranges) { |
| 6394 | assert(res.status != -1); |
| 6395 | |
| 6396 | if (400 <= res.status && error_handler_ && |
| 6397 | error_handler_(req, res) == HandlerResponse::Handled) { |
| 6398 | need_apply_ranges = true; |
| 6399 | } |
| 6400 | |
| 6401 | std::string content_type; |
| 6402 | std::string boundary; |
| 6403 | if (need_apply_ranges) { apply_ranges(req, res, content_type, boundary); } |
| 6404 | |
| 6405 | // Prepare additional headers |
| 6406 | if (close_connection || req.get_header_value("Connection") == "close") { |
| 6407 | res.set_header("Connection", "close"); |
| 6408 | } else { |
| 6409 | std::string s = "timeout="; |
| 6410 | s += std::to_string(keep_alive_timeout_sec_); |
| 6411 | s += ", max="; |
| 6412 | s += std::to_string(keep_alive_max_count_); |
| 6413 | res.set_header("Keep-Alive", s); |
| 6414 | } |
| 6415 | |
| 6416 | if ((!res.body.empty() || res.content_length_ > 0 || res.content_provider_) && |
| 6417 | !res.has_header("Content-Type")) { |
| 6418 | res.set_header("Content-Type", "text/plain"); |
| 6419 | } |
| 6420 | |
| 6421 | if (res.body.empty() && !res.content_length_ && !res.content_provider_ && |
| 6422 | !res.has_header("Content-Length")) { |
| 6423 | res.set_header("Content-Length", "0"); |
| 6424 | } |
| 6425 | |
| 6426 | if (req.method == "HEAD" && !res.has_header("Accept-Ranges")) { |
| 6427 | res.set_header("Accept-Ranges", "bytes"); |
| 6428 | } |
| 6429 | |
| 6430 | if (post_routing_handler_) { post_routing_handler_(req, res); } |
| 6431 | |
| 6432 | // Response line and headers |
| 6433 | { |
| 6434 | detail::BufferStream bstrm; |
| 6435 | if (!detail::write_response_line(bstrm, res.status)) { return false; } |
| 6436 | if (!header_writer_(bstrm, res.headers)) { return false; } |
| 6437 | |
| 6438 | // Flush buffer |
| 6439 | auto &data = bstrm.get_buffer(); |
| 6440 | detail::write_data(strm, data.data(), data.size()); |
| 6441 | } |
| 6442 | |
| 6443 | // Body |
| 6444 | auto ret = true; |
| 6445 | if (req.method != "HEAD") { |
| 6446 | if (!res.body.empty()) { |
| 6447 | if (!detail::write_data(strm, res.body.data(), res.body.size())) { |
| 6448 | ret = false; |
nothing calls this directly
no test coverage detected