| // 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 |