response.cc revision 31a6379d5f773cb40312d2085e07f30cf3ac685d
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(json, 60 base::JSONWriter::OPTIONS_PRETTY_PRINT, 61 &text); 62 std::string mime_type = chromeos::mime::AppendParameter( 63 chromeos::mime::application::kJson, 64 chromeos::mime::parameters::kCharset, 65 "utf-8"); 66 ReplyWithText(status_code, text, mime_type); 67} 68 69void Response::ReplyWithJson(int status_code, 70 const std::map<std::string, std::string>& json) { 71 base::DictionaryValue json_value; 72 for (const auto& pair : json) { 73 json_value.SetString(pair.first, pair.second); 74 } 75 ReplyWithJson(status_code, &json_value); 76} 77 78void Response::Redirect(int status_code, const std::string& redirect_url) { 79 AddHeader(chromeos::http::response_header::kLocation, redirect_url); 80 ReplyWithError(status_code, ""); 81} 82 83void Response::ReplyWithError(int status_code, const std::string& error_text) { 84 status_code_ = status_code; 85 data_.assign(error_text.begin(), error_text.end()); 86 SendResponse(); 87} 88 89void Response::ReplyWithErrorNotFound() { 90 ReplyWithError(chromeos::http::status_code::NotFound, "Not Found"); 91} 92 93void Response::SendResponse() { 94 CHECK(!reply_sent_) << "Response already sent"; 95 reply_sent_ = true; 96 handler_->CompleteRequest(request_id_, status_code_, headers_, data_); 97} 98 99} // namespace libwebserv 100