Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Docs/examples/web-servers/01-basic-hello-server.wfl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Basic Hello World Web Server
//
// This is the simplest possible web server in WFL.
// It demonstrates the core web server syntax: listen, wait, and respond.
//
// To run this example:
// 1. Save as hello-server.wfl
// 2. Run: wfl hello-server.wfl
// 3. Visit http://127.0.0.1:8080 in your browser
//
// Expected output: "Hello from WFL Web Server!"

display "=== Basic Hello World Web Server ==="
display "Starting web server on port 8080..."

// Start the web server - this creates an HTTP server listening on port 8080
listen on port 8080 as web_server

display "✓ Server started successfully!"
display "Visit http://127.0.0.1:8080 in your browser"

// Wait for an incoming HTTP request
wait for request comes in on web_server as req

display "Received request: " with method with " " with path

// Send a simple text response
respond to req with "Hello from WFL Web Server!"

display "Server responded to request"
display "Example complete!"
65 changes: 65 additions & 0 deletions Docs/examples/web-servers/02-file-server-basic.wfl
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Basic File Server - Reads and Serves File Contents
//
// This example demonstrates reading a file from disk and serving its contents
// as an HTTP response. This is exactly what was requested in GitHub issue #213.
//
// To run this example:
// 1. Create a file called "content.txt" with some text
// 2. Save this as file-server.wfl
// 3. Run: wfl file-server.wfl
// 4. Visit http://127.0.0.1:8080 in your browser
//
// Key concepts:
// - Reading files with open/read/close
// - Serving file contents as HTTP responses
// - Basic error handling with try/catch
// - Setting content types

display "=== Basic File Server Example ==="
display "This server reads files and serves their contents as HTTP responses"

// Create a sample file for demonstration
try:
create file at "content.txt" with "Hello from WFL File Server!
This content was read from a file on disk.
WFL makes file serving simple and natural."
display "✓ Created sample content.txt file"
catch:
display "Note: Using existing content.txt file"
end try

display "Starting web server on port 8080..."
listen on port 8080 as file_server

display "✓ Server started successfully!"
display "Visit http://127.0.0.1:8080 to see file contents"

// Wait for a request
wait for request comes in on file_server as req

display "Request received: " with method with " " with path

// Read file and serve its contents
try:
// Open the file for reading
open file at "content.txt" for reading as text_file

// Read the entire file content into a variable
store file_content as read content from text_file

// Close the file (good practice)
close file text_file

// Send the file content as the HTTP response
respond to req with file_content and content_type "text/plain"

display "✓ Successfully served file content"
display "File content length: " with length of file_content with " characters"

catch:
// Handle file errors (file not found, permission denied, etc.)
respond to req with "Error: Could not read content.txt file" and status 404
display "❌ Error reading file: " with error message
end try

display "=== File Server Example Complete ==="
145 changes: 145 additions & 0 deletions Docs/examples/web-servers/03-multi-route-server.wfl
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Multi-Route File Server - Handle Different URLs
//
// This example shows how to handle different URL paths and serve different files
// based on the requested path. It demonstrates basic routing concepts.
//
// To run this example:
// 1. Create files: index.html, about.txt, data.json
// 2. Save this as multi-route-server.wfl
// 3. Run: wfl multi-route-server.wfl
// 4. Visit different URLs:
// - http://127.0.0.1:8080/ (serves index.html)
// - http://127.0.0.1:8080/about (serves about.txt)
// - http://127.0.0.1:8080/data (serves data.json)
// - http://127.0.0.1:8080/anything-else (shows 404)
//
// Key concepts:
// - URL path routing with check/otherwise
// - Different content types for different file types
// - HTTP status codes (200 OK, 404 Not Found)
// - Conditional file serving

display "=== Multi-Route File Server Example ==="

// Create sample files for demonstration
try:
create file at "index.html" with "<!DOCTYPE html>
<html>
<head><title>WFL File Server</title></head>
<body>
<h1>Welcome to WFL File Server!</h1>
<p>This HTML file was served by WFL.</p>
<ul>
<li><a href='/about'>About page</a></li>
<li><a href='/data'>JSON data</a></li>
</ul>
</body>
</html>"
display "✓ Created index.html"
catch:
display "Using existing index.html"
end try
Comment on lines +24 to +41

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example creates sample files at runtime, which means running this example multiple times may have unexpected behavior. The catch block on line 39 handles existing files, but this pattern makes the example less predictable. Consider documenting that users should create these files manually before running, or handle file creation more explicitly.

