response.cc revision 75d6da24dedcbc090d23de60c4f1637c3a54b392
1// Copyright 2015 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include <libwebserv/response.h> 16 17#include <algorithm> 18 19#include <base/json/json_writer.h> 20#include <base/logging.h> 21#include <base/values.h> 22#include <brillo/http/http_request.h> 23#include <brillo/mime_utils.h> 24#include <brillo/streams/memory_stream.h> 25#include <brillo/strings/string_utils.h> 26#include <libwebserv/protocol_handler.h> 27 28namespace libwebserv { 29 30Response::Response(ProtocolHandler* handler, const std::string& request_id) 31 : handler_{handler}, request_id_{request_id} { 32} 33 34Response::~Response() { 35 if (!reply_sent_) { 36 ReplyWithError(brillo::http::status_code::InternalServerError, 37 "Internal server error"); 38 } 39} 40 41void Response::AddHeader(const std::string& header_name, 42 const std::string& value) { 43 headers_.emplace(header_name, value); 44} 45 46void Response::AddHeaders( 47 const std::vector<std::pair<std::string, std::string>>& headers) { 48 headers_.insert(headers.begin(), headers.end()); 49} 50 51void Response::Reply(int status_code, 52 brillo::StreamPtr data_stream, 53 const std::string& mime_type) { 54 CHECK(data_stream); 55 status_code_ = status_code; 56 data_stream_ = std::move(data_stream); 57 AddHeader(brillo::http::response_header::kContentType, mime_type); 58 SendResponse(); 59} 60 61void Response::ReplyWithText(int status_code, 62 const std::string& text, 63 const std::string& mime_type) { 64 Reply(status_code, brillo::MemoryStream::OpenCopyOf(text, nullptr), 65 mime_type); 66} 67 68void Response::ReplyWithJson(int status_code, const base::Value* json) { 69 std::string text; 70 base::JSONWriter::WriteWithOptions( 71 *json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &text); 72 std::string mime_type = brillo::mime::AppendParameter( 73 brillo::mime::application::kJson, 74 brillo::mime::parameters::kCharset, 75 "utf-8"); 76 ReplyWithText(status_code, text, mime_type); 77} 78 79void Response::ReplyWithJson(int status_code, 80 const std::map<std::string, std::string>& json) { 81 base::DictionaryValue json_value; 82 for (const auto& pair : json) { 83 json_value.SetString(pair.first, pair.second); 84 } 85 ReplyWithJson(status_code, &json_value); 86} 87 88void Response::Redirect(int status_code, const std::string& redirect_url) { 89 AddHeader(brillo::http::response_header::kLocation, redirect_url); 90 ReplyWithError(status_code, ""); 91} 92 93void Response::ReplyWithError(int status_code, const std::string& error_text) { 94 status_code_ = status_code; 95 data_stream_ = brillo::MemoryStream::OpenCopyOf(error_text, nullptr); 96 SendResponse(); 97} 98 99void Response::ReplyWithErrorNotFound() { 100 ReplyWithError(brillo::http::status_code::NotFound, "Not Found"); 101} 102 103void Response::SendResponse() { 104 CHECK(!reply_sent_) << "Response already sent"; 105 reply_sent_ = true; 106 handler_->CompleteRequest(request_id_, status_code_, headers_, 107 std::move(data_stream_)); 108} 109 110} // namespace libwebserv 111