The PrintMaster system now supports proxying HTTP requests through the WebSocket connection between agents and the server. This allows you to access:
- Agent web UIs from anywhere (even behind NAT/firewalls)
- Device web UIs (printer admin pages) through the agent's network connection
Browser → Server → WebSocket → Agent → Target (Agent UI or Device)
← ← ← ←
- User clicks "Open UI" button in the server web interface
- Browser makes HTTP request to server proxy endpoint
- Server converts HTTP request to WebSocket message (
proxy_request) - Server sends message through WebSocket to connected agent
- Agent receives proxy request and makes local HTTP request to target
- Agent sends HTTP response back through WebSocket (
proxy_response) - Server forwards response to browser
{
"type": "proxy_request",
"data": {
"request_id": "unique-id",
"url": "http://localhost:8080/",
"method": "GET",
"headers": {
"User-Agent": "...",
"Accept": "..."
},
"body": "base64-encoded-body"
},
"timestamp": "2025-11-07T12:00:00Z"
}{
"type": "proxy_response",
"data": {
"request_id": "unique-id",
"status_code": 200,
"headers": {
"Content-Type": "text/html",
"Content-Length": "1234"
},
"body": "base64-encoded-response-body"
},
"timestamp": "2025-11-07T12:00:01Z"
}GET /api/v1/proxy/agent/{agentID}/{path...}
Proxies HTTP requests to the agent's own web UI (typically running on http://localhost:8080).
Example:
GET /api/v1/proxy/agent/my-agent-id/
GET /api/v1/proxy/agent/my-agent-id/api/devices
GET /api/v1/proxy/device/{serialNumber}/{path...}
Proxies HTTP requests to a device's web UI through its associated agent.
Example:
GET /api/v1/proxy/device/ABC123/
GET /api/v1/proxy/device/ABC123/web/index.html
Each agent card now has an "Open UI" button that:
- Opens the agent's web interface in a new window
- Is disabled if the agent is not connected via WebSocket
- Shows a tooltip explaining why it's disabled
The agent details view includes an "Open Agent UI" button with the same functionality.
Each device card now has an "Open Web UI" button that:
- Opens the device's admin interface in a new window
- Is disabled if the device has no IP or no associated agent
- Requires the agent to be connected via WebSocket
Files Modified:
websocket.go- Added proxy message handling and request/response trackingmain.go- Added proxy endpoint handlers
Key Functions:
handleAgentProxy()- Proxies requests to agent UIshandleDeviceProxy()- Proxies requests to device UIsproxyThroughWebSocket()- Core proxy logicsendProxyRequest()- Sends proxy request via WebSockethandleWSProxyResponse()- Handles proxy responses from agents
Files Modified:
ws_client.go- Added proxy request handling
Key Functions:
handleProxyRequest()- Receives proxy request, makes HTTP call, sends responsesendProxyResponse()- Sends successful HTTP responsesendProxyError()- Sends error response
Files Modified:
app.js- Added proxy buttons and JavaScript functions
Key Functions:
openAgentUI(agentId)- Opens proxied agent UIopenDeviceUI(serialNumber)- Opens proxied device UI
- Authentication: The proxy endpoints currently inherit authentication from the server's session handling
- Agent Validation: Only connected agents can be proxied through
- Request Timeouts: Proxy requests have a 30-second timeout to prevent hanging connections
- Header Filtering: Hop-by-hop headers are filtered to prevent protocol issues
- WebSocket Required: Proxy only works when agent has active WebSocket connection
- Timeout: Long-running requests (>30s) will timeout
- Binary Content: All content is base64-encoded, adding ~33% overhead
- HTTP Only: HTTPS device UIs must be accessed via HTTP from agent's perspective
- No Streaming: Response is buffered entirely before being sent back
Potential improvements for future versions:
- Streaming Support: Stream responses instead of buffering
- WebSocket Upgrade: Support WebSocket connections through the proxy
- Compression: Add gzip compression for text content
- Caching: Cache static assets to reduce proxy traffic
- Port Configuration: Allow agents to specify custom web UI port
- SSL/TLS Support: Support HTTPS connections to devices
- Connection Pooling: Reuse HTTP connections to improve performance
To test the proxy feature:
- Start the server:
./printmaster-server - Start an agent with WebSocket enabled:
./printmaster-agent --config config.toml - Open the server web UI:
http://localhost:8080 - Navigate to Agents tab
- Click "Open UI" on an active agent - should open agent's UI in new window
- Navigate to Devices tab
- Click "Open Web UI" on a device - should open device's admin page
- Agent UI: Check that agent status is "active" (WebSocket connected)
- Device UI: Check that device has an IP address and associated agent
- Verify agent has
use_websocket = truein config - Check server logs for WebSocket connection status
- Verify network connectivity between agent and server
- Device may be offline or unreachable from agent
- Target service may be slow to respond
- Check agent logs for HTTP request errors
- Check browser console for errors
- Verify target service is running (agent UI or device web server)
- Check agent logs for proxy request handling
- Latency: Adds ~50-100ms overhead compared to direct access
- Throughput: Limited by WebSocket connection (~10-20 MB/s typical)
- Concurrent Requests: Multiple requests can be in-flight simultaneously
- Memory: Buffers entire response in memory (both agent and server)
For large file downloads or high-throughput needs, consider direct access when possible.