blob: 4f497f81579e030978f3fd600a7b28c0fc4ca299 [file] [log] [blame]
// Copyright 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "libwebserv/binder_response.h"
#include <base/bind.h>
#include <brillo/bind_lambda.h>
#include <brillo/http/http_request.h>
#include <brillo/mime_utils.h>
#include <brillo/streams/file_stream.h>
#include <brillo/streams/stream_utils.h>
using std::pair;
using std::string;
using std::vector;
using android::sp;
using android::binder::Status;
using android::webservd::IHttpRequest;
namespace libwebserv {
BinderResponse::BinderResponse(const sp<IHttpRequest>& request)
: request_(request) {}
void BinderResponse::AddHeaders(const vector<pair<string, string>>& headers) {
headers_.insert(headers.begin(), headers.end());
}
void BinderResponse::Reply(int status_code,
brillo::StreamPtr data_stream,
const std::string& mime_type) {
vector<string> headers;
AddHeader(brillo::http::response_header::kContentType, mime_type);
android::base::unique_fd data_out;
for (const auto& header : headers_) {
headers.emplace_back(header.first);
headers.emplace_back(header.second);
}
int64_t data_size = -1;
if (data_stream->CanGetSize()) {
data_size = data_stream->GetRemainingSize();
}
if (!request_->Respond(status_code, headers,
data_size, &data_out).isOk()) {
LOG(WARNING) << "Could not communicate response to server.";
return;
}
int dupfd = dup(data_out.get());
auto dest_stream =
brillo::FileStream::FromFileDescriptor(dupfd, true, nullptr);
CHECK(dest_stream);
// Dummy callbacks for success/error of data-copy operation. We ignore both
// notifications here.
auto on_success = [](brillo::StreamPtr, brillo::StreamPtr, uint64_t) {};
auto on_error = [](brillo::StreamPtr, brillo::StreamPtr,
const brillo::Error*) {};
brillo::stream_utils::CopyData(
std::move(data_stream), std::move(dest_stream), base::Bind(on_success),
base::Bind(on_error));
}
} // namespace libwebserv