update
Some checks failed
Build Gurty / Build Gurty (, ubuntu-latest, linux, x86_64-unknown-linux-gnu) (push) Failing after 1m33s
Build GurtCA / Build GurtCA (, ubuntu-latest, linux, x86_64-unknown-linux-gnu) (push) Failing after 11m20s
Build GDExtension / Build GDExtension (libgurt_godot.so, ubuntu-latest, linux, x86_64-unknown-linux-gnu) (push) Failing after 16m9s
Build Flumi / Build Flumi (Linux, 4.4.1, ubuntu-latest, linux) (push) Failing after 2h10m11s
Build Flumi / Build Flumi (Windows Desktop, 4.4.1, windows-latest, windows) (push) Has been cancelled
Build GDExtension / Build GDExtension (gurt_godot.dll, windows-latest, windows, x86_64-pc-windows-msvc) (push) Has been cancelled
Build GurtCA / Build GurtCA (.exe, windows-latest, windows, x86_64-pc-windows-msvc) (push) Has been cancelled
Build Gurty / Build Gurty (.exe, windows-latest, windows, x86_64-pc-windows-msvc) (push) Has been cancelled

This commit is contained in:
2025-11-06 20:02:53 +08:00
parent 3f79614850
commit a508e3cefd
48 changed files with 136 additions and 137 deletions

View File

@@ -3,7 +3,7 @@
[Website](https://gurted.com/) | [Docs](https://docs.gurted.com/) | [License](LICENSE) | [YouTube video](https://www.youtube.com) [Website](https://gurted.com/) | [Docs](https://docs.gurted.com/) | [License](LICENSE) | [YouTube video](https://www.youtube.com)
Gurted is an ecosystem similar to the World Wide Web, it features: Gurted is an ecosystem similar to the World Wide Web, it features:
- ⚡ A custom protocol (TCP-based) named `GURT://` with mandatory TLS security with a [spec](docs.gurted.com) - ⚡ A custom protocol (TCP-based) named `lw://` with mandatory TLS security with a [spec](docs.gurted.com)
- 🌐 A custom **wayfinder** (browser) written in Rust and GDScript with [Godot](https://godotengine.org/) - 🌐 A custom **wayfinder** (browser) written in Rust and GDScript with [Godot](https://godotengine.org/)
- 📄 A custom engine for HTML, CSS, and ***Lua*** (no JavaScript) - 📄 A custom engine for HTML, CSS, and ***Lua*** (no JavaScript)
- 🏷️ A custom **DNS** that allows users to create domains with TLDs such as `.based`, `.aura`, `.twin`, and many more - 🏷️ A custom **DNS** that allows users to create domains with TLDs such as `.based`, `.aura`, `.twin`, and many more
@@ -16,7 +16,7 @@ Gurted is an ecosystem similar to the World Wide Web, it features:
# File structure # File structure
- `/dns` - The **DNS** (Domain Name System) - `/dns` - The **DNS** (Domain Name System)
- `/docs` - The **documentation** at https://docs.gurted.com - `/docs` - The **documentation** at https://docs.gurted.com
- `/flumi` - The **wayfinder** Flumi, used to view gurt:// sites - `/flumi` - The **wayfinder** Flumi, used to view lw:// sites
- `/protocol` - All protocol related things - `/protocol` - All protocol related things
- `/protocol/library` - The Rust protocol implementation (client + server) - `/protocol/library` - The Rust protocol implementation (client + server)
- `/protocol/gdextension` - The Godot extension for GURT protocol (uses Rust library, used in Flumi) - `/protocol/gdextension` - The Godot extension for GURT protocol (uses Rust library, used in Flumi)

2
dns/Cargo.lock generated
View File

@@ -973,7 +973,7 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]] [[package]]
name = "gurtlib" name = "gurtlib"
version = "0.1.0" version = "0.1.1"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"chrono", "chrono",

View File

