blob: 2ae5910c759c7b254a2b430adec03f96037eedf4 [file] [log] [blame]
Vitaly Buka974647f2015-08-02 20:57:43 -07001// Copyright 2015 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 "buffet/webserv_client.h"
6
7#include <memory>
8#include <string>
9
10#include <libwebserv/protocol_handler.h>
11#include <libwebserv/request.h>
12#include <libwebserv/response.h>
13#include <libwebserv/server.h>
14
15#include "buffet/dbus_constants.h"
16
17namespace buffet {
18
19namespace {
20
21class RequestImpl : public weave::HttpServer::Request {
22 public:
23 explicit RequestImpl(std::unique_ptr<libwebserv::Request> request)
24 : request_{std::move(request)} {}
25 ~RequestImpl() override {}
26
27 // HttpServer::Request implementation.
28 const std::string& GetPath() const override { return request_->GetPath(); }
29 std::string GetFirstHeader(const std::string& name) const override {
30 return request_->GetFirstHeader(name);
31 }
32 const std::vector<uint8_t>& GetData() const override {
33 return request_->GetData();
34 }
35
36 private:
37 std::unique_ptr<libwebserv::Request> request_;
38
39 DISALLOW_COPY_AND_ASSIGN(RequestImpl);
40};
41
42} // namespace
43
44WebServClient::~WebServClient() {
45 web_server_->Disconnect();
46}
47
48void WebServClient::AddOnStateChangedCallback(
49 const OnStateChangedCallback& callback) {
50 on_state_changed_callbacks_.push_back(callback);
51 callback.Run(*this);
52}
53
54void WebServClient::AddRequestHandler(const std::string& path_prefix,
55 const OnRequestCallback& callback) {
56 web_server_->GetDefaultHttpHandler()->AddHandlerCallback(
57 path_prefix, "", base::Bind(&WebServClient::OnRequest,
58 weak_ptr_factory_.GetWeakPtr(), callback));
59 web_server_->GetDefaultHttpsHandler()->AddHandlerCallback(
60 path_prefix, "", base::Bind(&WebServClient::OnRequest,
61 weak_ptr_factory_.GetWeakPtr(), callback));
62}
63
64uint16_t WebServClient::GetHttpPort() const {
65 return http_port_;
66}
67
68uint16_t WebServClient::GetHttpsPort() const {
69 return https_port_;
70}
71
72const chromeos::Blob& WebServClient::GetHttpsCertificateFingerprint() const {
73 return certificate_;
74}
75
76WebServClient::WebServClient(
77 const scoped_refptr<dbus::Bus>& bus,
78 chromeos::dbus_utils::AsyncEventSequencer* sequencer) {
79 web_server_.reset(new libwebserv::Server);
80 web_server_->OnProtocolHandlerConnected(
81 base::Bind(&WebServClient::OnProtocolHandlerConnected,
82 weak_ptr_factory_.GetWeakPtr()));
83 web_server_->OnProtocolHandlerDisconnected(
84 base::Bind(&WebServClient::OnProtocolHandlerDisconnected,
85 weak_ptr_factory_.GetWeakPtr()));
86
87 web_server_->Connect(bus, buffet::kServiceName,
88 sequencer->GetHandler("Server::Connect failed.", true),
89 base::Bind(&base::DoNothing),
90 base::Bind(&base::DoNothing));
91}
92
93void WebServClient::OnRequest(const OnRequestCallback& callback,
94 std::unique_ptr<libwebserv::Request> request,
95 std::unique_ptr<libwebserv::Response> response) {
96 callback.Run(
97 RequestImpl{std::move(request)},
98 base::Bind(&WebServClient::OnResponse, weak_ptr_factory_.GetWeakPtr(),
99 base::Passed(&response)));
100}
101
102void WebServClient::OnResponse(std::unique_ptr<libwebserv::Response> response,
103 int status_code,
104 const std::string& data,
105 const std::string& mime_type) {
106 response->Reply(status_code, data.data(), data.size(), mime_type);
107}
108
109void WebServClient::OnProtocolHandlerConnected(
110 libwebserv::ProtocolHandler* protocol_handler) {
111 if (protocol_handler->GetName() == libwebserv::ProtocolHandler::kHttp) {
112 http_port_ = *protocol_handler->GetPorts().begin();
113 } else if (protocol_handler->GetName() ==
114 libwebserv::ProtocolHandler::kHttps) {
115 https_port_ = *protocol_handler->GetPorts().begin();
116 certificate_ = protocol_handler->GetCertificateFingerprint();
117 }
118 for (const auto& cb : on_state_changed_callbacks_)
119 cb.Run(*this);
120}
121
122void WebServClient::OnProtocolHandlerDisconnected(
123 libwebserv::ProtocolHandler* protocol_handler) {
124 if (protocol_handler->GetName() == libwebserv::ProtocolHandler::kHttp) {
125 http_port_ = 0;
126 } else if (protocol_handler->GetName() ==
127 libwebserv::ProtocolHandler::kHttps) {
128 https_port_ = 0;
129 certificate_.clear();
130 }
131 for (const auto& cb : on_state_changed_callbacks_)
132 cb.Run(*this);
133}
134
135} // namespace buffet