Kea  2.1.7-git
http_control_socket.cc
Go to the documentation of this file.
1 // Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
9 
10 #include <config.h>
11 
13 #include <cc/command_interpreter.h>
14 #include <asiolink/asio_wrapper.h>
15 #include <asiolink/io_service.h>
16 #include <asiolink/tls_socket.h>
17 #include <http/client.h>
18 #include <http/post_request_json.h>
19 #include <http/response_json.h>
20 #include <config/timeouts.h>
21 
22 using namespace std;
23 using namespace isc::asiolink;
24 using namespace isc::config;
25 using namespace isc::data;
26 using namespace isc::http;
27 
28 namespace isc {
29 namespace netconf {
30 
31 template <> ControlSocketBasePtr
32 createControlSocket<CfgControlSocket::Type::HTTP>(CfgControlSocketPtr ctrl_sock) {
33  return (HttpControlSocketPtr(new HttpControlSocket(ctrl_sock)));
34 }
35 
36 HttpControlSocket::HttpControlSocket(CfgControlSocketPtr ctrl_sock)
37  : ControlSocketBase(ctrl_sock) {
38 }
39 
41 HttpControlSocket::configGet(const string& service) {
42  if (service == "ca") {
43  return (sendCommand(createCommand("config-get")));
44  } else {
45  return (sendCommand(createCommand("config-get", service)));
46  }
47 }
48 
50 HttpControlSocket::configTest(ConstElementPtr config, const string& service) {
51  if (service == "ca") {
52  return (sendCommand(createCommand("config-test", config)));
53  } else {
54  return (sendCommand(createCommand("config-test", config, service)));
55  }
56 }
57 
59 HttpControlSocket::configSet(ConstElementPtr config, const string& service) {
60  if (service == "ca") {
61  return (sendCommand(createCommand("config-set", config)));
62  } else {
63  return (sendCommand(createCommand("config-set", config, service)));
64  }
65 }
66 
68 HttpControlSocket::sendCommand(ConstElementPtr command) {
69  PostHttpRequestJsonPtr request;
70  request.reset(new PostHttpRequestJson(HttpRequest::Method::HTTP_POST,
71  "/",
72  HttpVersion(1, 1)));
73  request->setBodyAsJson(command);
74  try {
75  request->finalize();
76  } catch (const std::exception& ex) {
77  isc_throw(ControlSocketError, "failed to create request: "
78  << ex.what());
79  }
80 
81  IOServicePtr io_service(new IOService());
82  HttpClient client(*io_service);
83  boost::system::error_code received_ec;
84  string receive_errmsg;
85  HttpResponseJsonPtr response(new HttpResponseJson());
86 
87  client.asyncSendRequest(getUrl(), TlsContextPtr(), request, response,
88  [&io_service, &received_ec, &receive_errmsg]
89  (const boost::system::error_code& ec,
90  const HttpResponsePtr&, const string& errmsg) {
91  // Capture error code and message.
92  received_ec = ec;
93  receive_errmsg = errmsg;
94  // Got the IO service so stop IO service.
95  // This causes to stop IO service when
96  // all handlers have been invoked.
97  io_service->stopWork();
98  },
100 
101  // Perform this synchronously.
102  io_service->run();
103 
104  if (received_ec) {
105  // Got an error code.
106  isc_throw(ControlSocketError, "communication error (code): "
107  << received_ec.message());
108  }
109 
110  if (!receive_errmsg.empty()) {
111  // Got an error message.
112  isc_throw(ControlSocketError, "communication error (message): "
113  << receive_errmsg);
114  }
115 
116  if (!response) {
117  // Failed to get the answer.
118  isc_throw(ControlSocketError, "empty response");
119  }
120 
121  try {
122  return (response->getBodyAsJson());
123  } catch (const std::exception& ex) {
124  isc_throw(ControlSocketError, "unparsable response: " << ex.what());
125  }
126 }
127 
128 } // namespace netconf
129 } // namespace isc
130 
Exception thrown when the error during communication.
Represents HTTP POST request with JSON body.
Contains declarations for HTTP control socket communication.
boost::shared_ptr< HttpControlSocket > HttpControlSocketPtr
Type definition for the pointer to the HttpControlSocket.
void asyncSendRequest(const Url &url, const asiolink::TlsContextPtr &tls_context, const HttpRequestPtr &request, const HttpResponsePtr &response, const RequestHandler &request_callback, const RequestTimeout &request_timeout=RequestTimeout(10000), const ConnectHandler &connect_callback=ConnectHandler(), const HandshakeHandler &handshake_callback=HandshakeHandler(), const CloseHandler &close_callback=CloseHandler())
Queues new asynchronous HTTP request for a given URL.
Definition: client.cc:1966
boost::shared_ptr< HttpResponseJson > HttpResponseJsonPtr
Pointer to the HttpResponseJson object.
Definition: response_json.h:24
boost::shared_ptr< ControlSocketBase > ControlSocketBasePtr
Type definition for the pointer to the ControlSocketBase.
HTTP request/response timeout value.
Definition: client.h:90
Base class for control socket communication.
HTTP protocol version.
Definition: http_types.h:14
STL namespace.
Class for control socket communication over HTTP socket.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
virtual data::ConstElementPtr configTest(data::ConstElementPtr config, const std::string &service)
Test configuration.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< PostHttpRequestJson > PostHttpRequestJsonPtr
Pointer to PostHttpRequestJson.
boost::shared_ptr< HttpResponse > HttpResponsePtr
Pointer to the HttpResponse object.
Definition: response.h:78
ConstElementPtr createCommand(const std::string &command)
Creates a standard command message with no argument (of the form { "command": "my_command" }) ...
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
constexpr long TIMEOUT_AGENT_FORWARD_COMMAND
Timeout for the Control Agent to forward command to a Kea server, e.g.
Definition: timeouts.h:31
Represents HTTP response with JSON content.
Definition: response_json.h:34
HTTP client class.
Definition: client.h:87
Defines the logger used by the top-level component of kea-lfc.
virtual data::ConstElementPtr configSet(data::ConstElementPtr config, const std::string &service)
Set configuration.
virtual data::ConstElementPtr configGet(const std::string &service)
Get configuration.
This file contains several functions and constants that are used for handling commands and responses ...
const isc::http::Url getUrl() const
Returns the HTTP server URL.
boost::shared_ptr< CfgControlSocket > CfgControlSocketPtr
Defines a pointer for CfgControlSocket instances.