diff --git a/file server/example/README.md b/file server/example/README.md
new file mode 100644
index 0000000..5ad9f3e
--- /dev/null
+++ b/file server/example/README.md
@@ -0,0 +1,12 @@
+# example prim-dns file server
+
+This is an example setup of a prim-dns file server.
+
+The directory structure seen here would actually be simulated by naming the notecards as follows:
+- `/agents/index.js`
+- `/agents/index.xhtml`
+- `/index.xhtml`
+- `/javascript/index.js`
+- `/javascript/index.xhtml`
+
+
diff --git a/file server/example/agents/index.js b/file server/example/agents/index.js
new file mode 100644
index 0000000..8631812
--- /dev/null
+++ b/file server/example/agents/index.js
@@ -0,0 +1,25 @@
+window.addEventListener('load', function() {
+ fetch('agents.json').then(resp => resp.json()).then(agents => {
+ document.getElementById('region-name').innerHTML = agents.region;
+
+ let table = document.getElementById('agents-table');
+
+ agents.agentList.forEach(agent => {
+ let row = document.createElement('tr');
+
+ let col1 = document.createElement('td');
+ col1.innerHTML = agent.key;
+ row.append(col1);
+
+ let col2 = document.createElement('td');
+ col2.innerHTML = agent.displayName;
+ row.append(col2);
+
+ let col3 = document.createElement('td');
+ col3.innerHTML = agent.username;
+ row.append(col3);
+
+ table.append(row);
+ });
+ });
+});
diff --git a/file server/example/agents/index.xhtml b/file server/example/agents/index.xhtml
new file mode 100644
index 0000000..08b7f29
--- /dev/null
+++ b/file server/example/agents/index.xhtml
@@ -0,0 +1,30 @@
+
+
+
+
+Agents in region
+
+
+
+
+
+Home
+Agents in region :
+
+
+
+| Key |
+Display name |
+Username |
+
+
+
+
+
+
+
diff --git a/file server/example/example inventory contents.png b/file server/example/example inventory contents.png
new file mode 100644
index 0000000..febbb79
Binary files /dev/null and b/file server/example/example inventory contents.png differ
diff --git a/file server/example/index.xhtml b/file server/example/index.xhtml
new file mode 100644
index 0000000..664cfe8
--- /dev/null
+++ b/file server/example/index.xhtml
@@ -0,0 +1,22 @@
+
+
+
+
+prim-dns file server default page
+
+
+
+
+prim-dns file server examples
+These are some examples of what you can do using the prim-dns file server:
+
+
+
diff --git a/file server/example/javascript/index.js b/file server/example/javascript/index.js
new file mode 100644
index 0000000..21a7091
--- /dev/null
+++ b/file server/example/javascript/index.js
@@ -0,0 +1,5 @@
+window.addEventListener('load', function() {
+ document.querySelectorAll('.color-button').forEach(btn => btn.addEventListener('click', function() {
+ document.getElementById('color-text').style.color = btn.getAttribute('data-color');
+ }));
+});
diff --git a/file server/example/javascript/index.xhtml b/file server/example/javascript/index.xhtml
new file mode 100644
index 0000000..c19fb56
--- /dev/null
+++ b/file server/example/javascript/index.xhtml
@@ -0,0 +1,26 @@
+
+
+
+
+Javascript example
+
+
+
+
+
+Home
+Javascript example:
+Color me!
+
+
+
+
+
diff --git a/file server/example/request handler.lsl b/file server/example/request handler.lsl
new file mode 100644
index 0000000..4ed9516
--- /dev/null
+++ b/file server/example/request handler.lsl
@@ -0,0 +1,63 @@
+/* This script handles requests to special paths which return dynamic responses using LSL. */
+
+string jsonrpc_notification(string method, string params_type, list params)
+{
+ return llList2Json(JSON_OBJECT, ["jsonrpc", "2.0", "method", method, "params", llList2Json(params_type, params)]);
+}
+
+jsonrpc_link_notification(integer link, string method, string params_type, list params)
+{
+ llMessageLinked(link, 0, jsonrpc_notification(method, params_type, params), NULL_KEY);
+}
+
+default
+{
+ state_entry()
+ {
+ /* Register the paths this script will handle instead of the file server. */
+ jsonrpc_link_notification(LINK_SET, "prim-dns:file-server:register-path", JSON_OBJECT, ["path", "/agents/agents.json"]);
+ }
+
+ link_message(integer sender, integer num, string str, key id)
+ {
+ string jsonrpc_method = llJsonGetValue(str, ["method"]);
+
+ if (jsonrpc_method == "prim-dns:request")
+ {
+ key request_id = (key) llJsonGetValue(str, ["params", "request-id"]);
+ string method = llJsonGetValue(str, ["params", "method"]);
+ string headers = llJsonGetValue(str, ["params", "headers"]);
+ string body = llJsonGetValue(str, ["params", "body"]);
+
+ /* Get the path from the headers and use it to determine the response. */
+ string path = llJsonGetValue(headers, ["x-path-info"]);
+
+ if (path == "/agents/agents.json")
+ {
+ list agents = llGetAgentList(AGENT_LIST_REGION, []);
+ integer total_agents = llGetListLength(agents);
+ list agentList;
+ integer i;
+
+ for (i = 0; i < total_agents; ++i)
+ {
+ key agent = llList2Key(agents, i);
+
+ agentList += llList2Json(JSON_OBJECT, [
+ "key", agent,
+ "username", llGetUsername(agent),
+ "displayName", llGetDisplayName(agent)
+ ]);
+ }
+
+ string out = llList2Json(JSON_OBJECT, [
+ "region", llGetRegionName(),
+ "agentList", llList2Json(JSON_ARRAY, agentList)
+ ]);
+
+ jsonrpc_link_notification(sender, "prim-dns:set-content-type", JSON_OBJECT, ["request-id", request_id, "content-type", CONTENT_TYPE_JSON]);
+ jsonrpc_link_notification(sender, "prim-dns:response", JSON_OBJECT, ["request-id", request_id, "status", 200, "body", out]);
+ }
+ }
+ }
+}