.gitignore | ||
LICENSE | ||
README.md |
arthur's distributed file protocol v0.01
Requires HTTPS except when the host is localhost
.
CLIENT PROTOCOL
Tests for capabilities with the path /.well-known/adfp
, returns a json body in the format:
{
"okay": true, // Should always be true unless the server is unhealthy.
"minver": "0.01", // minimum supported protocol version
"maxver": "0.01", // maximum supported protocol version
"flavor": "adfp", // flavor of the protocol
"server": "adfp-rs-official-0.1.0", // server name and version
"nets": ["4acb6596-30ec-4dcc-87c3-a9533eecc8c0"], // nets the server is a part of
"gateway_to": ["762a1e57-13d8-4cb8-8930-c651f127ca8d", "fd30e6f7-0779-49b0-aeb2-12bb088b0285"], // nets the server can route to
"base_path": "/adfp" // base path of all requests. can be absolute, relative, protocol-relative, or root-relative.
}
Each server is a part of one or more nets and every server can talk to one another through this net.
A resource is identified by a URN with a namespace of adfp
, a path of the net(if available on multiple nets, they are separated by a forward slash), and a fragment of the resource ID:
urn:adfp:4acb6596-30ec-4dcc-87c3-a9533eecc8c0/78fee96b-b328-4e31-a8df-0d23a4d66130#1d3cac63-8baf-4ead-b807-1cfac0f2231c
To retrieve metadata of a resource, it can be retrieved at {base_path}/{net id}:{resource id}/meta.json
. It is in the format:
{
"filename": "example.html",
"mimetype": "text/html",
// all timestamps are optional and should use the current time if not provided
"creationdate": "2025-03-15 15:18:40-05:00", // IETF RFC3339 timestamp
"modificationdate": "2025-03-15 15:18:57-05:00", // IETF RFC3339 timestamp
"opendate": "2025-03-15 15:19:17-05:00", // IETF RFC3339 timestamp
"readdate": "2025-03-15 15:19:38-05:00", // IETF RFC3339 timestamp
"size": 34622, // in bytes. useful for determining if there is enough free space on the current drive.
"os": { // all are optional. if the proper OS doesn't exist when deserializing, recreate a best guess from others, or if none exist use permissions 700 on unix and an empty DACL on windows. if no owner/group is provided, use the current user's.
"unix": {
"owner": 0,
"group": 0,
"perms": 511, // 777 in decimal; octal isn't supported in json
},
"windows": {
"owner": "DOMAIN\\username",
"group": "DOMAIN\\groupname",
"dacl": [
{
"aceType": "AccessAllowed",
"trustee": "DOMAIN\\user1",
"accessMask": 2032127,
"flags": 0
},
{
"aceType": "AccessDenied",
"trustee": "DOMAIN\\user2",
"accessMask": 128,
"flags": 0
}
],
"sacl": [
{
"aceType": "SystemAudit",
"trustee": "DOMAIN\\user3",
"accessMask": 2032127,
"flags": 0
}
]
}
// more...
}
}
If the resource cannot be found, an HTTP 404 response with no body should be returned.
To download a resource, perform a GET request to {base_path}/{net id}:{resource id}/resource
.
Updating resources is unspecified and up to the implementation.
SERVER PROTOCOL
The server protocol is used by nets of servers to communicate. When a request for metadata of a resource or a resource is made, the gateway server performs the following steps in order:
- Check if the requested resource is in its files. If so, return the resource/metadata.
- Check the net. If it is a part of the net or a gateway to the net, perform operation one to retrieve the resource.
- If neither, perform operation two to attempt to find the net. If successful, retrieve the resource and update the nets it is a gateway to. If unsuccessful, return an HTTP 404 error.
OPERATION ONE
Operation one assumes that the server has a URL for the server it is requesting a resource from. In this case, it simply uses the client protocol to retrieve the metadata/resource.
This is also used for nets the server is a gateway to. In this case, if the server isn't a part of the net, but knows a server that can route to the final net, it should use the client protocol to access this server with the final net. If it does not, see operation two.
OPERATION TWO
Operation two assumes that the server knows nothing about how to access the final net. It firstly checks if any server in any of its nets are a part of the destination net and if so uses them. If not, it randomly picks a server from any of its nets and uses it as its gateway. Because of the possiblity of infinite loops, after a timeout of at least two seconds and at most twenty seconds, it will randomly pick a different server. This process repeats at least twice and at most fifty times.
If it does not, it should use the client protocol to retrieve the nets that every server in all of its nets are a part of and if any are a part of the final net, use it. If not, it should pick a random server and ask it. It should then save that server as its gateway server to that net.