A Redis protocol proxy with HTTP API for response injection.
Transparently proxy Redis connections while injecting custom RESP responses via REST API.
+-------------+ RESP +-------------+ RESP +-------------+
| Client App |<----------->| RESP Proxy |<----------->| Redis Server|
+-------------+ +-------------+ +-------------+
^
|
HTTP REST API
(inject responses)
# Start proxy container ( the rest api will be running port 3000 by default)
docker run -d \
-p 6379:6379 -p 3000:3000 \
-e TARGET_HOST=your-redis-host \
-e TARGET_PORT=6380 \
redislabs/client-resp-proxy
RESP3 Push notification: >4\r\n$6\r\nMOVING\r\n:1\r\n:2\r\n$6\r\nhost:3\r\n
cURL Example:
curl -X POST "http://localhost:3000/send-to-all-clients?encoding=raw" \
--data-binary ">4\r\n\$6\r\nMOVING\r\n:1\r\n:2\r\n\$6\r\nhost:3\r\n"
TypeScript Example:
const response = await fetch('http://localhost:3000/send-to-all-clients?encoding=raw', {
method: 'POST',
body: '>4\r\n$6\r\nMOVING\r\n:1\r\n:2\r\n$6\r\nhost:3\r\n'
});
const result = await response.json();
console.log(result.success ? 'Injected' : 'Failed');
Go Example:
package main
import (
"io"
"net/http"
"strings"
)
func main() {
payload := strings.NewReader(">4\r\n$6\r\nMOVING\r\n:1\r\n:2\r\n$6\r\nhost:3\r\n")
resp, _ := http.Post("http://localhost:3000/send-to-all-clients?encoding=raw", "", payload)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if strings.Contains(string(body), `"success":true`) {
println("Injected")
}
}
Java Example:
import java.net.http.*;
import java.net.URI;
public class RespProxyClient {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:3000/send-to-all-clients?encoding=raw"))
.POST(HttpRequest.BodyPublishers.ofString(
">4\r\n$6\r\nMOVING\r\n:1\r\n:2\r\n$6\r\nhost:3\r\n"))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.body().contains("\"success\":true")) {
System.out.println("Injected");
}
}
}
Python Example:
import json
import urllib.request
data = b">4\r\n$6\r\nMOVING\r\n:1\r\n:2\r\n$6\r\nhost:3\r\n"
req = urllib.request.Request("http://localhost:3000/send-to-all-clients?encoding=raw", data)
with urllib.request.urlopen(req) as response:
result = json.loads(response.read())
print("Injected" if result["success"] else "Failed")
Key Endpoints: POST /send-to-client/{id}
, POST /send-to-all-clients
, GET /connections
, GET /stats
- Redis Transparent Protocol Proxy: Forwards Redis connections from clients to target Redis servers
- HTTP API: RESTful API for managing connections and sending arbitrary responses to clients
- Connection Management: Track active connections, view statistics, and close connections
- Data Encoding Support: Send data in base64 or raw binary format
- Docker Support: Containerized deployment with environment variable configuration
- Real-time Stats: Monitor active connections and proxy statistics
- Docker or Bun runtime
- Running Redis server (target)
Use the official docker image or
# Build the docker image first
docker build -t resp-proxy .
# Run with Docker - connects to Redis on host
docker run -d \
-p 6379:6379 \ # the proxy will listen for incoming connections on this port
-p 3000:3000 \ # the rest api will listen for http requests on this port
-e TARGET_HOST=host.docker.internal \ #<-- redis server host ( the proxy target )
-e TARGET_PORT=6380 \ # redis server port
-e LISTEN_PORT=6379 \ # proxy listen port
-e API_PORT = 3000 \ # rest api port
resp-proxy
# Install dependencies
bun install
# Start the proxy with CLI arguments
bun run proxy --listenPort=6379 --targetHost=localhost --targetPort=6380
# Or use the dev mode with hot reload
bun run dev --listenPort=6379 --targetHost=localhost --targetPort=6380
You can use env variables instead of cli arguments.
# Set required environment variables
export LISTEN_PORT=6379
export TARGET_HOST=localhost
export TARGET_PORT=6380
# Optional variables
export LISTEN_HOST=127.0.0.1
export TIMEOUT=30000
export ENABLE_LOGGING=true
export API_PORT=3000
# Start the proxy
bun run proxy
Parameter | CLI Flag | Environment Variable | Description |
---|---|---|---|
Target Host | --targetHost |
TARGET_HOST |
Redis server hostname/IP |
Target Port | --targetPort |
TARGET_PORT |
Redis server port |
Parameter | CLI Flag | Environment Variable | Default | Description |
---|---|---|---|---|
Listen Port | --listenPort |
LISTEN_PORT |
6379 |
Port for Redis clients to connect to |
Listen Host | --listenHost |
LISTEN_HOST |
127.0.0.1 |
Host interface to bind to |
Timeout | --timeout |
TIMEOUT |
- | Connection timeout (ms) |
Enable Logging | --enableLogging |
ENABLE_LOGGING |
false |
Verbose logging |
API Port | --apiPort |
API_PORT |
3000 |
HTTP API port |
The proxy provides a REST API for managing connections and sending arbitrary responses.
GET /stats
Returns detailed proxy statistics including active connections, total connections, and connection details.
Response:
{
"activeConnections": 2,
"totalConnections": 5,
"connections": [
{
"id": "conn_123",
"clientAddress": "127.0.0.1:54321",
"connectedAt": "2024-01-01T10:00:00Z"
}
]
}
GET /connections
Returns list of active connection IDs.
Response:
{
"connectionIds": ["conn_123", "conn_456"]
}
POST /send-to-client/{connectionId}?encoding={base64|raw}
Send Redis protocol data to a specific client connection.
Parameters:
connectionId
(path): Target connection IDencoding
(query): Data encoding format (base64
orraw
, default:base64
)
Body: Raw data or base64-encoded data
Example:
# Send PING command (base64 encoded)
curl -X POST "http://localhost:3000/send-to-client/conn_123?encoding=base64" \
-d "KjENCiQ0DQpQSU5HDQo="
# Send raw binary data
curl -X POST "http://localhost:3000/send-to-client/conn_123?encoding=raw" \
--data-binary "*1\r\n$4\r\nPING\r\n"
Response:
{
"success": true,
"connectionId": "conn_123"
}
POST /send-to-clients?connectionIds={id1,id2}&encoding={base64|raw}
Send data to multiple specific client connections.
Parameters:
connectionIds
(query): Comma-separated list of connection IDsencoding
(query): Data encoding format (base64
orraw
, default:base64
)
Example:
curl -X POST "http://localhost:3000/send-to-clients?connectionIds=conn_123,conn_456&encoding=base64" \
-d "KjENCiQ0DQpQSU5HDQo="
POST /send-to-all-clients?encoding={base64|raw}
Broadcast data to all active client connections.
Example:
curl -X POST "http://localhost:3000/send-to-all-clients?encoding=base64" \
-d "KjENCiQ0DQpQSU5HDQo="
DELETE /connections/{connectionId}
Forcefully close a specific client connection.
Response:
{
"success": true,
"connectionId": "conn_123"
}
Intercept and inspect Redis commands during development and testing.
Send custom Redis responses to specific clients for testing scenarios.
Analyze Redis protocol communication patterns.