Suggested change
// Create sample files for demonstration
try:
create file at "index.html" with "<!DOCTYPE html>
<html>
<head><title>WFL File Server</title></head>
<body>
<h1>Welcome to WFL File Server!</h1>
<p>This HTML file was served by WFL.</p>
<ul>
<li><a href='/about'>About page</a></li>
<li><a href='/data'>JSON data</a></li>
</ul>
</body>
</html>"
display "✓ Created index.html"
catch:
display "Using existing index.html"
end try
// This example assumes that the files index.html, about.txt, and data.json
// have been created manually before running (see instructions above).

Copilot uses AI. Check for mistakes.

try:
create file at "about.txt" with "About WFL File Server

This is a simple file server built with WFL (WebFirst Language).
WFL uses natural language syntax to make web development intuitive.

Key features:
- Natural English-like syntax
- Built-in web server capabilities
- Simple file serving
- Easy error handling"
display "✓ Created about.txt"
catch:
display "Using existing about.txt"
end try

try:
create file at "data.json" with "{
\"message\": \"Hello from WFL!\",
\"server\": \"WFL File Server\",
\"features\": [
\"Natural language syntax\",
\"Built-in web server\",
\"File serving\",
\"JSON support\"
],
\"version\": \"1.0\"
}"
display "✓ Created data.json"
catch:
display "Using existing data.json"
end try

display "Starting multi-route server on port 8080..."
listen on port 8080 as multi_server

display "✓ Server started successfully!"
display "Available routes:"
display " http://127.0.0.1:8080/ - HTML home page"
display " http://127.0.0.1:8080/about - Text about page"
display " http://127.0.0.1:8080/data - JSON data"

// Wait for a request
wait for request comes in on multi_server as req

display "Request: " with method with " " with path

// Route handling based on URL path
check if path is equal to "/":
// Serve the home page (HTML file)
try:
open file at "index.html" for reading as html_file
store html_content as read content from html_file
close file html_file
respond to req with html_content and content_type "text/html"
display "✓ Served HTML home page"
catch:
respond to req with "Error loading home page" and status 500
display "❌ Error serving home page"
end try

check if path is equal to "/about":
// Serve the about page (text file)
try:
open file at "about.txt" for reading as about_file
store about_content as read content from about_file
close file about_file
respond to req with about_content and content_type "text/plain"
display "✓ Served about page"
catch:
respond to req with "About page not found" and status 404
display "❌ Error serving about page"
end try

check if path is equal to "/data":
// Serve JSON data
try:
open file at "data.json" for reading as json_file
store json_content as read content from json_file
close file json_file
respond to req with json_content and content_type "application/json"
display "✓ Served JSON data"
catch:
respond to req with "Data not found" and status 404
display "❌ Error serving JSON data"
end try

otherwise:
// Handle 404 - Page not found
store not_found_html as "<!DOCTYPE html>
<html>
<head><title>404 Not Found</title></head>
<body>
<h1>404 - Page Not Found</h1>
<p>The requested page <code>" with path with "</code> was not found.</p>
<p><a href='/'>← Return to home page</a></p>
</body>
</html>"
respond to req with not_found_html and status 404 and content_type "text/html"
display "❌ 404 Not Found: " with path
end check

display "=== Multi-Route Server Example Complete ==="
149 changes: 149 additions & 0 deletions Docs/examples/web-servers/04-advanced-comprehensive.wfl
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Advanced Comprehensive Web Server
//
// This is a simplified version of the comprehensive web server demo that shows
// advanced features like JSON APIs, different HTTP methods, and request logging.
// Based on TestPrograms/comprehensive_web_server_demo.wfl but with explanatory comments.
//
// To run this example:
// 1. Save as advanced-server.wfl
// 2. Run: wfl advanced-server.wfl
// 3. Visit different endpoints:
// - http://127.0.0.1:8080/ (HTML home page)
// - http://127.0.0.1:8080/api/status (JSON status)
// - http://127.0.0.1:8080/api/time (JSON current time)
//
// Key concepts:
// - JSON API endpoints
// - Dynamic content generation
// - Server statistics and logging
// - Multiple content types
// - Request information access

display "=== Advanced Comprehensive Web Server ==="
display "This server demonstrates advanced WFL web features"

// Server configuration
store server_port as 8080
store request_count as 0
store server_start_time as current time in milliseconds

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable server_start_time uses current time in milliseconds but this may not match WFL's actual time function syntax. Verify that current time in milliseconds is the correct WFL syntax, as other examples use current time without the milliseconds specification.

Suggested change
store server_start_time as current time in milliseconds
store server_start_time as current time

