This document provides a technical deep-dive into how OpenBare works.
OpenBare is a decentralized web proxy network consisting of four main components:
┌─────────────────────────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ (Ultraviolet, SperaxOS Browser, Custom Apps) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ @openbare/client │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ ServerPool │ │ BareFetch │ │ Discovery │ │
│ │ - health │ │ - encode │ │ - registry │ │
│ │ - latency │ │ - decode │ │ - refresh │ │
│ │ - failover │ │ - headers │ │ - cache │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ @openbare/ │ │ @openbare/ │ │ @openbare/ │
│ server │ │ edge │ │ server │
│ (Node.js) │ │ (CF Workers) │ │ (Docker) │
│ │ │ │ │ │
│ Region: US │ │ Region: EU │ │ Region: Asia │
└───────────────┘ └───────────────┘ └───────────────┘
│ │ │
└─────────────────────┼─────────────────────┘
▼
┌───────────────────┐
│ @openbare/registry│
│ - Node discovery │
│ - Health tracking │
│ - Metrics agg. │
└───────────────────┘
OpenBare implements the TompHTTP Bare Server v3 protocol, which is the standard for web proxy servers in the Ultraviolet ecosystem.
1. Client wants to fetch https://google.com
2. Client encodes the request:
- URL: xor_encode("https://google.com") → "encoded_string"
- Headers: JSON.stringify({...}) → base64
3. Client sends to bare server:
GET /bare/v3/ HTTP/1.1
X-Bare-URL: https://google.com
X-Bare-Headers: {"Accept": "text/html", ...}
4. Bare server:
- Parses X-Bare-* headers
- Fetches https://google.com
- Strips X-Frame-Options, CSP headers
- Returns response with X-Bare-* response headers
5. Client decodes and returns to application
Request Headers:
| Header | Description |
|---|---|
X-Bare-URL |
Target URL to fetch |
X-Bare-Headers |
JSON-encoded headers to send |
X-Bare-Forward-Headers |
Headers to forward from client |
X-Bare-Pass-Headers |
Headers to pass through unchanged |
X-Bare-Pass-Status |
Status codes to pass through |
Response Headers:
| Header | Description |
|---|---|
X-Bare-Status |
Original response status code |
X-Bare-Status-Text |
Original status text |
X-Bare-Headers |
JSON-encoded response headers |
The client maintains a pool of servers and implements intelligent failover:
class ServerPool {
servers = [
{ url: 'https://bare1.com', latency: 50, healthy: true },
{ url: 'https://bare2.com', latency: 120, healthy: true },
{ url: 'https://bare3.com', latency: 80, healthy: false },
];
// Get best available server
getBest() {
return this.servers
.filter(s => s.healthy)
.sort((a, b) => a.latency - b.latency)[0];
}
// Fetch with automatic failover
async fetch(url, options) {
for (const server of this.getHealthyServers()) {
try {
return await this.bareFetch(server, url, options);
} catch (err) {
this.markUnhealthy(server);
continue; // Try next server
}
}
throw new Error('All servers failed');
}
}Servers are checked periodically:
async function checkHealth(server) {
const start = Date.now();
try {
const res = await fetch(server.url + '/health', { timeout: 5000 });
server.latency = Date.now() - start;
server.healthy = res.ok;
} catch {
server.healthy = false;
}
}The registry maintains a directory of public nodes:
CREATE TABLE nodes (
id TEXT PRIMARY KEY,
url TEXT UNIQUE NOT NULL,
region TEXT,
owner TEXT,
version TEXT,
registered_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_heartbeat DATETIME,
status TEXT DEFAULT 'unknown',
avg_latency INTEGER,
total_requests INTEGER DEFAULT 0
);
CREATE INDEX idx_nodes_status ON nodes(status);
CREATE INDEX idx_nodes_region ON nodes(region);| Endpoint | Method | Description |
|---|---|---|
/nodes |
GET | List healthy nodes |
/nodes/register |
POST | Register a node |
/nodes/:id |
DELETE | Unregister a node |
/nodes/:id/heartbeat |
POST | Send heartbeat |
// Runs every 30 seconds
async function healthCheckLoop() {
const nodes = await db.getAllNodes();
for (const node of nodes) {
const healthy = await checkNodeHealth(node.url);
if (!healthy) {
node.failureCount++;
if (node.failureCount >= 3) {
await db.markUnhealthy(node.id);
}
} else {
node.failureCount = 0;
await db.markHealthy(node.id);
}
}
}The edge version runs on Cloudflare's global network:
- 300+ locations - Requests served from nearest edge
- <50ms latency - Global average response time
- Auto-scaling - Handles any traffic level
- Free tier - 100K requests/day free
// Cloudflare Worker
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname.startsWith('/bare/')) {
return handleBareRequest(request);
}
return new Response(JSON.stringify({
status: 'ok',
edge_location: request.cf?.colo
}));
}
};- Strips X-Frame-Options headers
- Strips CSP frame-ancestors
- Forwards cookies (same-site context)
- Proxies WebSocket connections
- Store or log request content
- Modify response bodies
- Execute JavaScript
- Track users
const limiter = rateLimit({
windowMs: 60000, // 1 minute
max: 100, // 100 requests per window
keyGenerator: (req) => req.ip
});Each node collects metrics:
const metrics = {
requests: {
total: 0,
successful: 0,
failed: 0,
per_minute: []
},
bytes: {
received: 0,
sent: 0
},
latency: {
average: 0,
p50: 0,
p95: 0,
p99: 0
},
connections: {
active: 0,
peak: 0
}
};OpenBare fully supports WebSocket proxying:
Client Bare Server Target
│ │ │
│ WS Upgrade Request │ │
│ X-Bare-URL: wss://... │ │
│ ─────────────────────────>│ │
│ │ WS Upgrade Request │
│ │ ─────────────────────>│
│ │ │
│ │ WS Upgrade Response │
│ │ <─────────────────────│
│ WS Upgrade Response │ │
│ <─────────────────────────│ │
│ │ │
│ WS Frames (bidirectional) │
│ <═══════════════════════════════════════════════> │
The server maintains connection pools to frequently-accessed origins:
const agent = new https.Agent({
keepAlive: true,
maxSockets: 100,
maxFreeSockets: 10,
timeout: 60000
});Large responses are streamed, not buffered:
async function handleRequest(req, res) {
const upstream = await fetch(targetUrl);
// Stream response body
upstream.body.pipe(res);
}Appropriate caching headers are set:
res.setHeader('Cache-Control', 'no-store'); // Don't cache proxied content
res.setHeader('X-Bare-Cache', 'MISS'); // Cache status indicator