-namespace pdns::rust::web::rec {
+namespace pdns::rust::web::rec
+{
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
-#define WRAPPER(A) void A(const Request& /* unused */ , Response& /* unused */) { }
+#define WRAPPER(A) \
+ void A(const Request& /* unused */, Response& /* unused */) {}
-WRAPPER(jsonstat)
+WRAPPER(apiDiscovery)
+WRAPPER(apiDiscoveryV1)
+WRAPPER(apiServer)
WRAPPER(apiServerCacheFlush)
+WRAPPER(apiServerConfig)
+WRAPPER(apiServerConfigAllowFromGET)
+WRAPPER(apiServerConfigAllowFromPUT)
+WRAPPER(apiServerConfigAllowNotifyFromGET)
+WRAPPER(apiServerConfigAllowNotifyFromPUT)
WRAPPER(apiServerDetail)
+WRAPPER(apiServerRPZStats)
+WRAPPER(apiServerSearchData)
+WRAPPER(apiServerStatistics)
+WRAPPER(apiServerZoneDetailDELETE)
+WRAPPER(apiServerZoneDetailGET)
+WRAPPER(apiServerZoneDetailPUT)
WRAPPER(apiServerZonesGET)
WRAPPER(apiServerZonesPOST)
+WRAPPER(jsonstat)
WRAPPER(prometheusMetrics)
WRAPPER(serveStuff)
-WRAPPER(apiServerStatistics)
#undef WRAPPER
}
# with an rust/src/lib.rs.h that does not contain e.g. field name or field type changes.
#
# Use patterns to avoid having two instances of generate run simultaneously, a well-known hack for GNU make
-cxxsettings-generated%cc rust/src/lib%rs rust/src/web%rs: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst
+cxxsettings-generated%cc rust/src/lib%rs: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst
@if test "$(PYTHON)" = ":"; then echo "Settings table table.py has changed, python is needed to regenerate the related settings files but python was not found. Please install python and re-run configure"; exit 1; fi
@if ! $(PYTHON) --version | grep -q "Python 3"; then echo $(PYTHON) should be at least version 3. Please install python 3 and re-run configure; exit 1; fi
$(MAKE) -C rust clean
src/web.rs
# should actually end up in a target specific dir...
-libsettings.a lib.rs.h: src/web.rs src/bridge.rs src/lib.rs src/helpers.rs Cargo.toml Cargo.lock build.rs
+libsettings.a lib.rs.h web.rs.h: src/web.rs src/bridge.rs src/lib.rs src/helpers.rs Cargo.toml Cargo.lock build.rs
SYSCONFDIR=$(sysconfdir) NODCACHEDIRNOD=$(localstatedir)/nod NODCACHEDIRUDR=$(localstatedir)/udr $(CARGO) build --release $(RUST_TARGET) --target-dir=$(builddir)/target --manifest-path ${srcdir}/Cargo.toml
cp target/$(RUSTC_TARGET_ARCH)/release/libsettings.a libsettings.a
cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/settings/src/lib.rs.h lib.rs.h
struct KeyValue;
struct Request;
struct Response;
+void apiServer(const Request& rustRequest, Response& rustResponse);
+void apiDiscovery(const Request& rustRequest, Response& rustResponse);
+void apiDiscoveryV1(const Request& rustRequest, Response& rustResponse);
void apiServerCacheFlush(const Request& rustRequest, Response& rustResponse);
void apiServerDetail(const Request& rustRequest, Response& rustResponse);
void apiServerStatistics(const Request& rustRequest, Response& rustResponse);
-void apiServerZonesGET(const Request& rustRequest,Response& rustResponse);
+void apiServerZonesGET(const Request& rustRequest, Response& rustResponse);
void apiServerZonesPOST(const Request& rustRequest, Response& rustResponse);
void prometheusMetrics(const Request& rustRequest, Response& rustResponse);
void serveStuff(const Request& rustRequest, Response& rustResponse);
void jsonstat(const Request& rustRequest, Response& rustResponse);
+void apiServerConfigAllowFromPUT(const Request& rustRequest, Response& rustResponse);
+void apiServerConfigAllowFromGET(const Request& rustRequest, Response& rustResponse);
+void apiServerConfigAllowNotifyFromGET(const Request& rustRequest, Response& rustResponse);
+void apiServerConfigAllowNotifyFromPUT(const Request& rustRequest, Response& rustResponse);
+void apiServerConfig(const Request& rustRequest, Response& rustResponse);
+void apiServerRPZStats(const Request& rustRequest, Response& rustResponse);
+void apiServerSearchData(const Request& rustRequest, Response& rustResponse);
+void apiServerZoneDetailGET(const Request& rustRequest, Response& rustResponse);
+void apiServerZoneDetailPUT(const Request& rustRequest, Response& rustResponse);
+void apiServerZoneDetailDELETE(const Request& rustRequest, Response& rustResponse);
}
);
}
(&Method::PUT, "/api/v1/servers/localhost/cache/flush") => {
+ request.body = rust_request.collect().await?.to_bytes().to_vec();
api_wrapper(
rustweb::apiServerCacheFlush as Func,
&request,
headers,
);
}
+ (&Method::PUT, "/api/v1/servers/localhost/config/allow-from") => {
+ request.body = rust_request.collect().await?.to_bytes().to_vec();
+ api_wrapper(
+ rustweb::apiServerConfigAllowFromPUT as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api/v1/servers/localhost/config/allow-from") => {
+ api_wrapper(
+ rustweb::apiServerConfigAllowFromGET as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::PUT, "/api/v1/servers/localhost/config/allow-notify-from") => {
+ request.body = rust_request.collect().await?.to_bytes().to_vec();
+ api_wrapper(
+ rustweb::apiServerConfigAllowNotifyFromPUT as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api/v1/servers/localhost/config/allow-notify-from") => {
+ api_wrapper(
+ rustweb::apiServerConfigAllowNotifyFromGET as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api/v1/servers/localhost/config") => {
+ api_wrapper(
+ rustweb::apiServerConfig as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api/v1/servers/localhost/rpzstatistics") => {
+ api_wrapper(
+ rustweb::apiServerRPZStats as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api/v1/servers/localhost/search-data") => {
+ api_wrapper(
+ rustweb::apiServerSearchData as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api/v1/servers/localhost/zones/") => {
+ api_wrapper(
+ rustweb::apiServerZoneDetailGET as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::PUT, "/api/v1/servers/localhost/zones/") => {
+ request.body = rust_request.collect().await?.to_bytes().to_vec();
+ api_wrapper(
+ rustweb::apiServerZoneDetailPUT as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::DELETE, "/api/v1/servers/localhost/zones/") => {
+ api_wrapper(
+ rustweb::apiServerZoneDetailDELETE as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
(&Method::GET, "/api/v1/servers/localhost/statistics") => {
api_wrapper(
rustweb::apiServerStatistics as Func,
headers,
);
}
+ (&Method::GET, "/api/v1/servers") => {
+ api_wrapper(
+ rustweb::apiServer as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api/v1") => {
+ api_wrapper(
+ rustweb::apiDiscoveryV1 as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/api") => {
+ api_wrapper(
+ rustweb::apiDiscovery as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
(&Method::GET, "/metrics") => {
rustweb::prometheusMetrics(&request, &mut response).unwrap();
}
unsafe extern "C++" {
include!("bridge.hh");
+ fn apiDiscovery(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiDiscoveryV1(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServer(request: &Request, response: &mut Response) -> Result<()>;
fn apiServerCacheFlush(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerConfig(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerConfigAllowFromGET(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerConfigAllowFromPUT(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerConfigAllowNotifyFromGET(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerConfigAllowNotifyFromPUT(request: &Request, response: &mut Response) -> Result<()>;
fn apiServerDetail(requst: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerRPZStats(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerSearchData(request: &Request, response: &mut Response) -> Result<()>;
fn apiServerStatistics(requst: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerZoneDetailDELETE(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerZoneDetailGET(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerZoneDetailPUT(request: &Request, response: &mut Response) -> Result<()>;
fn apiServerZonesGET(request: &Request, response: &mut Response) -> Result<()>;
fn apiServerZonesPOST(requst: &Request, response: &mut Response) -> Result<()>;
fn jsonstat(request: &Request, response: &mut Response) -> Result<()>;
resp->setJsonBody(doc);
}
-
static void apiServerCacheFlush(HttpRequest* req, HttpResponse* resp)
{
DNSName canon = apiNameToDNSName(req->getvars["domain"]);
yarl.initialize(&req);
socket->setNonBlocking();
- const struct timeval timeout
- {
- g_networkTimeoutMsec / 1000, static_cast<suseconds_t>(g_networkTimeoutMsec) % 1000 * 1000
- };
+ const struct timeval timeout{
+ g_networkTimeoutMsec / 1000, static_cast<suseconds_t>(g_networkTimeoutMsec) % 1000 * 1000};
std::shared_ptr<TLSCtx> tlsCtx{nullptr};
if (d_loglevel > WebServer::LogLevel::None) {
socket->getRemote(remote);
void serveRustWeb()
{
static ::rust::Vec<::rust::String> urls;
- for (const auto& [url, _] : g_urlmap) {
+ for (const auto& [url, _] : g_urlmap) {
urls.emplace_back(url);
}
auto address = ComboAddress(arg()["webserver-address"], arg().asNum("webserver-port"));
}
}
-static void rustWrapper(const std::function<void (HttpRequest*, HttpResponse*)>& func, const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse)
+static void rustWrapper(const std::function<void(HttpRequest*, HttpResponse*)>& func, const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse)
{
HttpRequest request;
HttpResponse response;
for (const auto& [key, value] : rustRequest.vars) {
request.getvars[std::string(key)] = std::string(value);
}
- func(&request, &response);
+ request.d_slog = g_slog; // XXX
+ response.d_slog = g_slog; // XXX
+ try {
+ func(&request, &response);
+ }
+ catch (HttpException& e) {
+ response.body = e.response().body;
+ response.status = e.response().status;
+ }
fromCxxToRust(response, rustResponse);
}
-namespace pdns::rust::web::rec {
+namespace pdns::rust::web::rec
+{
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
-#define WRAPPER(A) void A(const Request& rustRequest, Response& rustResponse) { rustWrapper(::A, rustRequest, rustResponse); }
+#define WRAPPER(A) \
+ void A(const Request& rustRequest, Response& rustResponse) { rustWrapper(::A, rustRequest, rustResponse); }
void jsonstat(const Request& rustRequest, Response& rustResponse)
{
rustWrapper(RecursorWebServer::jsonstat, rustRequest, rustResponse);
}
+WRAPPER(apiDiscovery)
+WRAPPER(apiDiscoveryV1)
+WRAPPER(apiServer)
WRAPPER(apiServerCacheFlush)
+WRAPPER(apiServerConfig)
+WRAPPER(apiServerConfigAllowFromGET)
+WRAPPER(apiServerConfigAllowFromPUT)
+WRAPPER(apiServerConfigAllowNotifyFromGET)
+WRAPPER(apiServerConfigAllowNotifyFromPUT)
WRAPPER(apiServerDetail)
+WRAPPER(apiServerRPZStats)
+WRAPPER(apiServerSearchData)
+WRAPPER(apiServerStatistics)
+WRAPPER(apiServerZoneDetailDELETE)
+WRAPPER(apiServerZoneDetailGET)
+WRAPPER(apiServerZoneDetailPUT)
WRAPPER(apiServerZonesGET)
WRAPPER(apiServerZonesPOST)
WRAPPER(prometheusMetrics)
WRAPPER(serveStuff)
-WRAPPER(apiServerStatistics)
}