HTTP API Reference

This reference documents Rusty Beam's HTTP API, including standard file operations and the unique CSS selector-based manipulation features.

Table of Contents

API Overview

Rusty Beam provides a RESTful HTTP API with two main modes of operation:

  1. Standard Mode: Traditional file server operations (GET, PUT, POST, DELETE)
  2. Selector Mode: HTML manipulation using CSS selectors via the Range header
Design Philosophy: Rusty Beam intentionally repurposes the HTTP Range header for CSS selector operations. While unconventional, this enables powerful HTML manipulation through standard HTTP methods.

Standard File Operations

GET - Retrieve Files

GET /{path}

Retrieves a file or directory listing.

Request
Response
Examples
# 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

PUT - Upload/Replace Files

PUT /{path}

Creates or completely replaces a file.

Request
Response
Examples
# 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

POST - Append to Files

POST /{path}

Appends content to an existing file or creates a new file in a directory.

Request
Response
Examples
# 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/

DELETE - Remove Files

DELETE /{path}

Deletes a file or empty directory.

Request
Response
Examples
# Delete a file
curl -X DELETE http://localhost:3000/temp.txt

# Delete empty directory
curl -X DELETE http://localhost:3000/old-files/

OPTIONS - Check Allowed Methods

OPTIONS /{path}

Returns allowed HTTP methods for a resource.

Response
Example
curl -X OPTIONS -I http://localhost:3000/index.html

CSS Selector Operations

CSS selector operations use the Range header with the format: Range: selector={css-selector}

Requirements:

GET + Selector - Extract Elements

GET /{path} + Range: selector={selector}

Extracts HTML elements matching the CSS selector.

Request Headers
Response
Examples
# 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

PUT + Selector - Replace Elements

PUT /{path} + Range: selector={selector}

Replaces all elements matching the selector with new content.

Request
Response
Examples
# 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

POST + Selector - Append to Elements

POST /{path} + Range: selector={selector}

Appends content to elements matching the selector.

Request
Response
Examples
# 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

DELETE + Selector - Remove Elements

DELETE /{path} + Range: selector={selector}

Removes all elements matching the selector.

Request Headers
Response
Examples
# 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

Request Headers

Standard Headers

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

Custom Headers

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

Response Formats

Content Types

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
.pdf application/pdf

Response Headers

Common response headers include:

Status Codes

Success Codes (2xx)

Code 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)

Client Error Codes (4xx)

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

Server Error Codes (5xx)

Code Meaning Description
500 Internal Server Error Server error Unexpected server error
503 Service Unavailable Service down Server overloaded/maintenance

Examples

Building a Dynamic Page

# 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>

Working with Authentication

# 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

Batch Operations

#!/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

Plugin-Specific APIs

Some plugins add additional API endpoints or modify behavior:

WebSocket Plugin

# Connect to WebSocket
wscat -c ws://localhost:3000/ws

# The plugin broadcasts all file changes to connected clients

Health Check Plugin

# Check server health
curl http://localhost:3000/health

# Response:
{
  "status": "healthy",
  "uptime": 3600,
  "version": "0.1.0"
}

Metrics Plugin

# 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

Error Handling

Error Response Format

Errors may include a body with details:

{
  "error": "Invalid CSS selector",
  "details": "Unexpected token '}' at position 15",
  "code": "INVALID_SELECTOR"
}

Common Error Scenarios

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

Best Practices for Error Handling

API Clients

JavaScript/Fetch Example

// 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'
    );
}

Python Example

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>'
)

See Also