UniSet @VERSION@
UHttpRequestHandler.h
1#ifndef DISABLE_REST_API
2/*
3 * Copyright (c) 2015 Pavel Vainerman.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation, version 2.1.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Lesser Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17// -------------------------------------------------------------------------
18#ifndef UHttpRequesrHandler_H_
19#define UHttpRequesrHandler_H_
20// -------------------------------------------------------------------------
21#include <memory>
22#include <vector>
23#include <string>
24#include <unordered_set>
25#include <Poco/Net/HTTPRequestHandler.h>
26#include <Poco/Net/HTTPRequestHandlerFactory.h>
27#include <Poco/Net/HTTPServerRequest.h>
28#include <Poco/Net/HTTPServerResponse.h>
29#include <Poco/Net/IPAddress.h>
30#include <Poco/URI.h>
31#include <Poco/JSON/Object.h>
32#include "ujson.h"
33#include "DebugStream.h"
34// -------------------------------------------------------------------------
73// -------------------------------------------------------------------------
74namespace uniset
75{
76 namespace UHttp
77 {
78 // текущая версия API
79 const std::string UHTTP_API_VERSION = "v2";
80
81 // -------------------------------------------------------------------------
87 {
88 // Ссылки на Poco объекты (всегда существуют)
89 Poco::Net::HTTPServerRequest& request;
90 Poco::Net::HTTPServerResponse& response;
91
92 // Распарсенные данные (заполняются в конструкторе один раз)
93 std::vector<std::string> path; // путь после ObjectName: ["sensors", "count"]
94 Poco::URI::QueryParameters params; // query string параметры
95 std::string objectName; // имя объекта из URL
96
97 // Конструктор — парсит URI один раз
98 HttpRequestContext(Poco::Net::HTTPServerRequest& req,
99 Poco::Net::HTTPServerResponse& resp);
100
101 // Минимум хелперов
102 size_t depth() const { return path.size(); }
103
104 const std::string& operator[](size_t i) const
105 {
106 static const std::string empty;
107 return (i < path.size()) ? path[i] : empty;
108 }
109
110 // Для логов и сообщений об ошибках
111 std::string pathString() const;
112 };
113
114 // Простая структура для описания подсети (CIDR)
116 {
117 Poco::Net::IPAddress address;
118 unsigned int prefixLength = { 0 };
119 bool isRange = { false };
120 Poco::Net::IPAddress rangeEnd;
121 };
122
123 using NetworkRules = std::vector<NetworkRule>;
124 using BearerTokens = std::unordered_set<std::string>;
125
126 // -------------------------------------------------------------------------
129 {
130 public:
131 IHttpRequest() {}
132 virtual ~IHttpRequest() {}
133
134 // Основной метод обработки запросов
135 // throw SystemError
136 virtual Poco::JSON::Object::Ptr httpRequest(const HttpRequestContext& ctx) = 0;
137
138 // Справка по командам объекта (отдельно, чтобы не забыть реализовать)
139 // throw SystemError
140 virtual Poco::JSON::Object::Ptr httpHelp(const Poco::URI::QueryParameters& p) = 0;
141 };
142
143 // -------------------------------------------------------------------------
146 {
147 public:
149 virtual ~IHttpRequestRegistry() {}
150
151 // Основной метод — берёт objectName из ctx
152 // throw SystemError, NameNotFound
153 virtual Poco::JSON::Object::Ptr httpRequest(const HttpRequestContext& ctx) = 0;
154
155 // Список объектов
156 // throw SystemError
157 virtual Poco::JSON::Array::Ptr httpGetObjectsList(const HttpRequestContext& ctx) = 0;
158
159 // Справка по объекту (диспетчеризация к конкретному объекту по ctx.objectName)
160 // throw SystemError, NameNotFound
161 virtual Poco::JSON::Object::Ptr httpHelpRequest(const HttpRequestContext& ctx) = 0;
162
170 virtual bool httpStaticRequest(
171 const std::string& path,
172 Poco::Net::HTTPServerRequest& req,
173 Poco::Net::HTTPServerResponse& resp)
174 {
175 return false; // По умолчанию: не обрабатываем
176 }
177 };
178
179 // -------------------------------------------------------------------------
181 public Poco::Net::HTTPRequestHandler
182 {
183 public:
184 UHttpRequestHandler( std::shared_ptr<IHttpRequestRegistry> _registry, const std::string& httpCORS_allow = "*",
185 const std::string& contentType="text/json; charset=UTF-8",
186 const NetworkRules& whitelist = NetworkRules(),
187 const NetworkRules& blacklist = NetworkRules(),
188 const NetworkRules& trustedProxies = NetworkRules(),
189 bool bearerRequired = false,
190 const BearerTokens& bearerTokens = BearerTokens());
191
192 virtual void handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) override;
193
194 static bool match(const Poco::Net::IPAddress& ip, const NetworkRule& rule);
195 static bool inRules(const Poco::Net::IPAddress& ip, const NetworkRules& rules);
196 static bool isDenied(const Poco::Net::IPAddress& ip,
197 const NetworkRules& whitelist,
198 const NetworkRules& blacklist);
199 static bool validateBearer(const std::string& header, const BearerTokens& tokens);
200
201 private:
202
203 std::shared_ptr<IHttpRequestRegistry> registry;
204 std::shared_ptr<DebugStream> log;
205 const std::string httpCORS_allow = { "*" };
206 std::string httpDefaultContentType = {"text/json; charset=UTF-8" };
207 NetworkRules whitelist;
208 NetworkRules blacklist;
209 NetworkRules trustedProxies;
210 bool bearerRequired = { false };
211 BearerTokens bearerTokens;
212 };
213 // -------------------------------------------------------------------------
215 public Poco::Net::HTTPRequestHandlerFactory
216 {
217 public:
218
219 UHttpRequestHandlerFactory( std::shared_ptr<IHttpRequestRegistry>& _registry );
220
221 virtual Poco::Net::HTTPRequestHandler* createRequestHandler( const Poco::Net::HTTPServerRequest& ) override;
222
223 // (CORS): Access-Control-Allow-Origin. Default: *
224 void setCORS_allow( const std::string& allow );
225 void setDefaultContentType( const std::string& ct );
226 void setWhitelist( const NetworkRules& rules );
227 void setBlacklist( const NetworkRules& rules );
228 void setTrustedProxies( const NetworkRules& rules );
229 void setBearerRequired( bool required );
230 void setBearerTokens( const BearerTokens& tokens );
231 private:
232 std::shared_ptr<IHttpRequestRegistry> registry;
233 std::string httpCORS_allow = { "*" };
234 std::string httpDefaultContentType = {"text/json; charset=UTF-8" };
235 NetworkRules whitelist;
236 NetworkRules blacklist;
237 NetworkRules trustedProxies;
238 bool bearerRequired = { false };
239 BearerTokens bearerTokens;
240 };
241 }
242 // -------------------------------------------------------------------------
243} // end of uniset namespace
244// -------------------------------------------------------------------------
245#endif // UHttpRequesrHandler_H_
246// -------------------------------------------------------------------------
247#endif
Definition UHttpRequestHandler.h:129
Definition UHttpRequestHandler.h:146
virtual bool httpStaticRequest(const std::string &path, Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp)
Definition UHttpRequestHandler.h:170
Definition UHttpRequestHandler.h:216
Definition UHttpRequestHandler.h:182
Definition AccessConfig.h:30
Definition UHttpRequestHandler.h:87
Definition UHttpRequestHandler.h:116