From e22b335db9bdc1e24e9ddb61a38720bd7b796a41 Mon Sep 17 00:00:00 2001 From: t Date: Mon, 3 Aug 2026 10:44:48 -0600 Subject: Initial commit: web.{fetch,search} tools external `curl` for fetching, `exa` public service for search --- _selfcheck.lua | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 _selfcheck.lua (limited to '_selfcheck.lua') diff --git a/_selfcheck.lua b/_selfcheck.lua new file mode 100644 index 0000000..b7f35be --- /dev/null +++ b/_selfcheck.lua @@ -0,0 +1,59 @@ +-- Self-check for panto-web. Run with: +-- +-- panto lua panto-web/_selfcheck.lua + +local registered = {} +package.loaded["panto"] = { + ext = { + register_tool = function(tool) registered[#registered + 1] = tool end, + json = { + decode = function() return {} end, + encode = function() return "{}" end, + }, + }, +} + +local here = debug.getinfo(1, "S").source:match("^@(.*)/[^/]+$") or "." +package.path = here .. "/panto-web/?.lua;" .. here .. "/panto-web/?/init.lua;" .. package.path + +local web = require("init") +assert(web.name == "web", "entry name") + +local parsed = assert(web.parse_url("https://example.com:8443/docs?q=1")) +assert(parsed.host == "example.com" and parsed.port == 8443, "URL host and port") +local _, local_err = web.parse_url("http://user:pass@example.com/") +assert(local_err:find("credentials", 1, true), "URL credentials rejected") +assert(web.is_public_address("8.8.8.8"), "public IPv4 allowed") +assert(not web.is_public_address("127.0.0.1"), "loopback IPv4 blocked") +assert(not web.is_public_address("::1"), "loopback IPv6 blocked") +assert(not web.is_public_address("::127.0.0.1"), "IPv4-compatible loopback blocked") + +local page, title = web.html_to_text([[A & B +

Heading

Hello <world>.

+Read]]) +assert(title == "A & B", "HTML title decoded") +assert(page:find("Heading", 1, true) and page:find("Hello .", 1, true), "HTML text retained") +assert(page:find("Read (https://example.com/x)", 1, true), "link destination retained") +assert(not page:find("hidden", 1, true), "non-content HTML removed") + +local search_text = web.format_search([[Title: First result +URL: https://example.com/one +Highlights: +Useful first excerpt. +... +--- + +Title: Second result +URL: https://example.com/two +Highlights: +Useful second excerpt.]], "example query") +assert(search_text:find("1. First result", 1, true), "first search result") +assert(search_text:find("URL: https://example.com/two", 1, true), "second search URL") + +web.activate() +assert(registered[1].name == "web.fetch", "fetch tool registered") +assert(registered[2].name == "web.search", "search tool registered") +assert(web.on_fetch({ url = "file:///etc/passwd" }):find("only http", 1, true), "fetch rejects file URLs") +assert(web.on_search({ query = "" }):find("non-empty", 1, true), "search rejects empty query") + +print("panto-web selfcheck: OK") -- cgit v1.3