WebDAV validates connections and preserves directory listings, with CI checking every change #1

Merged
temeddix merged 10 commits from fix-directory-listing into main 2026-09-30 13:10:15 +00:00
3 changed files with 15 additions and 19 deletions
Showing only changes of commit 631ea9db65 - Show all commits
+4 -7
View File
@@ -7,6 +7,8 @@ interface, under the connection's permissions.
It registers one provider, `webdav`, for the `webdav` and `davs` schemes.
This package requires a Memona version that supports plugin manifest schema 2.
## Connecting
| Field | Meaning |
@@ -15,13 +17,8 @@ It registers one provider, `webdav`, for the `webdav` and `davs` schemes.
| Username | Optional account name for HTTP basic authentication |
| Password | Optional password, stored as a secret |
In Memona's connection permissions, enter the server's hostname or IP in
**Allowed hosts**, without the URL scheme, port or path. For example,
`http://192.168.1.20:8080/dav/` needs `192.168.1.20`. An empty list blocks every
request, even when the address and credentials are correct. Turn on
**Private network** as well for a server on localhost or a private network;
this switch does not grant a host by itself. Save and reconnect after changing
these permissions.
For localhost or a server on a private network, turn on **Private network** in
Outdated
Review

LAN, link-local, and localhost addresses require the private-network grant. Update this guidance so users are prompted for the permission instead of being told none is needed.

Profile: codex · gpt-5.6-terra

LAN, link-local, and localhost addresses require the private-network grant. Update this guidance so users are prompted for the permission instead of being told none is needed. > Profile: `codex` · `gpt-5.6-terra`
the connection settings. Save and reconnect after changing these settings.
Listing, reading, writing, creating directories, renaming and deleting are
supported. Reads and writes stream in pieces of at most 1 MiB, so a file of any
+1 -2
View File
@@ -1,5 +1,5 @@
{
"schemaVersion": 1,
"schemaVersion": 2,
"id": "memona/webdav",
"name": "WebDAV",
"version": "0.1.2",
@@ -7,7 +7,6 @@
"description": "Open a WebDAV server as a folder, and let agents work in it.",
"license": "MIT",
"entry": "plugin.wasm",
"networkHosts": ["*"],
"networkPorts": [],
"providers": [
{
+10 -10
View File
@@ -35,10 +35,10 @@ interface host {
/// `respond`. An empty result means the body is complete.
pull: func(limit: u32) -> result<list<u8>, host-error>;
}
/// Begins a request to a host both declared by the package and granted on
/// the connection. Each redirect and DNS result is checked, and DNS is
/// pinned. Private/LAN addresses additionally require the private-network
/// grant. Cross-origin redirects remove request headers; HTTPS cannot
/// Begins a request to any public HTTP or HTTPS host. Each redirect and
Review

LAN and loopback access still requires the connection's private-network grant. Restore that requirement here; otherwise this copied contract tells plugin authors that private hosts are reachable without consent.

Profile: codex · gpt-5.6-terra

LAN and loopback access still requires the connection's private-network grant. Restore that requirement here; otherwise this copied contract tells plugin authors that private hosts are reachable without consent. > Profile: `codex` · `gpt-5.6-terra`
/// DNS result is checked, and DNS is pinned. Private/LAN addresses require
/// the connection's private-network grant. Cross-origin redirects remove
/// request headers; HTTPS cannot
/// downgrade. The host bounds total bytes per exchange, not buffer size.
http: func(request: request) -> result<exchange, host-error>;
@@ -51,13 +51,13 @@ interface host {
/// Writes at most 1,048,576 bytes and returns how many were accepted.
write: func(data: list<u8>) -> result<u32, host-error>;
}
Outdated
Review

The private-network grant applies to TCP too. Keep that constraint in the socket documentation so it matches HTTP and the host's enforcement.

Profile: codex · gpt-5.6-terra

The private-network grant applies to TCP too. Keep that constraint in the socket documentation so it matches HTTP and the host's enforcement. > Profile: `codex` · `gpt-5.6-terra`
/// Opens a socket to a host and port both declared by the package and
/// granted on the connection. The host resolves and pins DNS, applies the
/// same private-address rule as `http`, and starts TLS when asked. Ports
/// negotiated at runtime, such as an FTP data channel, still need a grant.
/// Opens a socket to any public host on a package-declared port.
/// The host resolves and pins DNS, applies the same private-address rule
/// as `http`, and starts TLS when asked. Ports
/// negotiated at runtime, such as an FTP data channel, must be declared.
connect: func(host: string, port: u16, tls: bool) -> result<tcp, host-error>;
/// One datagram socket connected to a single granted peer.
/// One datagram socket connected to a single peer.
resource udp {
/// Sends one datagram of at most 65,507 bytes.
send: func(data: list<u8>) -> result<u32, host-error>;
@@ -65,7 +65,7 @@ interface host {
/// means none arrived inside the host's wait, not that the peer left.
receive: func(limit: u32) -> result<list<u8>, host-error>;
}
Outdated
Review

UDP uses the same private-network grant as TCP and HTTP. Restore the grant rule here instead of reducing it to a port-only constraint.

Profile: codex · gpt-5.6-terra

UDP uses the same private-network grant as TCP and HTTP. Restore the grant rule here instead of reducing it to a port-only constraint. > Profile: `codex` · `gpt-5.6-terra`
/// Connects a datagram socket under the same declaration and grant rules
/// Connects a datagram socket under the same port and private-network rules
/// as `connect`, for the few filesystem protocols that still need one.
bind: func(host: string, port: u16) -> result<udp, host-error>;