This reference documents Rusty Beam's HTTP API, including standard file operations and the unique CSS selector-based manipulation features.
Rusty Beam provides a RESTful HTTP API with two main modes of operation:
Retrieves a file or directory listing.
# Get a specific file
curl http://localhost:3000/index.html
# Get directory index
curl http://localhost:3000/docs/
# Get with custom headers
curl -H "Accept: text/html" http://localhost:3000/page.html
Creates or completely replaces a file.
# Upload HTML file
curl -X PUT -H "Content-Type: text/html" \
-d '<h1>Hello World</h1>' \
http://localhost:3000/hello.html
# Upload from file
curl -X PUT -H "Content-Type: application/json" \
--data-binary @data.json \
http://localhost:3000/api/data.json
Appends content to an existing file or creates a new file in a directory.
# Append to log file
curl -X POST -d "New log entry\n" \
http://localhost:3000/logs/app.log
# Create file in directory
curl -X POST -H "X-Filename: report.txt" \
-d "Report content" \
http://localhost:3000/reports/
Deletes a file or empty directory.
# Delete a file
curl -X DELETE http://localhost:3000/temp.txt
# Delete empty directory
curl -X DELETE http://localhost:3000/old-files/
Returns allowed HTTP methods for a resource.
Allow: GET, PUT, POST, DELETE, OPTIONS
curl -X OPTIONS -I http://localhost:3000/index.html
CSS selector operations use the Range
header with the format: Range: selector={css-selector}
Extracts HTML elements matching the CSS selector.
Range: selector={css-selector}
Content-Range: selector {selector}
# Extract by ID
curl -H "Range: selector=#header" http://localhost:3000/page.html
# Extract by class
curl -H "Range: selector=.important" http://localhost:3000/page.html
# Complex selector
curl -H "Range: selector=div.content > p:first-child" \
http://localhost:3000/page.html
# Multiple elements
curl -H "Range: selector=ul li" http://localhost:3000/page.html
Replaces all elements matching the selector with new content.
Range: selector={css-selector}
Content-Range: selector {selector}
# Replace single element
curl -X PUT -H "Range: selector=#title" \
-d '<h1 id="title">New Title</h1>' \
http://localhost:3000/page.html
# Replace all paragraphs in a div
curl -X PUT -H "Range: selector=div.content p" \
-d '<p class="updated">Updated content</p>' \
http://localhost:3000/page.html
Appends content to elements matching the selector.
Range: selector={css-selector}
Content-Range: selector {selector}
# Append to body
curl -X POST -H "Range: selector=body" \
-d '<footer>Copyright 2024</footer>' \
http://localhost:3000/page.html
# Add item to list
curl -X POST -H "Range: selector=ul#menu" \
-d '<li><a href="/new">New Item</a></li>' \
http://localhost:3000/page.html
Removes all elements matching the selector.
Range: selector={css-selector}
# Remove element by ID
curl -X DELETE -H "Range: selector=#temp-banner" \
http://localhost:3000/page.html
# Remove all elements with class
curl -X DELETE -H "Range: selector=.deprecated" \
http://localhost:3000/page.html
Header | Description | Example |
---|---|---|
Content-Type |
MIME type of request body | text/html; charset=utf-8 |
Accept |
Preferred response format | text/html, application/json |
Authorization |
Authentication credentials | Basic YWxpY2U6c2VjcmV0 |
Host |
Target virtual host | api.example.com |
Header | Description | Example |
---|---|---|
Range |
CSS selector for HTML operations | selector=#content |
X-Filename |
Filename for POST to directory | report.txt |
X-Request-ID |
Request tracking ID | 123e4567-e89b-12d3 |
Rusty Beam automatically sets appropriate Content-Type headers:
Extension | Content-Type |
---|---|
.html, .htm | text/html; charset=utf-8 |
.json | application/json |
.xml | application/xml |
.txt | text/plain; charset=utf-8 |
.css | text/css |
.js | application/javascript |
.jpg, .jpeg | image/jpeg |
.png | image/png |
.gif | image/gif |
application/pdf |
Common response headers include:
Content-Type
- MIME type of responseContent-Length
- Size in bytesLast-Modified
- File modification timeETag
- Entity tag for cachingServer
- Server identificationDate
- Response timestampCode | Meaning | Used When |
---|---|---|
200 OK | Success | GET success, PUT/POST update |
201 Created | Resource created | PUT/POST new file |
204 No Content | Success, no body | DELETE success |
206 Partial Content | Partial content | Selector operations (GET/PUT/POST) |
Code | Meaning | Common Causes |
---|---|---|
400 Bad Request | Invalid request | Malformed selector, invalid HTML |
401 Unauthorized | Authentication required | Missing/invalid credentials |
403 Forbidden | Access denied | Insufficient permissions |
404 Not Found | Resource not found | File doesn't exist |
405 Method Not Allowed | Invalid method | Method not supported |
409 Conflict | Conflict | Directory not empty |
413 Payload Too Large | Request too large | File exceeds size limit |
429 Too Many Requests | Rate limited | Rate limit exceeded |
Code | Meaning | Description |
---|---|---|
500 Internal Server Error | Server error | Unexpected server error |
503 Service Unavailable | Service down | Server overloaded/maintenance |
# Create initial page
curl -X PUT -H "Content-Type: text/html" -d '
<html>
<head><title>Dynamic Page</title></head>
<body>
<div id="header"><h1>Welcome</h1></div>
<div id="content"><p>Initial content</p></div>
<div id="sidebar"><ul id="menu"></ul></div>
</body>
</html>' http://localhost:3000/dynamic.html
# Update the header (returns 206 with the updated element)
curl -X PUT -H "Range: selector=#header h1" \
-d '<h1>Updated Welcome Message</h1>' \
http://localhost:3000/dynamic.html
# Response: 206 Partial Content
# Body: <h1>Updated Welcome Message</h1>
# Add menu items (returns 206 with the updated menu)
curl -X POST -H "Range: selector=#menu" \
-d '<li><a href="/">Home</a></li>' \
http://localhost:3000/dynamic.html
# Response: 206 Partial Content
# Body: <ul id="menu"><li><a href="/">Home</a></li></ul>
curl -X POST -H "Range: selector=#menu" \
-d '<li><a href="/about">About</a></li>' \
http://localhost:3000/dynamic.html
# Response: 206 Partial Content
# Body: <ul id="menu"><li><a href="/">Home</a></li><li><a href="/about">About</a></li></ul>
# Extract just the menu (returns 206 with matching element)
curl -H "Range: selector=#menu" http://localhost:3000/dynamic.html
# Response: 206 Partial Content
# Body: <ul id="menu"><li><a href="/">Home</a></li><li><a href="/about">About</a></li></ul>
# Without auth (fails)
curl http://localhost:3000/protected/data.json
# 401 Unauthorized
# With basic auth
curl -u username:password http://localhost:3000/protected/data.json
# With Authorization header
curl -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
http://localhost:3000/protected/data.json
#!/bin/bash
# Update multiple elements in a page
BASE_URL="http://localhost:3000/dashboard.html"
# Update status
curl -X PUT -H "Range: selector=#status" \
-d '<div id="status" class="online">Online</div>' \
$BASE_URL
# Update timestamp
curl -X PUT -H "Range: selector=#timestamp" \
-d "<span id=\"timestamp\">$(date)</span>" \
$BASE_URL
# Add log entry
curl -X POST -H "Range: selector=#log" \
-d "<li>$(date): System check completed</li>" \
$BASE_URL
Some plugins add additional API endpoints or modify behavior:
# Connect to WebSocket
wscat -c ws://localhost:3000/ws
# The plugin broadcasts all file changes to connected clients
# Check server health
curl http://localhost:3000/health
# Response:
{
"status": "healthy",
"uptime": 3600,
"version": "0.1.0"
}
# Get Prometheus metrics
curl http://localhost:3000/metrics
# Response:
# HELP http_requests_total Total HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200"} 1234
Errors may include a body with details:
{
"error": "Invalid CSS selector",
"details": "Unexpected token '}' at position 15",
"code": "INVALID_SELECTOR"
}
Scenario | Status | Response |
---|---|---|
Invalid CSS selector | 400 | Error details in body |
File not found | 404 | Empty or error page |
No selector matches | 204 | Empty body |
Rate limit hit | 429 | Retry-After header |
Server error | 500 | Error page or details |
// Helper function for selector operations
async function selectorOperation(url, method, selector, content) {
const options = {
method: method,
headers: {
'Range': `selector=${selector}`
}
};
if (content) {
options.body = content;
options.headers['Content-Type'] = 'text/html';
}
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// For selector operations with PUT/POST, we get 206 with partial content
// For DELETE, we get 204 with no content
return method === 'DELETE' ? null : response.text();
}
// Usage examples
async function updatePage() {
// Extract content
const menu = await selectorOperation(
'http://localhost:3000/page.html',
'GET',
'#menu'
);
// Update header
await selectorOperation(
'http://localhost:3000/page.html',
'PUT',
'h1',
'<h1>New Title</h1>'
);
// Add footer
await selectorOperation(
'http://localhost:3000/page.html',
'POST',
'body',
'<footer>© 2024</footer>'
);
// Remove ads
await selectorOperation(
'http://localhost:3000/page.html',
'DELETE',
'.advertisement'
);
}
import requests
from requests.auth import HTTPBasicAuth
class RustyBeamClient:
def __init__(self, base_url, auth=None):
self.base_url = base_url
self.auth = auth
self.session = requests.Session()
def selector_get(self, path, selector):
"""Extract elements using CSS selector"""
response = self.session.get(
f"{self.base_url}/{path}",
headers={'Range': f'selector={selector}'},
auth=self.auth
)
response.raise_for_status()
return response.text
def selector_put(self, path, selector, content):
"""Replace elements matching selector"""
response = self.session.put(
f"{self.base_url}/{path}",
headers={'Range': f'selector={selector}'},
data=content,
auth=self.auth
)
response.raise_for_status()
return response.text
def upload_file(self, path, content, content_type='text/html'):
"""Upload a complete file"""
response = self.session.put(
f"{self.base_url}/{path}",
data=content,
headers={'Content-Type': content_type},
auth=self.auth
)
response.raise_for_status()
return response.status_code == 201
# Usage
client = RustyBeamClient(
'http://localhost:3000',
auth=HTTPBasicAuth('user', 'pass')
)
# Extract navigation
nav = client.selector_get('index.html', 'nav')
# Update title
client.selector_put(
'index.html',
'title',
'<title>Updated Site</title>'
)