Copilot uses AI. Check for mistakes.

display "Starting advanced web server on port " with server_port with "..."
listen on port server_port as advanced_server

display "✓ Server started successfully!"
display "Available endpoints:"
display " GET http://127.0.0.1:8080/ - HTML home page"
display " GET http://127.0.0.1:8080/api/status - JSON server status"
display " GET http://127.0.0.1:8080/api/time - JSON current time"
display ""

// Wait for incoming request
wait for request comes in on advanced_server as req

// Increment request counter for statistics
store request_count as request_count plus 1

// Log the incoming request (middleware-like behavior)
display "Request #" with request_count with ": " with method with " " with path
display " Client IP: " with client_ip
display " User Agent: " with (headers at "user-agent" or "Unknown")

Copilot AI Jan 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The syntax headers at \"user-agent\" or \"Unknown\" uses an unconventional pattern for accessing headers with a fallback. This should be verified against WFL's actual header access syntax. If headers access doesn't support the or operator for default values, this will fail at runtime.

Suggested change
display " User Agent: " with (headers at "user-agent" or "Unknown")
display " User Agent: " with (headers at "user-agent")

Copilot uses AI. Check for mistakes.

Comment on lines +40 to +50

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Search for dictionary/map access patterns in WFL files
echo "=== Searching for 'at' keyword usage in WFL files ==="
rg -n '\bat\b.*"' --type=wfl -C2 | head -100

echo -e "\n=== Searching for 'or' operator with dictionary access ==="
rg -n 'at.*or' --type=wfl -C2 | head -100

echo -e "\n=== Searching for 'headers' dictionary access patterns ==="
rg -n 'headers\s+(at|with)' --type=wfl -C2 | head -100

echo -e "\n=== Looking for WFL documentation on dictionary syntax ==="
fd -e wfl -e md | xargs grep -l "dictionary\|map\|access" | head -10

Repository: WebFirstLanguage/wfl

Length of output: 3988


🏁 Script executed:

# Find all .wfl files
echo "=== All .wfl files in repo ==="
find . -name "*.wfl" -type f | head -20

# Read the specific file mentioned in the review
echo -e "\n=== Content of the file being reviewed ==="
cat -n "Docs/examples/web-servers/04-advanced-comprehensive.wfl" 2>/dev/null || echo "File not found with that path"

# Try alternative paths
echo -e "\n=== Searching for the file ==="
find . -name "*04-advanced-comprehensive*" -type f

Repository: WebFirstLanguage/wfl

Length of output: 7366


🏁 Script executed:

