| // Copyright 2015 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "webservd/dbus_request_handler.h" |
| |
| #include <tuple> |
| #include <vector> |
| |
| #include <base/bind.h> |
| #include <base/bind_helpers.h> |
| #include <base/strings/string_util.h> |
| #include <brillo/http/http_request.h> |
| #include <brillo/mime_utils.h> |
| |
| #include "libwebserv/dbus-proxies.h" |
| #include "webservd/request.h" |
| #include "webservd/server.h" |
| |
| namespace webservd { |
| |
| namespace { |
| |
| constexpr int kDbusTimeoutInMsec = 50 * 1000; |
| |
| void OnError(Request* request, bool debug, brillo::Error* error) { |
| std::string error_msg{"Internal Server Error"}; |
| if (debug) { |
| error_msg += "\r\n" + error->GetMessage(); |
| } |
| if (!request) { |
| LOG(ERROR) << "Invalid Request Instance"; |
| return; |
| } |
| request->Complete(brillo::http::status_code::InternalServerError, {}, |
| brillo::mime::text::kPlain, error_msg); |
| } |
| |
| bool CompleteRequestIfInvalid(Request* request, const std::string& value) { |
| if (base::IsStringUTF8(value)) |
| return false; |
| |
| request->Complete(brillo::http::status_code::BadRequest, {}, |
| brillo::mime::text::kPlain, "Invalid Characters\n"); |
| return true; |
| } |
| |
| } // anonymous namespace |
| |
| DBusRequestHandler::DBusRequestHandler(Server* server, |
| RequestHandlerProxy* handler_proxy) |
| : server_{server}, handler_proxy_{handler_proxy} {} |
| |
| void DBusRequestHandler::HandleRequest(Request* request, |
| const std::string& src) { |
| std::vector<std::tuple<std::string, std::string>> headers; |
| for (const auto& pair : request->GetHeaders()) { |
| if (CompleteRequestIfInvalid(request, pair.second)) |
| return; |
| headers.emplace_back(pair.first, pair.second); |
| } |
| headers.emplace_back("Source-Host", src); |
| |
| std::vector< |
| std::tuple<int32_t, std::string, std::string, std::string, std::string>> |
| files; |
| int32_t index = 0; |
| for (const auto& file : request->GetFileInfo()) { |
| files.emplace_back(index++, file->field_name, file->file_name, |
| file->content_type, file->transfer_encoding); |
| } |
| |
| std::vector<std::tuple<bool, std::string, std::string>> params; |
| for (const auto& pair : request->GetDataGet()) { |
| if (CompleteRequestIfInvalid(request, pair.second)) |
| return; |
| params.emplace_back(false, pair.first, pair.second); |
| } |
| |
| for (const auto& pair : request->GetDataPost()) { |
| if (CompleteRequestIfInvalid(request, pair.second)) |
| return; |
| params.emplace_back(true, pair.first, pair.second); |
| } |
| |
| auto error_callback = base::Bind(&OnError, base::Unretained(request), |
| server_->GetConfig().use_debug); |
| |
| auto request_id = std::make_tuple( |
| request->GetProtocolHandlerID(), request->GetRequestHandlerID(), |
| request->GetID(), request->GetURL(), request->GetMethod()); |
| |
| base::ScopedFD body_data_pipe(request->GetBodyDataFileDescriptor()); |
| handler_proxy_->ProcessRequestAsync(request_id, headers, params, files, |
| body_data_pipe.get(), base::DoNothing(), |
| error_callback, kDbusTimeoutInMsec); |
| } |
| |
| } // namespace webservd |