MySQL 9.1.0
Source Code Documentation
rest_api_utils.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQLROUTER_REST_API_UTILS_INCLUDED
27#define MYSQLROUTER_REST_API_UTILS_INCLUDED
28
29#include <chrono>
30#include <map>
31#include <string>
32
33#ifdef RAPIDJSON_NO_SIZETYPEDEFINE
34#include "my_rapidjson_size_t.h"
35#endif
36
37#include <rapidjson/document.h>
38
39#include "http/base/request.h"
40#include "mysql/harness/utility/string.h" // string_format()
41
42/**
43 * send a JsonProblem HTTP response.
44 *
45 * RFC 7807 defines `application/problem+json`:
46 *
47 * - title
48 * - description
49 * - instance
50 * - detail
51 *
52 * @param req HttpRequest object to send error-msg
53 * @param status_code HTTP Status code of the problem message
54 * @param fields fields on the problem message
55 */
57 HttpStatusCode::key_type status_code,
58 const std::map<std::string, std::string> &fields);
59
60/**
61 * ensure HTTP method is allowed.
62 *
63 * sends HTTP-response with status 405 if method is not allowed and sets `Allow`
64 * HTTP header.
65 *
66 * @returns success
67 * @retval true if HTTP method is allowed
68 * @retval false if HTTP is not allowed and HTTP response has been sent
69 */
71 HttpMethod::Bitset allowed_methods);
72
73/**
74 * ensure request is authenticated.
75 *
76 * sends HTTP-response with status 401 if authentication was not successful.
77 *
78 * @returns success
79 * @retval true if request is authenticaticated
80 * @retval false if authentication was not successful and HTTP response has been
81 * sent
82 */
83bool ensure_auth(http::base::Request &req, const std::string require_realm);
84
85/**
86 * ensure request has no parameters.
87 *
88 * sends HTTP-response with status 400 if request contained a query string.
89 *
90 * @returns success
91 * @retval true if request did not contain a query-string
92 * @retval false if request contained a query-string and HTTP response has
93 * been sent
94 */
96
97/**
98 * send a JsonProblem "Not Found" error.
99 *
100 * @param req HttpRequest object to send error-msg
101 */
103
104/**
105 * ensure resource has modified since client received it.
106 *
107 * sends HTTP-response with status 304 if client has a newer version that
108 *
109 * @returns success
110 * @retval true if resource is modified since client received it.
111 * @retval false if client has the same resource and HTTP response has been
112 * sent
113 */
114bool ensure_modified_since(http::base::Request &req, time_t last_modified);
115
116/**
117 * send json document as HTTP response.
118 *
119 * Content-Type must be sent before the function is called.
120 *
121 * @param req HttpRequest object to send error-msg
122 * @param status_code HTTP Status code of the problem message
123 * @param json_doc json document to send as response
124 */
126 HttpStatusCode::key_type status_code,
127 const rapidjson::Document &json_doc);
128
129/**
130 * format a timepoint as json-value (date-time format).
131 */
132template <class Encoding, class AllocatorType>
133rapidjson::GenericValue<Encoding, AllocatorType> json_value_from_timepoint(
134 std::chrono::time_point<std::chrono::system_clock> tp,
135 AllocatorType &allocator) {
136 time_t cur = std::chrono::system_clock::to_time_t(tp);
137 struct tm cur_gmtime;
138#ifdef _WIN32
139 gmtime_s(&cur_gmtime, &cur);
140#else
141 gmtime_r(&cur, &cur_gmtime);
142#endif
143 auto usec = std::chrono::duration_cast<std::chrono::microseconds>(
144 tp - std::chrono::system_clock::from_time_t(cur));
145
146 std::string iso8601_datetime{mysql_harness::utility::string_format(
147 "%04d-%02d-%02dT%02d:%02d:%02d.%06ldZ", cur_gmtime.tm_year + 1900,
148 cur_gmtime.tm_mon + 1, cur_gmtime.tm_mday, cur_gmtime.tm_hour,
149 cur_gmtime.tm_min, cur_gmtime.tm_sec,
150 // cast to long int as it is "longlong" on 32bit, and "long" on
151 // 64bit platforms, but we only have a range of 0-999
152 static_cast<long int>(usec.count()))};
153
154 return {iso8601_datetime.c_str(), iso8601_datetime.size(), allocator};
155}
156
157#endif
Definition: request.h:44
Define rapidjson::SizeType to be std::uint64_t.
std::bitset< Pos::_LAST+1 > Bitset
Definition: method.h:57
int key_type
Definition: status_code.h:36
HARNESS_EXPORT std::string string_format(const char *format,...)
Definition: utilities.cc:64
bool ensure_no_params(http::base::Request &req)
ensure request has no parameters.
Definition: rest_api_utils.cc:145
bool ensure_auth(http::base::Request &req, const std::string require_realm)
ensure request is authenticated.
Definition: rest_api_utils.cc:129
rapidjson::GenericValue< Encoding, AllocatorType > json_value_from_timepoint(std::chrono::time_point< std::chrono::system_clock > tp, AllocatorType &allocator)
format a timepoint as json-value (date-time format).
Definition: rest_api_utils.h:133
void send_rfc7807_not_found_error(http::base::Request &req)
send a JsonProblem "Not Found" error.
Definition: rest_api_utils.cc:81
bool ensure_modified_since(http::base::Request &req, time_t last_modified)
ensure resource has modified since client received it.
Definition: rest_api_utils.cc:158
void send_json_document(http::base::Request &req, HttpStatusCode::key_type status_code, const rapidjson::Document &json_doc)
send json document as HTTP response.
Definition: rest_api_utils.cc:40
void send_rfc7807_error(http::base::Request &req, HttpStatusCode::key_type status_code, const std::map< std::string, std::string > &fields)
send a JsonProblem HTTP response.
Definition: rest_api_utils.cc:58
bool ensure_http_method(http::base::Request &req, HttpMethod::Bitset allowed_methods)
ensure HTTP method is allowed.
Definition: rest_api_utils.cc:89