-
Notifications
You must be signed in to change notification settings - Fork 0
Add comprehensive web server documentation (Issue #213) #220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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!" |
| 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 ===" |
| 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 | ||
|
|
||
| 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 ===" | ||
| 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 | ||||||
|
||||||
| store server_start_time as current time in milliseconds | |
| store server_start_time as current time |
Copilot
AI
Jan 6, 2026
There was a problem hiding this comment.
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.
| display " User Agent: " with (headers at "user-agent" or "Unknown") | |
| display " User Agent: " with (headers at "user-agent") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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 -10Repository: 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 fRepository: 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 -30Repository: 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 -30Repository: 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/nullRepository: 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 -100Repository: 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.mdRepository: 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 -C3Repository: 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.wflRepository: 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.wflRepository: 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.
There was a problem hiding this comment.
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
catchblock 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.