rec-system-resolve.hh rec-system-resolve.cc \
rec-taskqueue.cc rec-taskqueue.hh \
rec-tcounters.cc rec-tcounters.hh \
+ rec-web-stubs.hh \
rec-xfrtracker.cc \
rec-zonetocache.cc rec-zonetocache.hh \
recpacketcache.cc recpacketcache.hh \
rec-system-resolve.cc rec-system-resolve.hh \
rec_channel.cc rec_channel.hh \
rec_control.cc \
+ rec-web-stubs.hh \
settings/cxxsupport.cc \
sillyrecords.cc \
sortlist.cc sortlist.hh \
--- /dev/null
+namespace pdns::rust::web::rec {
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+#define WRAPPER(A) void A(const Request& /* unused */ , Response& /* unused */) { }
+
+WRAPPER(jsonstat)
+WRAPPER(apiServerCacheFlush)
+WRAPPER(apiServerDetail)
+WRAPPER(apiServerZonesGET)
+WRAPPER(apiServerZonesPOST)
+WRAPPER(prometheusMetrics)
+WRAPPER(serveStuff)
+WRAPPER(apiServerStatistics)
+
+#undef WRAPPER
+}
return 1;
}
}
+#include "rec-web-stubs.hh"
-void pdns::rust::web::rec::serveStuff(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::prometheusMetrics(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::apiServerZonesGET(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::apiServerCacheFlush(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::apiServerZonesPOST(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
# 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: 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 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
@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
/Makefile.in
/cxx.h
/lib.rs.h
+/web.rs.h
src/lib.rs
.dir-locals.el
Cargo.lock \
build.rs \
src/bridge.rs \
- src/helpers.rs
+ src/helpers.rs \
+ 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
struct KeyValue;
struct Request;
struct Response;
-void serveStuff(const Request& rustRequest, Response& rustResponse);
-void prometheusMetrics(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 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);
}
header::HeaderValue::from_static("default-src 'self'; style-src 'self' 'unsafe-inline'"),
);
- println!("api_wrapper A0 Status {}", response.status);
match handler(request, response) {
Ok(_) => {}
Err(_) => {
response.status = StatusCode::UNPROCESSABLE_ENTITY.as_u16(); // 422
}
}
- println!("api_wrapper A Status {}", response.status);
}
async fn hello(
};
let headers = rust_response.headers_mut().expect("no headers?");
match (rust_request.method(), rust_request.uri().path()) {
- (&Method::GET, "/metrics") => {
- rustweb::prometheusMetrics(&request, &mut response).unwrap();
+ (&Method::GET, "/jsonstat") => {
+ api_wrapper(
+ rustweb::jsonstat as Func,
+ &request,
+ &mut response,
+ headers,
+ );
}
(&Method::PUT, "/api/v1/servers/localhost/cache/flush") => {
api_wrapper(
headers,
);
}
+ (&Method::GET, "/api/v1/servers/localhost/statistics") => {
+ api_wrapper(
+ rustweb::apiServerStatistics as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
(&Method::GET, "/api/v1/servers/localhost/zones") => {
- println!("hello Status {}", response.status);
api_wrapper(
rustweb::apiServerZonesGET as Func,
&request,
headers,
);
}
+ (&Method::GET, "/api/v1/servers/localhost") => {
+ api_wrapper(
+ rustweb::apiServerDetail as Func,
+ &request,
+ &mut response,
+ headers,
+ );
+ }
+ (&Method::GET, "/metrics") => {
+ rustweb::prometheusMetrics(&request, &mut response).unwrap();
+ }
_ => {
let mut path = rust_request.uri().path();
if path == "/" {
}
}
}
- println!("B Status {}", response.status);
let mut rust_response = rust_response
.status(StatusCode::from_u16(response.status).unwrap())
.body(full(response.body))?;
unsafe extern "C++" {
include!("bridge.hh");
- fn serveStuff(request: &Request, response: &mut Response) -> Result<()>;
- fn prometheusMetrics(request: &Request, response: &mut Response) -> Result<()>;
fn apiServerCacheFlush(request: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerDetail(requst: &Request, response: &mut Response) -> Result<()>;
+ fn apiServerStatistics(requst: &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<()>;
+ fn prometheusMetrics(request: &Request, response: &mut Response) -> Result<()>;
+ fn serveStuff(request: &Request, response: &mut Response) -> Result<()>;
}
}
return LWResult::Result::Timeout;
}
-void pdns::rust::web::rec::serveStuff(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::prometheusMetrics(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::apiServerZonesGET(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::apiServerCacheFlush(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
-void pdns::rust::web::rec::apiServerZonesPOST(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */)
-{
-}
-
+#include "rec-web-stubs.hh"
using json11::Json;
-static void fromCxxToRust(const HttpResponse& cxxresp, pdns::rust::web::rec::Response& rustResponse)
-{
- if (cxxresp.status != 0) {
- rustResponse.status = cxxresp.status;
- }
- rustResponse.body = ::rust::Vec<::rust::u8>();
- rustResponse.body.reserve(cxxresp.body.size());
- std::copy(cxxresp.body.cbegin(), cxxresp.body.cend(), std::back_inserter(rustResponse.body));
- for (const auto& header : cxxresp.headers) {
- rustResponse.headers.emplace_back(pdns::rust::web::rec::KeyValue{header.first, header.second});
- }
-}
-
void productServerStatisticsFetch(map<string, string>& out)
{
auto stats = getAllStatsMap(StatComponent::API);
resp->status = 201;
}
-void pdns::rust::web::rec::apiServerZonesPOST(const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse)
-{
- HttpRequest req;
- HttpResponse resp;
-
- req.body = std::string(reinterpret_cast<const char*>(rustRequest.body.data()), rustRequest.body.size());
- apiServerZonesPOST(&req, &resp);
- fromCxxToRust(resp, rustResponse);
-}
-
static void apiServerZonesGET(HttpRequest* /* req */, HttpResponse* resp)
{
Json::array doc;
resp->setJsonBody(doc);
}
-void pdns::rust::web::rec::apiServerZonesGET(const pdns::rust::web::rec::Request& /* rustRequest */, pdns::rust::web::rec::Response& rustResponse)
-{
- HttpResponse resp;
- apiServerZonesGET(nullptr, &resp);
- fromCxxToRust(resp, rustResponse);
-}
-
static inline DNSName findZoneById(HttpRequest* req)
{
auto zonename = apiZoneIdToName(req->parameters["id"]);
{"result", "Flushed cache."}});
}
-void pdns::rust::web::rec::apiServerCacheFlush(const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse)
-{
- HttpRequest request;
- for (const auto& [key, value] : rustRequest.vars) {
- cerr << key << ' ' << value << endl;
- request.getvars[std::string(key)] = std::string(value);
- }
- HttpResponse response;
- apiServerCacheFlush(&request, &response);
- fromCxxToRust(response, rustResponse);
-}
-
static void apiServerRPZStats(HttpRequest* /* req */, HttpResponse* resp)
{
auto luaconf = g_luaconfs.getLocal();
resp->status = 200;
}
-void pdns::rust::web::rec::prometheusMetrics(const pdns::rust::web::rec::Request& /* rustRequest */, pdns::rust::web::rec::Response& rustReponse)
-{
- HttpResponse resp;
- prometheusMetrics(nullptr, &resp);
- fromCxxToRust(resp, rustReponse);
-}
-
#include "htmlfiles.h"
static void serveStuff(HttpRequest* req, HttpResponse* resp)
}
}
-void pdns::rust::web::rec::serveStuff(const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustReponse)
-{
- HttpRequest request;
- HttpResponse response;
- request.url = std::string(rustRequest.uri);
- serveStuff(&request, &response);
- fromCxxToRust(response, rustReponse);
-}
-
const std::map<std::string, MetricDefinition> MetricDefinitionStorage::d_metrics = {
#include "rec-prometheus-gen.h"
};
for (const auto& [url, _] : g_urlmap) {
urls.emplace_back(url);
}
- pdns::rust::web::rec::serveweb({"127.0.0.1:3000", "[::1]:3000"}, urls);
+ pdns::rust::web::rec::serveweb({"127.0.0.1:3000", "[::1]:3000"}, ::rust::Slice<const ::rust::String>{urls.data(), urls.size()});
+}
+
+static void fromCxxToRust(const HttpResponse& cxxresp, pdns::rust::web::rec::Response& rustResponse)
+{
+ if (cxxresp.status != 0) {
+ rustResponse.status = cxxresp.status;
+ }
+ rustResponse.body = ::rust::Vec<::rust::u8>();
+ rustResponse.body.reserve(cxxresp.body.size());
+ std::copy(cxxresp.body.cbegin(), cxxresp.body.cend(), std::back_inserter(rustResponse.body));
+ for (const auto& header : cxxresp.headers) {
+ rustResponse.headers.emplace_back(pdns::rust::web::rec::KeyValue{header.first, header.second});
+ }
+}
+
+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;
+ request.body = std::string(reinterpret_cast<const char*>(rustRequest.body.data()), rustRequest.body.size());
+ request.url = std::string(rustRequest.uri);
+ for (const auto& [key, value] : rustRequest.vars) {
+ request.getvars[std::string(key)] = std::string(value);
+ }
+ func(&request, &response);
+ fromCxxToRust(response, rustResponse);
+}
+
+namespace pdns::rust::web::rec {
+
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+#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(apiServerCacheFlush)
+WRAPPER(apiServerDetail)
+WRAPPER(apiServerZonesGET)
+WRAPPER(apiServerZonesPOST)
+WRAPPER(prometheusMetrics)
+WRAPPER(serveStuff)
+WRAPPER(apiServerStatistics)
+
}