response.cc revision e88b8067863605485b966c074ba3bc5384da1763
1// Copyright 2014 The Chromium OS Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <libwebserv/response.h> 6 7#include <algorithm> 8 9#include <base/json/json_writer.h> 10#include <base/logging.h> 11#include <base/values.h> 12#include <chromeos/http/http_request.h> 13#include <chromeos/mime_utils.h> 14#include <chromeos/strings/string_utils.h> 15#include <libwebserv/protocol_handler.h> 16 17namespace libwebserv { 18 19Response::Response(ProtocolHandler* handler, const std::string& request_id) 20 : handler_{handler}, request_id_{request_id} { 21} 22 23Response::~Response() { 24 if (!reply_sent_) { 25 ReplyWithError(chromeos::http::status_code::InternalServerError, 26 "Internal server error"); 27 } 28} 29 30void Response::AddHeader(const std::string& header_name, 31 const std::string& value) { 32 headers_.emplace(header_name, value); 33} 34 35void Response::AddHeaders( 36 const std::vector<std::pair<std::string, std::string>>& headers) { 37 headers_.insert(headers.begin(), headers.end()); 38} 39 40void Response::Reply(int status_code, 41 const void* data, 42 size_t data_size, 43 const std::string& mime_type) { 44 status_code_ = status_code; 45 const uint8_t* byte_ptr = static_cast<const uint8_t*>(data); 46 data_.assign(byte_ptr, byte_ptr + data_size); 47 AddHeader(chromeos::http::response_header::kContentType, mime_type); 48 SendResponse(); 49} 50 51void Response::ReplyWithText(int status_code, 52 const std::string& text, 53 const std::string& mime_type) { 54 Reply(status_code, text.data(), text.size(), mime_type); 55} 56 57void Response::ReplyWithJson(int status_code, const base::Value* json) { 58 std::string text; 59 base::JSONWriter::WriteWithOptions( 60 *json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &text); 61 std::string mime_type = chromeos::mime::AppendParameter( 62 chromeos::mime::application::kJson, 63 chromeos::mime::parameters::kCharset, 64 "utf-8"); 65 ReplyWithText(status_code, text, mime_type); 66} 67 68void Response::ReplyWithJson(int status_code, 69 const std::map<std::string, std::string>& json) { 70 base::DictionaryValue json_value; 71 for (const auto& pair : json) { 72 json_value.SetString(pair.first, pair.second); 73 } 74 ReplyWithJson(status_code, &json_value); 75} 76 77void Response::Redirect(int status_code, const std::string& redirect_url) { 78 AddHeader(chromeos::http::response_header::kLocation, redirect_url); 79 ReplyWithError(status_code, ""); 80} 81 82void Response::ReplyWithError(int status_code, const std::string& error_text) { 83 status_code_ = status_code; 84 data_.assign(error_text.begin(), error_text.end()); 85 SendResponse(); 86} 87 88void Response::ReplyWithErrorNotFound() { 89 ReplyWithError(chromeos::http::status_code::NotFound, "Not Found"); 90} 91 92void Response::SendResponse() { 93 CHECK(!reply_sent_) << "Response already sent"; 94 reply_sent_ = true; 95 handler_->CompleteRequest(request_id_, status_code_, headers_, data_); 96} 97 98} // namespace libwebserv 99