@@ -74,7 +74,7 @@ end
local function loadDomains() local function loadDomains()
print('Loading domains...') print('Loading domains...')
local response = fetch('gurt://dns.web/auth/domains?page=1&limit=100', { local response = fetch('lw://dns.web/auth/domains?page=1&limit=100', {
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
} }
@@ -95,7 +95,7 @@ local function checkAuth()
if authToken then if authToken then
print('Found auth token, checking validity...') print('Found auth token, checking validity...')
local response = fetch('gurt://dns.web/auth/me', { local response = fetch('lw://dns.web/auth/me', {
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
} }

View File

@@ -29,7 +29,7 @@ local renderRecords
local function deleteRecord(recordId) local function deleteRecord(recordId)
print('Deleting DNS record: ' .. recordId) print('Deleting DNS record: ' .. recordId)
local response = fetch('gurt://dns.web/domain/' .. domainName .. '/records/' .. recordId, { local response = fetch('lw://dns.web/domain/' .. domainName .. '/records/' .. recordId, {
method = 'DELETE', method = 'DELETE',
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
@@ -57,7 +57,7 @@ end
-- Actual implementation -- Actual implementation
loadRecords = function() loadRecords = function()
print('Loading DNS records for: ' .. domainName) print('Loading DNS records for: ' .. domainName)
local response = fetch('gurt://dns.web/domain/' .. domainName .. '/records', { local response = fetch('lw://dns.web/domain/' .. domainName .. '/records', {
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
} }
@@ -175,7 +175,7 @@ end
local function loadDomain() local function loadDomain()
print('Loading domain details for: ' .. domainName) print('Loading domain details for: ' .. domainName)
local response = fetch('gurt://dns.web/domain/' .. domainName, { local response = fetch('lw://dns.web/domain/' .. domainName, {
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
} }
@@ -197,7 +197,7 @@ local function checkAuth()
if authToken then if authToken then
print('Found auth token, checking validity...') print('Found auth token, checking validity...')
local response = fetch('gurt://dns.web/auth/me', { local response = fetch('lw://dns.web/auth/me', {
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
} }
@@ -228,7 +228,7 @@ end
local function addRecord(type, name, value, ttl) local function addRecord(type, name, value, ttl)
hideError('record-error') hideError('record-error')
local response = fetch('gurt://dns.web/domain/' .. domainName .. '/records', { local response = fetch('lw://dns.web/domain/' .. domainName .. '/records', {
method = 'POST', method = 'POST',
headers = { headers = {
['Content-Type'] = 'application/json', ['Content-Type'] = 'application/json',

View File

@@ -75,7 +75,7 @@ end
local function loadTLDs() local function loadTLDs()
print('Loading available TLDs...') print('Loading available TLDs...')
local response = fetch('gurt://dns.web/tlds') local response = fetch('lw://dns.web/tlds')
if response:ok() then if response:ok() then
tlds = response:json() tlds = response:json()
@@ -91,7 +91,7 @@ local function checkAuth()
if authToken then if authToken then
print('Found auth token, checking validity...') print('Found auth token, checking validity...')
local response = fetch('gurt://dns.web/auth/me', { local response = fetch('lw://dns.web/auth/me', {
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
} }
@@ -127,7 +127,7 @@ local function submitDomain(name, tld)
hideError('domain-error') hideError('domain-error')
print('Submitting domain: ' .. name .. '.' .. tld) print('Submitting domain: ' .. name .. '.' .. tld)
local response = fetch('gurt://dns.web/domain', { local response = fetch('lw://dns.web/domain', {
method = 'POST', method = 'POST',
headers = { headers = {
['Content-Type'] = 'application/json', ['Content-Type'] = 'application/json',
@@ -157,7 +157,7 @@ end
local function createInvite() local function createInvite()
print('Creating invite code...') print('Creating invite code...')
local response = fetch('gurt://dns.web/auth/invite', { local response = fetch('lw://dns.web/auth/invite', {
method = 'POST', method = 'POST',
headers = { headers = {
Authorization = 'Bearer ' .. authToken Authorization = 'Bearer ' .. authToken
@@ -184,7 +184,7 @@ local function redeemInvite(code)
hideError('redeem-error') hideError('redeem-error')
print('Redeeming invite code: ' .. code) print('Redeeming invite code: ' .. code)
local response = fetch('gurt://dns.web/auth/redeem-invite', { local response = fetch('lw://dns.web/auth/redeem-invite', {
method = 'POST', method = 'POST',
headers = { headers = {
['Content-Type'] = 'application/json', ['Content-Type'] = 'application/json',

View File

@@ -21,7 +21,7 @@ submitBtn:on('submit', function(event)
password = password password = password
}) })
print(request_body) print(request_body)
local url = 'gurt://dns.web/auth/login' local url = 'lw://dns.web/auth/login'
local headers = { local headers = {
['Content-Type'] = 'application/json' ['Content-Type'] = 'application/json'
} }

View File

@@ -57,7 +57,7 @@ submitBtn:on('submit', function(event)
password = password password = password
}) })
local url = 'gurt://dns.web/auth/register' local url = 'lw://dns.web/auth/register'
local headers = { local headers = {
['Content-Type'] = 'application/json' ['Content-Type'] = 'application/json'
} }

View File

@@ -4,7 +4,7 @@ sidebar_position: 6
# DNS System # DNS System
The Gurted ecosystem features a custom DNS system that enables domain resolution for the gurt:// protocol. Unlike traditional DNS, Gurted DNS is designed specifically for the decentralized web ecosystem, providing: The Gurted ecosystem features a custom DNS system that enables domain resolution for the lw:// protocol. Unlike traditional DNS, Gurted DNS is designed specifically for the decentralized web ecosystem, providing:
- Domain registration with approval workflows - Domain registration with approval workflows
- DNS record management (A, AAAA, CNAME, TXT) - DNS record management (A, AAAA, CNAME, TXT)

View File

@@ -4,5 +4,5 @@ sidebar_position: 7
# Flumi (browser) # Flumi (browser)
**Flumi** is the official browser for the Gurted ecosystem, built using the Godot game engine. It provides a complete web browsing experience for `gurt://` URLs with custom HTML/CSS rendering, Lua scripting support, and integration with the Gurted DNS system. **Flumi** is the official browser for the Gurted ecosystem, built using the Godot game engine. It provides a complete web browsing experience for `lw://` URLs with custom HTML/CSS rendering, Lua scripting support, and integration with the Gurted DNS system.

View File

@@ -27,7 +27,7 @@ async fn main() -> Result<()> {
let client = GurtClient::new(); let client = GurtClient::new();
// Make a GET request // Make a GET request
let response = client.get("gurt://example.com/").await?; let response = client.get("lw://example.com/").await?;
println!("Status: {}", response.status_code); println!("Status: {}", response.status_code);
println!("Body: {}", response.text()?); println!("Body: {}", response.text()?);
@@ -65,7 +65,7 @@ let client = GurtClient::with_config(config);
### GET Requests ### GET Requests
```rust ```rust
let response = client.get("gurt://api.example.com/users").await?; let response = client.get("lw://api.example.com/users").await?;
if response.is_success() { if response.is_success() {
println!("Success: {}", response.text()?); println!("Success: {}", response.text()?);
@@ -78,7 +78,7 @@ if response.is_success() {
#### Text Data #### Text Data
```rust ```rust
let response = client.post("gurt://api.example.com/submit", "Hello, GURT!").await?; let response = client.post("lw://api.example.com/submit", "Hello, GURT!").await?;
``` ```
#### JSON Data #### JSON Data
@@ -90,30 +90,30 @@ let data = json!({
"email": "john@example.com" "email": "john@example.com"
}); });
let response = client.post_json("gurt://api.example.com/users", &data).await?; let response = client.post_json("lw://api.example.com/users", &data).await?;
``` ```
### PUT Requests ### PUT Requests
```rust ```rust
// Text data // Text data
let response = client.put("gurt://api.example.com/resource/123", "Updated content").await?; let response = client.put("lw://api.example.com/resource/123", "Updated content").await?;
// JSON data // JSON data
let update_data = json!({"status": "completed"}); let update_data = json!({"status": "completed"});
let response = client.put_json("gurt://api.example.com/tasks/456", &update_data).await?; let response = client.put_json("lw://api.example.com/tasks/456", &update_data).await?;
``` ```
### DELETE Requests ### DELETE Requests
```rust ```rust
let response = client.delete("gurt://api.example.com/users/123").await?; let response = client.delete("lw://api.example.com/users/123").await?;
``` ```
### HEAD Requests ### HEAD Requests
```rust ```rust
let response = client.head("gurt://api.example.com/large-file").await?; let response = client.head("lw://api.example.com/large-file").await?;
// Check headers without downloading body // Check headers without downloading body
let content_length = response.headers.get("content-length"); let content_length = response.headers.get("content-length");
@@ -122,7 +122,7 @@ let content_length = response.headers.get("content-length");
### OPTIONS Requests ### OPTIONS Requests
```rust ```rust
let response = client.options("gurt://api.example.com/endpoint").await?; let response = client.options("lw://api.example.com/endpoint").await?;
// Check allowed methods // Check allowed methods
let allowed_methods = response.headers.get("allow"); let allowed_methods = response.headers.get("allow");
@@ -132,7 +132,7 @@ let allowed_methods = response.headers.get("allow");
```rust ```rust
let patch_data = json!({"name": "Updated Name"}); let patch_data = json!({"name": "Updated Name"});
let response = client.patch_json("gurt://api.example.com/users/123", &patch_data).await?; let response = client.patch_json("lw://api.example.com/users/123", &patch_data).await?;
``` ```
## Response Handling ## Response Handling
@@ -152,7 +152,7 @@ pub struct GurtResponse {
### Accessing Response Data ### Accessing Response Data
```rust ```rust
let response = client.get("gurt://api.example.com/data").await?; let response = client.get("lw://api.example.com/data").await?;
// Status information // Status information
println!("Status Code: {}", response.status_code); println!("Status Code: {}", response.status_code);
@@ -201,14 +201,14 @@ All of this happens transparently when you call methods like `get()`, `post()`,
## URL Parsing ## URL Parsing
The client automatically parses `gurt://` URLs: The client automatically parses `lw://` URLs:
```rust ```rust
// These are all valid GURT URLs: // These are all valid GURT URLs:
client.get("gurt://example.com/").await?; // Port 4878 (default) client.get("lw://example.com/").await?; // Port 4878 (default)
client.get("gurt://example.com:8080/api").await?; // Custom port client.get("lw://example.com:8080/api").await?; // Custom port
client.get("gurt://192.168.1.100/test").await?; // IP address client.get("lw://192.168.1.100/test").await?; // IP address
client.get("gurt://localhost:4878/dev").await?; // Localhost client.get("lw://localhost:4878/dev").await?; // Localhost
``` ```
### URL Components ### URL Components
@@ -225,7 +225,7 @@ The client extracts:
```rust ```rust
use gurtlib::GurtError; use gurtlib::GurtError;
match client.get("gurt://invalid-url").await { match client.get("lw://invalid-url").await {
Ok(response) => { Ok(response) => {
// Handle successful response // Handle successful response
} }
@@ -332,7 +332,7 @@ impl ApiClient {
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
let api = ApiClient::new("gurt://api.example.com".to_string()); let api = ApiClient::new("lw://api.example.com".to_string());
// Create a user // Create a user
let new_user = CreateUser { let new_user = CreateUser {

View File

@@ -4,7 +4,7 @@ sidebar_position: 2
# GURT Protocol # GURT Protocol
**GURT** (version 1.0.0) is a TCP-based application protocol designed as an HTTP-like alternative with built-in TLS 1.3 encryption. It serves as the foundation for the Gurted ecosystem, enabling secure communication between clients and servers using the `gurt://` URL scheme. **GURT** (version 1.0.0) is a TCP-based application protocol designed as an HTTP-like alternative with built-in TLS 1.3 encryption. It serves as the foundation for the Gurted ecosystem, enabling secure communication between clients and servers using the `lw://` URL scheme.
## Overview ## Overview
@@ -21,12 +21,12 @@ GURT provides a familiar HTTP-like syntax while offering security through mandat
## URL Scheme ## URL Scheme
GURT uses the `gurt://` URL scheme: GURT uses the `lw://` URL scheme:
``` ```
gurt://example.com/path lw://example.com/path
gurt://192.168.1.100:4878/api/data lw://192.168.1.100:4878/api/data
gurt://localhost:4878/hello lw://localhost:4878/hello
``` ```
The protocol automatically defaults to port 4878. The protocol automatically defaults to port 4878.
@@ -244,13 +244,13 @@ GURT integrates with Gurted's custom DNS system:
### Direct IP Access ### Direct IP Access
``` ```
gurt://192.168.1.100:4878/ lw://192.168.1.100:4878/
gurt://localhost:4878/api lw://localhost:4878/api
``` ```
### Domain Resolution ### Domain Resolution
``` ```
gurt://example.real/ # Resolves via Gurted DNS lw://example.real/ # Resolves via Gurted DNS
``` ```
The Gurted DNS server resolves domains in the format `name.tld` to IP addresses, enabling human-readable domain names for GURT services. This is done automatically by your GURT browser and is documented in the [DNS System documentation](./dns-system.md). The Gurted DNS server resolves domains in the format `name.tld` to IP addresses, enabling human-readable domain names for GURT services. This is done automatically by your GURT browser and is documented in the [DNS System documentation](./dns-system.md).

View File

@@ -38,7 +38,7 @@ async fn main() -> Result<()> {
Ok(GurtResponse::ok().with_json_body(&users)) Ok(GurtResponse::ok().with_json_body(&users))
}); });
println!("GURT server starting on gurt://127.0.0.1:4878"); println!("GURT server starting on lw://127.0.0.1:4878");
server.listen("127.0.0.1:4878").await server.listen("127.0.0.1:4878").await
} }
``` ```
@@ -462,7 +462,7 @@ mod tests {
// Test with client // Test with client
let client = GurtClient::new(); let client = GurtClient::new();
let response = client.get("gurt://127.0.0.1:9999/test").await.unwrap(); let response = client.get("lw://127.0.0.1:9999/test").await.unwrap();
assert_eq!(response.status_code, 200); assert_eq!(response.status_code, 200);
assert_eq!(response.text().unwrap(), "test response"); assert_eq!(response.text().unwrap(), "test response");

View File

@@ -75,7 +75,7 @@ line breaks
Links can point to external URLs (which open in the user's default browser) or GURT protocol links: Links can point to external URLs (which open in the user's default browser) or GURT protocol links:
```html ```html
<a href="https://example.com">External link</a> <a href="https://example.com">External link</a>
<a href="gurt://internal.site">GURT protocol link</a> <a href="lw://internal.site">GURT protocol link</a>
``` ```
### Line Breaks ### Line Breaks
@@ -317,7 +317,7 @@ Network image loading with sizing controls:
```html ```html
<img src="https://example.com/image.jpg" style="max-w-24 max-h-24 rounded" /> <img src="https://example.com/image.jpg" style="max-w-24 max-h-24 rounded" />
<img src="gurt://local.site/image.png" style="w-32 h-32" /> <img src="lw://local.site/image.png" style="w-32 h-32" />
``` ```
## Advanced Features ## Advanced Features

View File

@@ -5,7 +5,7 @@ sidebar_position: 1
# Introduction # Introduction
**Gurted** is a project introducing a new web ecosystem, featuring: **Gurted** is a project introducing a new web ecosystem, featuring:
- the **gurt:// protocol** - the **lw:// protocol**
- a custom search engine - a custom search engine
- a custom browser - **Flumi** - a custom browser - **Flumi**
- a custom **DNS** (Domain Name System) - a custom **DNS** (Domain Name System)
@@ -22,7 +22,7 @@ Learn more about the GURT protocol: [Protocol Specification](./gurt-protocol.md)
Get started by **exploring Gurted sites** or **try creating your first GURT page**. Get started by **exploring Gurted sites** or **try creating your first GURT page**.
To get started, download: To get started, download:
- [Flumi](https://gurted.com/download/), the official browser for `gurt://` - [Flumi](https://gurted.com/download/), the official browser for `lw://`
- A *text editor* of choice, we recommend [Visual Studio Code](https://code.visualstudio.com/download) - A *text editor* of choice, we recommend [Visual Studio Code](https://code.visualstudio.com/download)
## Components ## Components
@@ -34,7 +34,7 @@ Gurted consists of three main components:
```html ```html
<head> <head>
<title>Yo Gurt</title> <title>Yo Gurt</title>
<icon src="gurt://example.real/icon.png"> <icon src="lw://example.real/icon.png">
<style>...</style> <style>...</style>
</head> </head>

View File

@@ -12,7 +12,7 @@ audio:stop() -- Stop and reset
audio.currentTime = 30.0 -- Seek to 30 seconds audio.currentTime = 30.0 -- Seek to 30 seconds
audio.volume = 0.8 -- Set volume (0.0 - 1.0) audio.volume = 0.8 -- Set volume (0.0 - 1.0)
audio.loop = true -- Enable looping audio.loop = true -- Enable looping
audio.src = 'gurt://new-audio.mp3' -- Change source audio.src = 'lw://new-audio.mp3' -- Change source
local duration = audio.duration local duration = audio.duration
local currentPos = audio.currentTime local currentPos = audio.currentTime

View File

@@ -14,7 +14,7 @@ download_id = gurt.download(url filename)
### Parameters ### Parameters
- **url** (string): The URL to download from. Supports HTTP, HTTPS, and gurt:// protocols. - **url** (string): The URL to download from. Supports HTTP, HTTPS, and lw:// protocols.
- **filename** (string, optional): The filename to save as. If not provided, the filename will be extracted from the URL or default to "download". - **filename** (string, optional): The filename to save as. If not provided, the filename will be extracted from the URL or default to "download".
### Returns ### Returns

View File

@@ -92,7 +92,7 @@ gurt.location.reload()
Navigates to a new URL. Navigates to a new URL.
```lua ```lua
gurt.location.goto('gurt://example.com/page') gurt.location.goto('lw://example.com/page')
gurt.location.goto('https://external-site.com') gurt.location.goto('https://external-site.com')
``` ```

View File

@@ -40,7 +40,7 @@ end
**Supported Methods:** `GET`, `POST`, `PUT`, `DELETE`, `HEAD`, `OPTIONS`, `PATCH` **Supported Methods:** `GET`, `POST`, `PUT`, `DELETE`, `HEAD`, `OPTIONS`, `PATCH`
**Relative URLs** are automatically resolved to the current domain with `gurt://` protocol. **Relative URLs** are automatically resolved to the current domain with `lw://` protocol.
## WebSocket API ## WebSocket API
@@ -89,8 +89,8 @@ trace.log(params) -- name%3DJohn%20Doe%26age%3D30
-- Building query strings -- Building query strings
local searchTerm = 'cats & dogs' local searchTerm = 'cats & dogs'
local url = 'gurt://search.com/api?q=' .. urlEncode(searchTerm) local url = 'lw://search.com/api?q=' .. urlEncode(searchTerm)
trace.log(url) -- gurt://search.com/api?q=cats%20%26%20dogs trace.log(url) -- lw://search.com/api?q=cats%20%26%20dogs
``` ```
### urlDecode(string) ### urlDecode(string)

View File

@@ -435,7 +435,7 @@ text = "Flumi"
layout_mode = 2 layout_mode = 2
theme = ExtResource("2_theme") theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1) theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1)
text = "Flumi is the official browser for the Gurted ecosystem, built using the Godot game engine. It provides a complete web browsing experience for gurt:// URLs with custom HTML/CSS rendering, Lua scripting support, and integration with the Gurted DNS system." text = "Flumi is the official browser for the Gurted ecosystem, built using the Godot game engine. It provides a complete web browsing experience for lw:// URLs with custom HTML/CSS rendering, Lua scripting support, and integration with the Gurted DNS system."
autowrap_mode = 3 autowrap_mode = 3
[node name="ProtocolPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"] [node name="ProtocolPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"]
@@ -463,7 +463,7 @@ layout_mode = 2
theme = ExtResource("2_theme") theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1) theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 20 theme_override_font_sizes/font_size = 20
text = "gurt://" text = "lw://"
[node name="DescriptionLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/ProtocolPanel/ProtocolSection/VBoxContainer"] [node name="DescriptionLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/ProtocolPanel/ProtocolSection/VBoxContainer"]
layout_mode = 2 layout_mode = 2
@@ -503,5 +503,5 @@ text = "Luau Integration"
layout_mode = 2 layout_mode = 2
theme = ExtResource("2_theme") theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1) theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1)
text = "Flumi uses Luau (Lua) for client-side scripting, providing dynamic content manipulation and interactive experiences within gurt:// pages. Similar to how HTTP web browsers user JavaScript." text = "Flumi uses Luau (Lua) for client-side scripting, providing dynamic content manipulation and interactive experiences within lw:// pages. Similar to how HTTP web browsers user JavaScript."
autowrap_mode = 3 autowrap_mode = 3

View File

@@ -421,8 +421,8 @@ text = "默认搜索引擎地址: "
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
theme_override_styles/normal = SubResource("StyleBoxFlat_input") theme_override_styles/normal = SubResource("StyleBoxFlat_input")
text = "gurt://search.web?q=" text = "lw://search.web?q="
placeholder_text = "gurt://search.web?q=" placeholder_text = "lw://search.web?q="
[node name="PrivacyPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"] [node name="PrivacyPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"]
visible = false visible = false

View File

@@ -84,7 +84,7 @@ func _start_download(download_id: String, url: String, save_path: String, downlo
"current_site": download_data.get("current_site", "") "current_site": download_data.get("current_site", "")
} }
if url.begins_with("gurt://"): if url.begins_with("lw://"):
_start_gurt_download(download_id, url) _start_gurt_download(download_id, url)
else: else:
_start_http_download(download_id, url) _start_http_download(download_id, url)

View File

@@ -14,7 +14,7 @@ static func set_dns_server(ip_port: String):
DNS_SERVER_PORT = 4878 DNS_SERVER_PORT = 4878
static func is_gurt_domain(url: String) -> bool: static func is_gurt_domain(url: String) -> bool:
if url.begins_with("gurt://"): if url.begins_with("lw://"):
return true return true
if not url.contains("://"): if not url.contains("://"):

View File

@@ -6,7 +6,7 @@ var settings_data = {
"startup_new_tab": true, "startup_new_tab": true,
"startup_specific_page": false, "startup_specific_page": false,
"startup_url": "", "startup_url": "",
"search_engine_url": "gurt://search.web?q=", "search_engine_url": "lw://search.web?q=",
"download_confirmation": true, "download_confirmation": true,
"dns_url": "135.125.163.131:4878" "dns_url": "135.125.163.131:4878"
} }

View File

@@ -198,7 +198,7 @@ func set_active_tab(index: int) -> void:
if tabs[index].has_content: if tabs[index].has_content:
main.current_domain = tabs[index].current_url main.current_domain = tabs[index].current_url
var display_text = main.current_domain var display_text = main.current_domain
if display_text.begins_with("gurt://"): if display_text.begins_with("lw://"):
display_text = display_text.substr(7) display_text = display_text.substr(7)
main.search_bar.text = display_text main.search_bar.text = display_text
else: else:

View File

@@ -40,7 +40,7 @@ static func get_or_create_gurt_client(domain: String) -> GurtProtocolClient:
static func extract_domain_from_url(gurt_url: String) -> String: static func extract_domain_from_url(gurt_url: String) -> String:
var host_domain = gurt_url var host_domain = gurt_url
if host_domain.begins_with("gurt://"): if host_domain.begins_with("lw://"):
host_domain = host_domain.right(-7) host_domain = host_domain.right(-7)
var slash_pos = host_domain.find("/") var slash_pos = host_domain.find("/")
if slash_pos != -1: if slash_pos != -1:

View File

@@ -40,7 +40,6 @@ var HTML_CONTENT = """
<title>新标签页</title> <title>新标签页</title>
</head> </head>
<body style="bg-[#323949] text-white font-sans"> <body style="bg-[#323949] text-white font-sans">
<postprocess preset="crt"></postprocess>
<div style="flex flex-col items-center justify-center w-full mt-12"> <div style="flex flex-col items-center justify-center w-full mt-12">
<h1 style="target text-8xl font-bold mb-4 text-[#4a9eff] font-serif font-italic">你好!</h1> <h1 style="target text-8xl font-bold mb-4 text-[#4a9eff] font-serif font-italic">你好!</h1>
<p style="text-lg mb-8 text-[#cccccc]">欢迎使用LeonBrowser</p> <p style="text-lg mb-8 text-[#cccccc]">欢迎使用LeonBrowser</p>

View File

@@ -27,7 +27,7 @@ static func load_font(font_info: Dictionary) -> void:
if src.begins_with("http://") or src.begins_with("https://"): if src.begins_with("http://") or src.begins_with("https://"):
load_web_font(font_info) load_web_font(font_info)
elif src.begins_with("gurt://"): elif src.begins_with("lw://"):
load_gurt_font(font_info) load_gurt_font(font_info)
else: else:
load_local_font(font_info) load_local_font(font_info)

View File

@@ -20,7 +20,7 @@ func fetch_image(url: String) -> ImageTexture:
var headers: PackedStringArray var headers: PackedStringArray
var response_headers = {} var response_headers = {}
if url.begins_with("gurt://"): if url.begins_with("lw://"):
var gurt_body = await fetch_gurt_resource(url, true) var gurt_body = await fetch_gurt_resource(url, true)
if gurt_body.is_empty(): if gurt_body.is_empty():
return null return null
@@ -160,7 +160,7 @@ func fetch_external_resource(url: String, base_url: String = "") -> String:
if resolved_url.begins_with("https://"): if resolved_url.begins_with("https://"):
return await fetch_text(resolved_url) return await fetch_text(resolved_url)
elif resolved_url.begins_with("gurt://"): elif resolved_url.begins_with("lw://"):
return fetch_gurt_resource(resolved_url) return fetch_gurt_resource(resolved_url)
else: else:
print("Resource loading error: Only HTTPS and GURT protocols are supported. Attempted: ", resolved_url) print("Resource loading error: Only HTTPS and GURT protocols are supported. Attempted: ", resolved_url)
@@ -171,8 +171,8 @@ func fetch_gurt_resource(url: String, as_binary: bool = false):
return PackedByteArray() if as_binary else "" return PackedByteArray() if as_binary else ""
var gurt_url = url var gurt_url = url
if not gurt_url.begins_with("gurt://"): if not gurt_url.begins_with("lw://"):
gurt_url = "gurt://" + gurt_url gurt_url = "lw://" + gurt_url
if gurt_url.contains("localhost"): if gurt_url.contains("localhost"):
gurt_url = gurt_url.replace("localhost", "127.0.0.1") gurt_url = gurt_url.replace("localhost", "127.0.0.1")

View File

@@ -102,19 +102,19 @@ func load_audio_async(src: String) -> void:
reset_stream_state() reset_stream_state()
if src.begins_with("https://") or src.begins_with("gurt://"): if src.begins_with("https://") or src.begins_with("lw://"):
await load_remote_audio(src) await load_remote_audio(src)
else: else:
print("Audio loading error: Only HTTPS and GURT protocols are supported. Attempted: ", src) print("Audio loading error: Only HTTPS and GURT protocols are supported. Attempted: ", src)
return return
func load_remote_audio(src: String) -> void: func load_remote_audio(src: String) -> void:
if not (src.begins_with("https://") or src.begins_with("gurt://")): if not (src.begins_with("https://") or src.begins_with("lw://")):
return return
if src.begins_with("https://"): if src.begins_with("https://"):
await load_https_audio(src) await load_https_audio(src)
elif src.begins_with("gurt://"): elif src.begins_with("lw://"):
await load_gurt_audio(src) await load_gurt_audio(src)
func load_https_audio(src: String) -> void: func load_https_audio(src: String) -> void:

View File

@@ -79,7 +79,7 @@ static func get_current_domain() -> String:
static func sanitize_domain_for_filename(domain: String) -> String: static func sanitize_domain_for_filename(domain: String) -> String:
# Remove protocol prefix # Remove protocol prefix
if domain.begins_with("gurt://"): if domain.begins_with("lw://"):
domain = domain.substr(7) domain = domain.substr(7)
elif domain.contains("://"): elif domain.contains("://"):
var parts = domain.split("://") var parts = domain.split("://")

View File

@@ -12,7 +12,7 @@ static func setup_network_api(vm: LuauVM):
vm.lua_setglobal("fetch") vm.lua_setglobal("fetch")
static func resolve_fetch_url(url: String) -> String: static func resolve_fetch_url(url: String) -> String:
if url.begins_with("http://") or url.begins_with("https://") or url.begins_with("gurt://"): if url.begins_with("http://") or url.begins_with("https://") or url.begins_with("lw://"):
return url return url
var main_node = Engine.get_main_loop().current_scene var main_node = Engine.get_main_loop().current_scene
@@ -22,9 +22,9 @@ static func resolve_fetch_url(url: String) -> String:
if current_domain.is_empty(): if current_domain.is_empty():
if url.begins_with("/"): if url.begins_with("/"):
return "gurt://" + url.substr(1) return "lw://" + url.substr(1)
else: else:
return "gurt://" + url return "lw://" + url
return URLUtils.resolve_url(current_domain, url) return URLUtils.resolve_url(current_domain, url)
@@ -35,7 +35,7 @@ static func _lua_fetch_handler(vm: LuauVM) -> int:
if vm.lua_gettop() >= 2 and vm.lua_istable(2): if vm.lua_gettop() >= 2 and vm.lua_istable(2):
options = vm.lua_todictionary(2) options = vm.lua_todictionary(2)
# Resolve relative URLs and default to gurt:// protocol # Resolve relative URLs and default to lw:// protocol
var url = resolve_fetch_url(original_url) var url = resolve_fetch_url(original_url)
# Default options # Default options
@@ -135,7 +135,7 @@ static func _response_ok_handler(vm: LuauVM) -> int:
return 1 return 1
static func make_http_request(url: String, method: String, headers: PackedStringArray, body: String) -> Dictionary: static func make_http_request(url: String, method: String, headers: PackedStringArray, body: String) -> Dictionary:
if url.begins_with("gurt://"): if url.begins_with("lw://"):
return make_gurt_request(url, method, headers, body) return make_gurt_request(url, method, headers, body)
var http_client = HTTPClient.new() var http_client = HTTPClient.new()
var response_data = { var response_data = {
@@ -320,7 +320,7 @@ static func make_gurt_request(url: String, method: String, headers: PackedString
"body": "" "body": ""
} }
var domain_part = url.replace("gurt://", "") var domain_part = url.replace("lw://", "")
if domain_part.contains("/"): if domain_part.contains("/"):
domain_part = domain_part.split("/")[0] domain_part = domain_part.split("/")[0]

View File

@@ -3,7 +3,7 @@ extends RefCounted
static func resolve_url(base_url: String, relative_url: String) -> String: static func resolve_url(base_url: String, relative_url: String) -> String:
# If relative_url is already absolute, return it as-is # If relative_url is already absolute, return it as-is
if relative_url.begins_with("http://") or relative_url.begins_with("https://") or relative_url.begins_with("gurt://") or relative_url.begins_with("file://"): if relative_url.begins_with("http://") or relative_url.begins_with("https://") or relative_url.begins_with("lw://") or relative_url.begins_with("file://"):
return relative_url return relative_url
# If empty, treat as relative to current domain # If empty, treat as relative to current domain
@@ -94,7 +94,7 @@ static func extract_domain(url: String) -> String:
return "" return ""
var clean_url = url var clean_url = url
if clean_url.begins_with("gurt://"): if clean_url.begins_with("lw://"):
clean_url = clean_url.substr(7) clean_url = clean_url.substr(7)
elif clean_url.begins_with("https://"): elif clean_url.begins_with("https://"):
clean_url = clean_url.substr(8) clean_url = clean_url.substr(8)

View File

@@ -120,8 +120,8 @@ func _on_search_submitted(url: String, add_to_history: bool = true) -> void:
tab.start_loading() tab.start_loading()
var gurt_url = url var gurt_url = url
if not gurt_url.begins_with("gurt://"): if not gurt_url.begins_with("lw://"):
gurt_url = "gurt://" + gurt_url gurt_url = "lw://" + gurt_url
await fetch_gurt_content_async(gurt_url, tab, url, add_to_history) await fetch_gurt_content_async(gurt_url, tab, url, add_to_history)
else: else:
@@ -289,7 +289,7 @@ func _on_search_focus_entered() -> void:
func _on_search_focus_exited() -> void: func _on_search_focus_exited() -> void:
if not current_domain.is_empty(): if not current_domain.is_empty():
var display_text = current_domain var display_text = current_domain
if display_text.begins_with("gurt://"): if display_text.begins_with("lw://"):
display_text = display_text.right(-7) display_text = display_text.right(-7)
elif display_text.begins_with("file://"): elif display_text.begins_with("file://"):
display_text = URLUtils.file_url_to_path(display_text) display_text = URLUtils.file_url_to_path(display_text)
@@ -828,7 +828,7 @@ func reload_current_page() -> void:
_on_search_submitted(current_domain) _on_search_submitted(current_domain)
func navigate_to_url(url: String, add_to_history: bool = true) -> void: func navigate_to_url(url: String, add_to_history: bool = true) -> void:
if url.begins_with("gurt://") or url.begins_with("file://"): if url.begins_with("lw://") or url.begins_with("file://"):
_on_search_submitted(url, add_to_history) _on_search_submitted(url, add_to_history)
else: else:
var resolved_url = resolve_url(url) var resolved_url = resolve_url(url)
@@ -837,7 +837,7 @@ func navigate_to_url(url: String, add_to_history: bool = true) -> void:
func update_search_bar_from_current_domain() -> void: func update_search_bar_from_current_domain() -> void:
if not search_bar.has_focus() and not current_domain.is_empty(): if not search_bar.has_focus() and not current_domain.is_empty():
var display_text = current_domain var display_text = current_domain
if display_text.begins_with("gurt://"): if display_text.begins_with("lw://"):
display_text = display_text.right(-7) display_text = display_text.right(-7)
elif display_text.begins_with("file://"): elif display_text.begins_with("file://"):
display_text = URLUtils.file_url_to_path(display_text) display_text = URLUtils.file_url_to_path(display_text)
@@ -878,7 +878,7 @@ func add_to_history(url: String, tab: Tab, add_to_navigation: bool = true):
icon_url = tab.get_meta("parsed_icon_url") icon_url = tab.get_meta("parsed_icon_url")
var clean_url = url var clean_url = url
if clean_url.begins_with("gurt://"): if clean_url.begins_with("lw://"):
clean_url = clean_url.right(-7) clean_url = clean_url.right(-7)
BrowserHistory.add_entry(clean_url, title, icon_url) BrowserHistory.add_entry(clean_url, title, icon_url)
@@ -922,7 +922,7 @@ func get_startup_behavior() -> Dictionary:
func _handle_startup_behavior(): func _handle_startup_behavior():
var args = OS.get_cmdline_args() var args = OS.get_cmdline_args()
for arg in args: for arg in args:
if arg.begins_with("gurt://"): if arg.begins_with("lw://"):
print("Opening URL from command line: ", arg) print("Opening URL from command line: ", arg)
_on_search_submitted(arg, true) _on_search_submitted(arg, true)
return return

View File

@@ -44,7 +44,7 @@ For production deployments, you can use the Gurted Certificate Authority to get
3. **Follow the DNS challenge instructions:** 3. **Follow the DNS challenge instructions:**
When prompted, add the TXT record to your domain: When prompted, add the TXT record to your domain:
- Go to gurt://dns.web (or your DNS server) - Go to lw://dns.web (or your DNS server)
- Login and navigate to your domain - Login and navigate to your domain
- Add a TXT record with: - Add a TXT record with:
- Name: `_gurtca-challenge` - Name: `_gurtca-challenge`

View File

@@ -16,7 +16,7 @@ GURT networking extension for Godot.
var client = GurtProtocolClient.new() var client = GurtProtocolClient.new()
client.create_client(30) # 30s timeout client.create_client(30) # 30s timeout
var response = client.request("gurt://127.0.0.1:4878", {"method": "GET"}) var response = client.request("lw://127.0.0.1:4878", {"method": "GET"})
client.disconnect() # cleanup client.disconnect() # cleanup

View File

@@ -3,7 +3,7 @@ use crate::client::{Challenge, GurtCAClient};
pub async fn complete_dns_challenge(challenge: &Challenge, client: &GurtCAClient) -> Result<()> { pub async fn complete_dns_challenge(challenge: &Challenge, client: &GurtCAClient) -> Result<()> {
println!("Please add this TXT record to your domain:"); println!("Please add this TXT record to your domain:");
println!(" 1. Go to gurt://dns.web (or your DNS server)"); println!(" 1. Go to lw://dns.web (or your DNS server)");
println!(" 2. Login and navigate to your domain: {}", challenge.domain); println!(" 2. Login and navigate to your domain: {}", challenge.domain);
println!(" 3. Add TXT record:"); println!(" 3. Add TXT record:");
println!(" Name: _gurtca-challenge"); println!(" Name: _gurtca-challenge");
@@ -30,7 +30,7 @@ async fn verify_dns_txt_record(domain: &str, expected_value: &str, client: &Gurt
}); });
let response = client let response = client
.post_json("gurt://dns.web/resolve-full", &request) .post_json("lw://dns.web/resolve-full", &request)
.await?; .await?;
if response.is_success() { if response.is_success() {

View File

@@ -199,7 +199,7 @@ impl GurtCAClient {
async fn fetch_ca_via_http(&self) -> Result<String> { async fn fetch_ca_via_http(&self) -> Result<String> {
let http_url = self.ca_url let http_url = self.ca_url
.replace("gurt://", "http://") .replace("lw://", "http://")
.replace(":8877", ":8876"); .replace(":8877", ":8876");
let client = reqwest::Client::new(); let client = reqwest::Client::new();

View File

@@ -12,7 +12,7 @@ struct Cli {
#[command(subcommand)] #[command(subcommand)]
command: Commands, command: Commands,
#[arg(long, default_value = "gurt://dns.web")] #[arg(long, default_value = "lw://dns.web")]
ca_url: String, ca_url: String,
} }

View File

@@ -5,7 +5,7 @@ edition = "2021"
authors = ["FaceDev"] authors = ["FaceDev"]
license = "MIT" license = "MIT"
repository = "https://github.com/outpoot/gurted" repository = "https://github.com/outpoot/gurted"
description = "Official GURT:// protocol implementation" description = "Official lw:// protocol implementation"
[lib] [lib]
name = "gurtlib" name = "gurtlib"

View File

@@ -12,7 +12,7 @@ async fn main() -> Result<()> {
Ok(GurtResponse::ok().with_string_body("Test endpoint working!")) Ok(GurtResponse::ok().with_string_body("Test endpoint working!"))
}); });
println!("Starting GURT server on gurt://127.0.0.1:4878"); println!("Starting GURT server on lw://127.0.0.1:4878");
server.listen("127.0.0.1:4878").await server.listen("127.0.0.1:4878").await
} }

View File

@@ -518,7 +518,7 @@ impl GurtClient {
let parsed_url = Url::parse(url).map_err(|e| GurtError::invalid_message(format!("Invalid URL: {}", e)))?; let parsed_url = Url::parse(url).map_err(|e| GurtError::invalid_message(format!("Invalid URL: {}", e)))?;
if parsed_url.scheme() != "gurt" { if parsed_url.scheme() != "gurt" {
return Err(GurtError::invalid_message("URL must use gurt:// scheme")); return Err(GurtError::invalid_message("URL must use lw:// scheme"));
} }
let host = parsed_url.host_str().ok_or_else(|| GurtError::invalid_message("URL must have a host"))?.to_string(); let host = parsed_url.host_str().ok_or_else(|| GurtError::invalid_message("URL must have a host"))?.to_string();
@@ -767,12 +767,12 @@ mod tests {
async fn test_url_parsing() { async fn test_url_parsing() {
let client = GurtClient::new(); let client = GurtClient::new();
let (host, port, path) = client.parse_gurt_url("gurt://example.com/test").unwrap(); let (host, port, path) = client.parse_gurt_url("lw://example.com/test").unwrap();
assert_eq!(host, "example.com"); assert_eq!(host, "example.com");
assert_eq!(port, DEFAULT_PORT); assert_eq!(port, DEFAULT_PORT);
assert_eq!(path, "/test"); assert_eq!(path, "/test");
let (host, port, path) = client.parse_gurt_url("gurt://example.com:8080/api/v1").unwrap(); let (host, port, path) = client.parse_gurt_url("lw://example.com:8080/api/v1").unwrap();
assert_eq!(host, "example.com"); assert_eq!(host, "example.com");
assert_eq!(port, 8080); assert_eq!(port, 8080);
assert_eq!(path, "/api/v1"); assert_eq!(path, "/api/v1");

View File

@@ -967,24 +967,6 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "gurt"
version = "0.1.0"
dependencies = [
"base64 0.22.1",
"chrono",
"rustls 0.23.31",
"rustls-native-certs",
"rustls-pemfile 2.2.0",
"serde",
"serde_json",
"thiserror",
"tokio",
"tokio-rustls",
"tracing",
"url",
]
[[package]] [[package]]
name = "gurted-search-engine" name = "gurted-search-engine"
version = "0.1.0" version = "0.1.0"
@@ -995,7 +977,7 @@ dependencies = [
"clap", "clap",
"futures", "futures",
"glob", "glob",
"gurt", "gurtlib",
"lol_html", "lol_html",
"mime", "mime",
"regex", "regex",
@@ -1016,6 +998,24 @@ dependencies = [
"uuid", "uuid",
] ]
[[package]]
name = "gurtlib"
version = "0.1.1"
dependencies = [
"base64 0.22.1",
"chrono",
"rustls 0.23.31",
"rustls-native-certs",
"rustls-pemfile 2.2.0",
"serde",
"serde_json",
"thiserror",
"tokio",
"tokio-rustls",
"tracing",
"url",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.27" version = "0.3.27"

View File

@@ -76,7 +76,7 @@ impl Config {
} }
pub fn gurt_protocol_url(&self) -> String { pub fn gurt_protocol_url(&self) -> String {
format!("gurt://{}:{}", self.server.address, self.server.port) format!("lw://{}:{}", self.server.address, self.server.port)
} }
pub fn is_allowed_extension(&self, extension: &str) -> bool { pub fn is_allowed_extension(&self, extension: &str) -> bool {

View File

@@ -418,7 +418,7 @@ impl DomainCrawler {
let url_str = Self::normalize_url(absolute_url.to_string()); let url_str = Self::normalize_url(absolute_url.to_string());
// Only include GURT protocol URLs for the same domain // Only include GURT protocol URLs for the same domain
if url_str.starts_with("gurt://") { if url_str.starts_with("lw://") {
if let Ok(parsed) = Url::parse(&url_str) { if let Ok(parsed) = Url::parse(&url_str) {
if let Some(host) = parsed.host_str() { if let Some(host) = parsed.host_str() {
if let Ok(base_parsed) = Url::parse(base_url) { if let Ok(base_parsed) = Url::parse(base_url) {
@@ -742,31 +742,31 @@ mod tests {
#[test] #[test]
fn parse_clanker_rules_preserves_case_in_allowed_urls() { fn parse_clanker_rules_preserves_case_in_allowed_urls() {
let content = "User-agent: TestBot\nAllow: /getpage?l=Fri,12Sep2025000605_ZzesV.txt\n"; let content = "User-agent: TestBot\nAllow: /getpage?l=Fri,12Sep2025000605_ZzesV.txt\n";
let result = DomainCrawler::parse_clanker_rules(content, "gurt://wi.ki", "TestBot") let result = DomainCrawler::parse_clanker_rules(content, "lw://wi.ki", "TestBot")
.expect("expected allow list"); .expect("expected allow list");
assert_eq!( assert_eq!(
result, result,
vec!["gurt://wi.ki/getpage?l=Fri,12Sep2025000605_ZzesV.txt".to_string()] vec!["lw://wi.ki/getpage?l=Fri,12Sep2025000605_ZzesV.txt".to_string()]
); );
} }
#[test] #[test]
fn parse_clanker_rules_handles_case_insensitive_directives() { fn parse_clanker_rules_handles_case_insensitive_directives() {
let content = "user-Agent: AnotherBot\nAlLoW: /MiXeD/Path.HTML\n"; let content = "user-Agent: AnotherBot\nAlLoW: /MiXeD/Path.HTML\n";
let result = DomainCrawler::parse_clanker_rules(content, "gurt://example", "AnotherBot") let result = DomainCrawler::parse_clanker_rules(content, "lw://example", "AnotherBot")
.expect("expected allow list"); .expect("expected allow list");
assert_eq!( assert_eq!(
result, result,
vec!["gurt://example/MiXeD/Path.HTML".to_string()] vec!["lw://example/MiXeD/Path.HTML".to_string()]
); );
} }
#[test] #[test]
fn parse_clanker_rules_respects_disallow_all() { fn parse_clanker_rules_respects_disallow_all() {
let content = "User-agent: Bot\nDisallow: /\n"; let content = "User-agent: Bot\nDisallow: /\n";
let result = DomainCrawler::parse_clanker_rules(content, "gurt://example", "Bot"); let result = DomainCrawler::parse_clanker_rules(content, "lw://example", "Bot");
assert!(result.is_err()); assert!(result.is_err());
} }

View File

@@ -17,7 +17,7 @@ impl Domain {
} }
pub fn gurt_url(&self) -> String { pub fn gurt_url(&self) -> String {
format!("gurt://{}.{}", self.name, self.tld) format!("lw://{}.{}", self.name, self.tld)
} }
} }

View File

@@ -7,7 +7,7 @@
<link rel="apple-touch-icon" href="/favicon.ico" /> <link rel="apple-touch-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Gurted</title> <title>Gurted</title>
<meta name="description" content="Gurted introduces a new web ecosystem with the gurt:// protocol, custom browser Flumi, and revolutionary HTML/CSS/Lua standards." /> <meta name="description" content="Gurted introduces a new web ecosystem with the lw:// protocol, custom browser Flumi, and revolutionary HTML/CSS/Lua standards." />
%sveltekit.head% %sveltekit.head%
</head> </head>
<body data-sveltekit-preload-data="hover" class="dark bg-background text-foreground"> <body data-sveltekit-preload-data="hover" class="dark bg-background text-foreground">

View File

@@ -29,7 +29,7 @@
<title>Gurted</title> <title>Gurted</title>
<meta <meta
name="description" name="description"
content="A web ecosystem with the gurt:// protocol, custom browser Flumi, DNS system, and modern HTML/CSS/Lua standards." content="A web ecosystem with the lw:// protocol, custom browser Flumi, DNS system, and modern HTML/CSS/Lua standards."
/> />
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" /> <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" />
@@ -49,7 +49,7 @@
</h1> </h1>
<p class="text-muted-foreground mx-auto mb-4 max-w-3xl text-xl md:text-2xl"> <p class="text-muted-foreground mx-auto mb-4 max-w-3xl text-xl md:text-2xl">
A web ecosystem introducing the <code A web ecosystem introducing the <code
class="bg-muted text-primary rounded px-2 py-1 font-mono">gurt://</code class="bg-muted text-primary rounded px-2 py-1 font-mono">lw://</code
> protocol > protocol
</p> </p>
@@ -246,7 +246,7 @@
class="language-html" class="language-html"
>{`<head> >{`<head>
<title>My Gurt Site</title> <title>My Gurt Site</title>
<icon src="gurt://example.real/icon.png"> <icon src="lw://example.real/icon.png">
</head> </head>
<body> <body>

View File

@@ -77,7 +77,7 @@
-- no ai slop btw -- no ai slop btw
downloadPeakBtn:on('click', function() downloadPeakBtn:on('click', function()
-- i expect you to host this yourself -- i expect you to host this yourself
local downloadId = gurt.download("gurt://127.0.0.1", "peakshit.iso") local downloadId = gurt.download("lw://127.0.0.1", "peakshit.iso")
addLog(`started your peak download {downloadId}`) addLog(`started your peak download {downloadId}`)
end) end)
@@ -138,7 +138,7 @@ gurt.select("#download-shit"):on("click", function()
end) end)
gurt.select("#download-peak"):on("click", function() gurt.select("#download-peak"):on("click", function()
local downloadId = gurt.download("gurt://127.0.0.1", "peakshit.iso") local downloadId = gurt.download("lw://127.0.0.1", "peakshit.iso")
end) end)
</div> </div>
</div> </div>