Commit 1e00c859 authored by jan.koester's avatar jan.koester
Browse files

test

parent eba9ed78
Loading
Loading
Loading
Loading
+15 −0
Changes for admin/static/app.js: 15 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -108,6 +108,8 @@ const ProxyPlusAdmin = (() => {
  }

  async function createRoute() {
    document.getElementById("route-error").textContent = "";
    try {
      await api("POST", "/api/v1/http/routes", {
        id: document.getElementById("route-id").value,
        path_prefix: document.getElementById("route-path").value,
@@ -116,6 +118,9 @@ const ProxyPlusAdmin = (() => {
        required_permission: document.getElementById("route-permission").value,
      });
      await refreshRoutes();
    } catch (e) {
      document.getElementById("route-error").textContent = e.message;
    }
  }

  function showNewRelayForm() {
@@ -123,6 +128,8 @@ const ProxyPlusAdmin = (() => {
  }

  async function createRelay() {
    document.getElementById("relay-error").textContent = "";
    try {
      await api("POST", "/api/v1/smtp/relays", {
        id: document.getElementById("relay-id").value,
        domain: document.getElementById("relay-domain").value || "*",
@@ -131,6 +138,9 @@ const ProxyPlusAdmin = (() => {
        owner_group_id: document.getElementById("relay-group").value,
      });
      await refreshRelays();
    } catch (e) {
      document.getElementById("relay-error").textContent = e.message;
    }
  }

  function showNewPoolForm() {
@@ -155,6 +165,8 @@ const ProxyPlusAdmin = (() => {
  }

  async function createPool() {
    document.getElementById("pool-error").textContent = "";
    try {
      await api("POST", "/api/v1/pools", {
        id: document.getElementById("pool-id").value,
        kind: document.getElementById("pool-kind").value,
@@ -162,6 +174,9 @@ const ProxyPlusAdmin = (() => {
        targets: parseTargets(document.getElementById("pool-targets").value),
      });
      await refreshPools();
    } catch (e) {
      document.getElementById("pool-error").textContent = e.message;
    }
  }

  return {
+7 −4
Changes for admin/static/index.html: 7 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -29,10 +29,11 @@
  <div id="new-route-form" hidden>
    <input id="route-id" placeholder="ID">
    <input id="route-path" placeholder="Pfad-Prefix, z.B. /app">
    <input id="route-upstream" placeholder="Upstream (direkt), z.B. http://10.0.0.5:8080">
    <input id="route-upstream-pool" placeholder="oder Pool-ID (statt Upstream)">
    <input id="route-upstream" placeholder="Upstream (direkt), genau eine URL, z.B. http://10.0.0.5:8080">
    <input id="route-upstream-pool" placeholder="oder Pool-ID fuer mehrere Ziele (statt Upstream)">
    <input id="route-permission" placeholder="Berechtigung, z.B. http.proxy.use">
    <button onclick="ProxyPlusAdmin.createRoute()">Anlegen</button>
    <div id="route-error" class="error"></div>
  </div>

  <h2>SMTP-Relays</h2>
@@ -41,10 +42,11 @@
  <div id="new-relay-form" hidden>
    <input id="relay-id" placeholder="ID">
    <input id="relay-domain" placeholder="Domain, * fuer alle">
    <input id="relay-smarthost" placeholder="Smarthost (direkt), z.B. mail.example.com:587">
    <input id="relay-smarthost-pool" placeholder="oder Pool-ID (statt Smarthost)">
    <input id="relay-smarthost" placeholder="Smarthost (direkt), genau ein Ziel, z.B. mail.example.com:587">
    <input id="relay-smarthost-pool" placeholder="oder Pool-ID fuer mehrere Ziele (statt Smarthost)">
    <input id="relay-group" placeholder="Owner-Gruppen-UUID (optional)">
    <button onclick="ProxyPlusAdmin.createRelay()">Anlegen</button>
    <div id="relay-error" class="error"></div>
  </div>

  <h2>Load-Balancer-Pools</h2>
@@ -62,6 +64,7 @@
    </select>
    <input id="pool-targets" placeholder="Ziele: adresse:gewicht, ... z.B. http://10.0.0.1:8080:1, http://10.0.0.2:8080:1">
    <button onclick="ProxyPlusAdmin.createPool()">Anlegen</button>
    <div id="pool-error" class="error"></div>
  </div>

  <button onclick="ProxyPlusAdmin.logout()">Logout</button>
+16 −0
Changes for src/api/JsonApiServer.cpp: 16 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -70,6 +70,14 @@ store::LbAlgorithm lbAlgorithmFromString(const std::string &s) {
    return store::LbAlgorithm::RoundRobin;
}

// A direct upstream/smarthost field must name exactly one backend. Nothing downstream
// validates this: libhttppp::HttpUrl silently stops parsing at the first stray character
// after the port and defaults the path to "/", so e.g. "https://a:443,https://b:443" is
// accepted without error and quietly turns into a request to "https://a:443/" -- the real
// path and every backend but the first are dropped with no diagnostic anywhere. Reject the
// comma up front so the mistake (meant for a pool's targets field) surfaces immediately.
bool looksLikeSingleTarget(const std::string &s) { return s.find(',') == std::string::npos; }

} // namespace

JsonApiController::JsonApiController(std::vector<netplus::socket *> serverSockets,
@@ -209,6 +217,10 @@ void JsonApiController::registerRoutes() {
             if (rec.upstream.empty() && rec.upstreamPool.empty()) {
                 return jsonError("either upstream or upstream_pool is required");
             }
             if (!looksLikeSingleTarget(rec.upstream)) {
                 return jsonError("upstream must name exactly one backend URL; "
                                   "use upstream_pool for more than one target");
             }
             _configStore.putHttpRoute(rec);
             JsonGuard resp(json_object_new_object());
             json_object_object_add(resp, "status", json_object_new_string("created"));
@@ -248,6 +260,10 @@ void JsonApiController::registerRoutes() {
             if (rec.smarthost.empty() && rec.smarthostPool.empty()) {
                 return jsonError("either smarthost or smarthost_pool is required");
             }
             if (!looksLikeSingleTarget(rec.smarthost)) {
                 return jsonError("smarthost must name exactly one backend host:port; "
                                   "use smarthost_pool for more than one target");
             }
             _configStore.putSmtpRelayRule(rec);
             JsonGuard resp(json_object_new_object());
             json_object_object_add(resp, "status", json_object_new_string("created"));