# Search all .wfl files for dictionary access patterns with "at"
echo "=== Searching for 'at' keyword usage in all .wfl files ==="
grep -n '\bat\b' ./Docs/examples/web-servers/*.wfl ./Nexus/*.wfl 2>/dev/null | head -50

# Search for 'or' operator in context of dictionary/variable access
echo -e "\n=== Searching for 'or' with variable access ==="
grep -n ' or ' ./Docs/examples/web-servers/*.wfl ./Nexus/*.wfl 2>/dev/null | head -50

# Check if headers variable is documented anywhere
echo -e "\n=== Searching for 'headers' in WFL files ==="
grep -n 'headers' ./Docs/examples/web-servers/*.wfl ./Nexus/*.wfl 2>/dev/null

# Look at the list module documentation
echo -e "\n=== Check list/map module documentation ==="
head -100 ./Docs/api/list-module.md 2>/dev/null || echo "File not found"

Repository: WebFirstLanguage/wfl

Length of output: 5791


🏁 Script executed:

# Search for documentation on map/dictionary access
echo "=== Searching for map, dictionary, or object documentation ==="
find ./Docs -name "*.md" -type f | xargs grep -l "map\|dictionary\|object" 2>/dev/null | head -20

# Look at the API documentation index
echo -e "\n=== API documentation files ==="
ls -la ./Docs/api/ 2>/dev/null

# Check for request handling documentation
echo -e "\n=== Searching for request object documentation ==="
grep -r "request" ./Docs/api/*.md 2>/dev/null | grep -i "header\|field\|access" | head -20

# Look for bracket notation examples in examples
echo -e "\n=== Checking for bracket notation in examples ==="
grep -n '\[.*\]' ./Docs/examples/web-servers/*.wfl | head -30

Repository: WebFirstLanguage/wfl

Length of output: 1939


🏁 Script executed:

# Check container system documentation for map/object access syntax
echo "=== Container System Documentation (map/object access) ==="
head -150 ./Docs/api/container-system.md

echo -e "\n=== Core Module Documentation (likely includes request object) ==="
cat ./Docs/api/core-module.md

echo -e "\n=== Searching for request handling in by-example guide ==="
grep -n "request\|header" ./Docs/guides/wfl-by-example.md | head -30

Repository: WebFirstLanguage/wfl

Length of output: 11614


🏁 Script executed:

# Get the full section on request handling from wfl-by-example.md
echo "=== Request Handling Section from wfl-by-example.md ==="
sed -n '750,900p' ./Docs/guides/wfl-by-example.md

# Also search for any documentation on accessing headers specifically
echo -e "\n=== Searching for 'headers' with access patterns ==="
grep -n "headers" ./Docs/guides/wfl-by-example.md | head -20

# Check if there's a language reference or specification
echo -e "\n=== Looking for language reference files ==="
find ./Docs -name "*spec*" -o -name "*reference*" -type f 2>/dev/null

Repository: WebFirstLanguage/wfl

Length of output: 4756


🏁 Script executed:

# Check the WFL specification for dictionary/map access syntax
echo "=== WFL Specification (looking for map/dictionary access) ==="
grep -n "at\|dictionary\|map\|access\|\[" ./Docs/wfldocs/WFL-spec.md | head -100

# Search for "headers" in the specification
echo -e "\n=== Searching for headers in WFL spec ==="
grep -n "headers" ./Docs/wfldocs/WFL-spec.md | head -20

# Check web server specification
echo -e "\n=== Checking web server spec ==="
ls -la ./Docs/wflspecs/ | grep -i web
head -200 ./Docs/wflspecs/SPEC-web-server.md 2>/dev/null | head -100

Repository: WebFirstLanguage/wfl

Length of output: 31705


🏁 Script executed:

# Search for headers access examples in test programs
echo "=== Searching for headers access in test programs ==="
find ./TestPrograms -name "*.wfl" -type f | xargs grep -l "headers" 2>/dev/null | head -5

# Check any web server test files
echo -e "\n=== Web server test files ==="
find . -path ./node_modules -prune -o -name "*web*server*test*" -type f -print 2>/dev/null | head -10

# Search for dictionary/map key access patterns with "of"
echo -e "\n=== Searching for 'of' with dictionary access ==="
grep -n '\s of ' ./Docs/guides/wfl-by-example.md | head -30

# Look for any "index" or "key" access patterns
echo -e "\n=== Searching for map/dictionary access documentation ==="
grep -n "dictionary\|map\|key.*access\|headers\[" ./Docs/wfldocs/WFL-spec.md

Repository: WebFirstLanguage/wfl

Length of output: 6877


🏁 Script executed:

# Read the comprehensive web server demo to see headers usage
echo "=== Comprehensive Web Server Demo (headers access) ==="
cat ./TestPrograms/comprehensive_web_server_demo.wfl | head -200

# Search for the specific headers access pattern
echo -e "\n=== Searching for headers access in demo ==="
grep -n "headers" ./TestPrograms/comprehensive_web_server_demo.wfl -C3

# Check the web server request/response test
echo -e "\n=== Checking web_server_request_response_test.wfl ==="
grep -n "headers" ./TestPrograms/web_server_request_response_test.wfl -C3

Repository: WebFirstLanguage/wfl

Length of output: 6712


🏁 Script executed:

# Check the web server spec for headers structure
echo "=== Web Server Spec (headers structure) ==="
grep -n "headers" ./Docs/wflspecs/SPEC-web-server.md -A5 -B5

# Look for examples of map/dictionary key access in test files
echo -e "\n=== Searching for map access patterns in tests ==="
grep -n "get.*from\|map\|dictionary" ./TestPrograms/*.wfl | head -30

# Check if there are more examples of headers access
echo -e "\n=== Searching for all headers access patterns ==="
grep -rn "headers" ./TestPrograms/ --include="*.wfl" | head -20

# Look at the comprehensive demo more to find header value access
echo -e "\n=== Searching for user-agent or header field access ==="
grep -rn "user-agent\|User-Agent\|header.*\[" --include="*.wfl" .

Repository: WebFirstLanguage/wfl

Length of output: 4706


🏁 Script executed:

# Read the header_access_test.wfl file
echo "=== Header Access Test File ==="
cat ./TestPrograms/header_access_test.wfl

Repository: WebFirstLanguage/wfl

Length of output: 1594


🏁 Script executed:

# Check how the request variables are used in the by-example guide
echo "=== Checking request variable usage in by-example ==="
sed -n '750,820p' ./Docs/guides/wfl-by-example.md

# Check the comprehensive demo for how it extracts method, path, etc
echo -e "\n=== How variables are used in comprehensive demo ==="
sed -n '200,220p' ./TestPrograms/comprehensive_web_server_demo.wfl

Repository: WebFirstLanguage/wfl

Length of output: 3386


Fix HTTP header access syntax on line 49.

The expression (headers at "user-agent" or "Unknown") uses incorrect WFL syntax. The correct syntax for accessing HTTP headers is header "KEY" of REQUEST_OBJECT. Change line 49 to:

display "  User Agent: " with (header "user-agent" of req or "Unknown")

The keyword is header (singular), not headers, and the accessor is of, not at. If the headers variable is needed elsewhere, extract it separately: store request_headers as headers of req, then access individual headers using the same header "KEY" of request_headers pattern.

🤖 Prompt for AI Agents
In @Docs/examples/web-servers/04-advanced-comprehensive.wfl around lines 40 -
50, The WFL header access on the display of User Agent is using incorrect
syntax; replace the expression using `headers`/`at` with the singular `header`
accessor applied to the request object `req` and the `of` operator (e.g., use
header "user-agent" of req or "Unknown"); alternatively, if you prefer a
temporary headers variable, first `store request_headers as headers of req` and
then use `header "user-agent" of request_headers or "Unknown"` when building the
display string.

// Route handling with different response types
check if path is equal to "/":
// Serve a dynamic HTML home page
store current_time as current time
store home_html as "<!DOCTYPE html>
<html>
<head>
<title>WFL Advanced Web Server</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.header { color: #007acc; border-bottom: 2px solid #007acc; padding-bottom: 10px; }
.stats { background: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0; }
.endpoint { background: #f5f5f5; padding: 10px; margin: 5px 0; border-left: 4px solid #007acc; }
.method { font-weight: bold; color: #007acc; }
</style>
</head>
<body>
<h1 class=\"header\">WFL Advanced Web Server Demo</h1>
<p>This is an advanced web server built with WebFirst Language!</p>

<div class=\"stats\">
<h3>📊 Server Statistics</h3>
<p><strong>Requests served:</strong> " with request_count with "</p>
<p><strong>Server time:</strong> " with current_time with "</p>
<p><strong>Your IP:</strong> " with client_ip with "</p>
</div>

<h3>🌐 Available API Endpoints</h3>
<div class=\"endpoint\">
<span class=\"method\">GET</span>
<a href=\"/api/status\">/api/status</a> - Server status information
</div>
<div class=\"endpoint\">
<span class=\"method\">GET</span>
<a href=\"/api/time\">/api/time</a> - Current server time
</div>

<h3>✨ WFL Features Demonstrated</h3>
<ul>
<li>Natural language web server syntax</li>
<li>Dynamic HTML generation with variables</li>
<li>JSON API endpoints</li>
<li>Request statistics and logging</li>
<li>HTTP headers access</li>
<li>Multiple content types</li>
</ul>
</body>
</html>"
respond to req with home_html and content_type "text/html"
display "✓ Served dynamic HTML home page"

check if path is equal to "/api/status":
// Serve JSON status information
store uptime_ms as (current time in milliseconds) minus server_start_time
store uptime_seconds as uptime_ms divided by 1000

store status_json as "{
\"server\": \"WFL Advanced Web Server\",
\"status\": \"running\",
\"version\": \"1.0\",
\"requests_served\": " with request_count with ",
\"uptime_seconds\": " with round of uptime_seconds with ",
\"current_time\": \"" with current time with "\",
\"client_ip\": \"" with client_ip with "\",
\"method\": \"" with method with "\"
}"
respond to req with status_json and content_type "application/json"
display "✓ Served JSON status API"

check if path is equal to "/api/time":
// Serve current time as JSON
store time_json as "{
\"current_time\": \"" with current time with "\",
\"timestamp_ms\": " with (current time in milliseconds) with ",
\"timezone\": \"Server Local Time\",
\"request_number\": " with request_count with "
}"
respond to req with time_json and content_type "application/json"
display "✓ Served JSON time API"

otherwise:
// Handle 404 errors with JSON response
store error_json as "{
\"error\": \"Not Found\",
\"message\": \"The requested endpoint '" with path with "' was not found.\",
\"status_code\": 404,
\"available_endpoints\": [
\"/\",
\"/api/status\",
\"/api/time\"
]
}"
respond to req with error_json and status 404 and content_type "application/json"
display "❌ 404 Not Found: " with path
end check

display ""
display "Request processing complete!"
display "=== Advanced Web Server Example Complete ==="
Loading