Kea 1.9.11
ca_response_creator.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2020 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
7#include <config.h>
8
9#include <agent/ca_cfg_mgr.h>
11#include <agent/ca_controller.h>
12#include <agent/ca_process.h>
14#include <cc/data.h>
16#include <hooks/hooks_log.h>
17#include <hooks/hooks_manager.h>
19#include <http/response_json.h>
20#include <boost/pointer_cast.hpp>
21#include <iostream>
22
23using namespace isc::data;
24using namespace isc::hooks;
25using namespace isc::http;
26
27namespace {
28
30struct CtrlAgentHooks {
31 int hook_index_auth_;
32 int hook_index_response_;
33
35 CtrlAgentHooks() {
36 hook_index_auth_ = HooksManager::registerHook("auth");
37 hook_index_response_ = HooksManager::registerHook("response");
38 }
39};
40
41} // end of anonymous namespace.
42
43// Declare a Hooks object. As this is outside any function or method, it
44// will be instantiated (and the constructor run) when the module is loaded.
45// As a result, the hook indexes will be defined before any method in this
46// module is called.
47CtrlAgentHooks Hooks;
48
49namespace isc {
50namespace agent {
51
54 return (HttpRequestPtr(new PostHttpRequestJson()));
55}
56
60 const HttpStatusCode& status_code) const {
61 HttpResponsePtr response = createStockHttpResponseInternal(request, status_code);
62 response->finalize();
63 return (response);
64}
65
67CtrlAgentResponseCreator::
68createStockHttpResponseInternal(const HttpRequestPtr& request,
69 const HttpStatusCode& status_code) const {
70 // The request hasn't been finalized so the request object
71 // doesn't contain any information about the HTTP version number
72 // used. But, the context should have this data (assuming the
73 // HTTP version is parsed ok).
74 HttpVersion http_version(request->context()->http_version_major_,
75 request->context()->http_version_minor_);
76 // We only accept HTTP version 1.0 or 1.1. If other version number is found
77 // we fall back to HTTP/1.0.
78 if ((http_version < HttpVersion(1, 0)) || (HttpVersion(1, 1) < http_version)) {
79 http_version.major_ = 1;
80 http_version.minor_ = 0;
81 }
82 // This will generate the response holding JSON content.
83 HttpResponsePtr response(new HttpResponseJson(http_version, status_code));
84 return (response);
85}
86
88CtrlAgentResponseCreator::
89createDynamicHttpResponse(HttpRequestPtr request) {
90 // First check authentication.
91 HttpResponseJsonPtr http_response;
92
93 // Context will hold the server configuration.
95
96 // There is a hierarchy of the objects through which we need to pass to get
97 // the configuration context. We may simplify this at some point but since
98 // we're in the singleton we want to make sure that we're using most current
99 // configuration.
100 boost::shared_ptr<CtrlAgentController> controller =
101 boost::dynamic_pointer_cast<CtrlAgentController>(CtrlAgentController::instance());
102 if (controller) {
103 CtrlAgentProcessPtr process = controller->getCtrlAgentProcess();
104 if (process) {
105 CtrlAgentCfgMgrPtr cfgmgr = process->getCtrlAgentCfgMgr();
106 if (cfgmgr) {
107 ctx = cfgmgr->getCtrlAgentCfgContext();
108 if (ctx) {
109 const HttpAuthConfigPtr& auth = ctx->getAuthConfig();
110 if (auth) {
111 // Check authentication.
112 http_response = auth->checkAuth(*this, request);
113 }
114 }
115 }
116 }
117 }
118
119 // Callout point for "auth".
120 if (HooksManager::calloutsPresent(Hooks.hook_index_auth_)) {
121 // Get callout handle.
122 CalloutHandlePtr callout_handle = request->getCalloutHandle();
123 ScopedCalloutHandleState callout_handle_state(callout_handle);
124
125 // Pass arguments.
126 callout_handle->setArgument("request", request);
127 callout_handle->setArgument("response", http_response);
128
129 // Call callouts.
130 HooksManager::callCallouts(Hooks.hook_index_auth_, *callout_handle);
131 callout_handle->getArgument("request", request);
132 callout_handle->getArgument("response", http_response);
133
134 // Ignore status as the HTTP response is used instead.
135 }
136
137 // The basic HTTP authentication check or a callout failed and
138 // left a response.
139 if (http_response) {
140 return (http_response);
141 }
142
143 // The request is always non-null, because this is verified by the
144 // createHttpResponse method. Let's try to convert it to the
145 // PostHttpRequestJson type as this is the type generated by the
146 // createNewHttpRequest. If the conversion result is null it means that
147 // the caller did not use createNewHttpRequest method to create this
148 // instance. This is considered an error in the server logic.
149 PostHttpRequestJsonPtr request_json =
150 boost::dynamic_pointer_cast<PostHttpRequestJson>(request);
151 if (!request_json) {
152 // Notify the client that we have a problem with our server.
153 return (createStockHttpResponse(request, HttpStatusCode::INTERNAL_SERVER_ERROR));
154 }
155
156 // We have already checked that the request is finalized so the call
157 // to getBodyAsJson must not trigger an exception.
158 ConstElementPtr command = request_json->getBodyAsJson();
159
160 // Process command doesn't generate exceptions but can possibly return
161 // null response, if the handler is not implemented properly. This is
162 // again an internal server issue.
164 if (!response) {
165 // Notify the client that we have a problem with our server.
166 return (createStockHttpResponse(request, HttpStatusCode::INTERNAL_SERVER_ERROR));
167 }
168 // The response is ok, so let's create new HTTP response with the status OK.
169 http_response = boost::dynamic_pointer_cast<
170 HttpResponseJson>(createStockHttpResponseInternal(request, HttpStatusCode::OK));
171 http_response->setBodyAsJson(response);
172 http_response->finalize();
173
174 // Callout point for "response".
175 if (HooksManager::calloutsPresent(Hooks.hook_index_response_)) {
176 // Get callout handle.
177 CalloutHandlePtr callout_handle = request->getCalloutHandle();
178 ScopedCalloutHandleState callout_handle_state(callout_handle);
179
180 // Pass arguments.
181 callout_handle->setArgument("request", request);
182 callout_handle->setArgument("response", http_response);
183
184 // Call callouts.
185 HooksManager::callCallouts(Hooks.hook_index_response_,
186 *callout_handle);
187 callout_handle->getArgument("response", http_response);
188
189 // Ignore status as the HTTP response is used instead.
190 }
191
192 return (http_response);
193}
194
195} // end of namespace isc::agent
196} // end of namespace isc
CtrlAgentHooks Hooks
static CtrlAgentCommandMgr & instance()
Returns sole instance of the Command Manager.
virtual isc::data::ConstElementPtr processCommand(const isc::data::ConstElementPtr &cmd)
Triggers command processing.
static process::DControllerBasePtr & instance()
Static singleton instance method.
virtual http::HttpResponsePtr createStockHttpResponse(const http::HttpRequestPtr &request, const http::HttpStatusCode &status_code) const
Creates stock HTTP response.
virtual http::HttpRequestPtr createNewHttpRequest() const
Create a new request.
Wrapper class around callout handle which automatically resets handle's state.
Represents HTTP response with JSON content.
Definition: response_json.h:34
void setBodyAsJson(const data::ConstElementPtr &json_body)
Generates JSON content from the data structures represented as data::ConstElementPtr.
Represents HTTP POST request with JSON body.
boost::shared_ptr< CtrlAgentCfgContext > CtrlAgentCfgContextPtr
Pointer to a configuration context.
Definition: ca_cfg_mgr.h:21
boost::shared_ptr< CtrlAgentProcess > CtrlAgentProcessPtr
Defines a shared pointer to CtrlAgentProcess.
Definition: ca_process.h:150
boost::shared_ptr< CtrlAgentCfgMgr > CtrlAgentCfgMgrPtr
Defines a shared pointer to CtrlAgentCfgMgr.
Definition: ca_cfg_mgr.h:311
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
HttpStatusCode
HTTP status codes (cf RFC 2068)
Definition: response.h:30
boost::shared_ptr< PostHttpRequestJson > PostHttpRequestJsonPtr
Pointer to PostHttpRequestJson.
boost::shared_ptr< HttpAuthConfig > HttpAuthConfigPtr
Type of shared pointers to HTTP authentication configuration.
Definition: auth_config.h:79
boost::shared_ptr< HttpResponseJson > HttpResponseJsonPtr
Pointer to the HttpResponseJson object.
Definition: response_json.h:24
boost::shared_ptr< HttpResponse > HttpResponsePtr
Pointer to the HttpResponse object.
Definition: response.h:78
boost::shared_ptr< HttpRequest > HttpRequestPtr
Pointer to the HttpRequest object.
Definition: request.h:27
Defines the logger used by the top-level component of kea-lfc.
HTTP protocol version.
Definition: http_types.h:14