Skip to content

Commit fbb08d8

Browse files
committed
initial
0 parents  commit fbb08d8

File tree

11 files changed

+813
-0
lines changed

11 files changed

+813
-0
lines changed

.dockerignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
node_modules
2+
Dockerfile*
3+
docker-compose*
4+
.dockerignore
5+
.git
6+
.gitignore
7+
README.md
8+
LICENSE
9+
.vscode
10+
Makefile
11+
helm-charts
12+
.env
13+
.editorconfig
14+
.idea
15+
coverage*

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# deps
2+
node_modules/

Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
FROM oven/bun:alpine AS build
2+
3+
WORKDIR /app
4+
5+
COPY bun.lock package.json ./
6+
7+
RUN bun install --frozen-lockfile --production --verbose
8+
9+
COPY . .
10+
11+
RUN bun build --target bun --compile --minify --sourcemap ./src/index.ts --outfile resp-proxy
12+
13+
FROM oven/bun:alpine AS runner
14+
15+
# Required
16+
ENV LISTEN_PORT="6379"
17+
ENV TARGET_HOST=""
18+
ENV TARGET_PORT=""
19+
20+
# Optional
21+
ENV LISTEN_HOST="127.0.0.1"
22+
ENV TIMEOUT=""
23+
ENV ENABLE_LOGGING="false"
24+
ENV API_PORT="3000"
25+
26+
#Default proxy port
27+
EXPOSE 6379
28+
#Default api port
29+
EXPOSE 3000
30+
31+
WORKDIR /app
32+
33+
COPY --from=build /app/resp-proxy .
34+
35+
ENTRYPOINT ["./resp-proxy"]

README.md

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# Redis RESP Proxy
2+
3+
A Redis protocol proxy with HTTP API for response injection.
4+
5+
## Features
6+
7+
- **Redis Transparent Protocol Proxy**: Forwards Redis connections from clients to target Redis servers
8+
- **HTTP API**: RESTful API for managing connections and sending commands to clients
9+
- **Connection Management**: Track active connections, view statistics, and close connections
10+
- **Data Encoding Support**: Send data in base64 or raw binary format
11+
- **Docker Support**: Containerized deployment with environment variable configuration
12+
- **Real-time Stats**: Monitor active connections and proxy statistics
13+
14+
## Quick Start
15+
16+
### Prerequisites
17+
- Docker or [Bun](https://bun.sh/) runtime
18+
- Running Redis server (target)
19+
20+
### Basic Usage
21+
22+
#### Docker (Recommended)
23+
24+
The easiest way to get started is with Docker :
25+
26+
27+
```bash
28+
# Build the docker image first
29+
docker build -t resp-proxy .
30+
```
31+
32+
33+
34+
```bash
35+
# Run with Docker - connects to Redis on host
36+
docker run -d \
37+
-p 6379:6379 \ # the proxy will listen for incoming connections on this port
38+
-p 3000:3000 \ # the rest api will listen for http requests on this port
39+
-e TARGET_HOST=host.docker.internal \ #<-- redis server host ( the proxy target )
40+
-e TARGET_PORT=6380 \ # redis server port
41+
-e LISTEN_PORT=6379 \ # proxy listen port
42+
-e API_PORT = 3000 \ # rest api port
43+
resp-proxy
44+
```
45+
46+
### Local Development
47+
48+
```bash
49+
# Install dependencies
50+
bun install
51+
52+
# Start the proxy with CLI arguments
53+
bun run proxy --listenPort=6379 --targetHost=localhost --targetPort=6380
54+
55+
# Or use the dev mode with hot reload
56+
bun run dev --listenPort=6379 --targetHost=localhost --targetPort=6380
57+
```
58+
59+
#### Environment Variables
60+
You can use env variables instead of cli arguments.
61+
62+
```bash
63+
# Set required environment variables
64+
export LISTEN_PORT=6379
65+
export TARGET_HOST=localhost
66+
export TARGET_PORT=6380
67+
68+
# Optional variables
69+
export LISTEN_HOST=127.0.0.1
70+
export TIMEOUT=30000
71+
export ENABLE_LOGGING=true
72+
export API_PORT=3000
73+
74+
# Start the proxy
75+
bun run proxy
76+
```
77+
78+
## Configuration
79+
80+
### Required Parameters
81+
82+
| Parameter | CLI Flag | Environment Variable | Description |
83+
|-----------|----------|---------------------|-------------|
84+
| Target Host | `--targetHost` | `TARGET_HOST` | Redis server hostname/IP |
85+
| Target Port | `--targetPort` | `TARGET_PORT` | Redis server port |
86+
87+
### Optional Parameters
88+
89+
| Parameter | CLI Flag | Environment Variable | Default | Description |
90+
|-----------|----------|---------------------|---------|-------------|
91+
| Listen Port | `--listenPort` | `LISTEN_PORT` | `6379` | Port for Redis clients to connect to |
92+
| Listen Host | `--listenHost` | `LISTEN_HOST` | `127.0.0.1` | Host interface to bind to |
93+
| Timeout | `--timeout` | `TIMEOUT` | - | Connection timeout (ms) |
94+
| Enable Logging | `--enableLogging` | `ENABLE_LOGGING` | `false` | Verbose logging |
95+
| API Port | `--apiPort` | `API_PORT` | `3000` | HTTP API port |
96+
97+
## HTTP API Reference
98+
99+
The proxy provides a REST API for managing connections and sending commands.
100+
101+
102+
### Endpoints
103+
104+
105+
#### Get Statistics
106+
```http
107+
GET /stats
108+
```
109+
Returns detailed proxy statistics including active connections, total connections, and connection details.
110+
111+
**Response:**
112+
```json
113+
{
114+
"activeConnections": 2,
115+
"totalConnections": 5,
116+
"connections": [
117+
{
118+
"id": "conn_123",
119+
"clientAddress": "127.0.0.1:54321",
120+
"connectedAt": "2024-01-01T10:00:00Z"
121+
}
122+
]
123+
}
124+
```
125+
126+
#### Get Active Connections
127+
```http
128+
GET /connections
129+
```
130+
Returns list of active connection IDs.
131+
132+
**Response:**
133+
```json
134+
{
135+
"connectionIds": ["conn_123", "conn_456"]
136+
}
137+
```
138+
139+
#### Send Data to Specific Client
140+
```http
141+
POST /send-to-client/{connectionId}?encoding={base64|raw}
142+
```
143+
Send Redis protocol data to a specific client connection.
144+
145+
**Parameters:**
146+
- `connectionId` (path): Target connection ID
147+
- `encoding` (query): Data encoding format (`base64` or `raw`, default: `base64`)
148+
149+
**Body:** Raw data or base64-encoded data
150+
151+
**Example:**
152+
```bash
153+
# Send PING command (base64 encoded)
154+
curl -X POST "http://localhost:3000/send-to-client/conn_123?encoding=base64" \
155+
-d "KjENCiQ0DQpQSU5HDQo="
156+
157+
# Send raw binary data
158+
curl -X POST "http://localhost:3000/send-to-client/conn_123?encoding=raw" \
159+
--data-binary "*1\r\n$4\r\nPING\r\n"
160+
```
161+
162+
**Response:**
163+
```json
164+
{
165+
"success": true,
166+
"connectionId": "conn_123"
167+
}
168+
```
169+
170+
#### Send Data to Multiple Clients
171+
```http
172+
POST /send-to-clients?connectionIds={id1,id2}&encoding={base64|raw}
173+
```
174+
Send data to multiple specific client connections.
175+
176+
**Parameters:**
177+
- `connectionIds` (query): Comma-separated list of connection IDs
178+
- `encoding` (query): Data encoding format (`base64` or `raw`, default: `base64`)
179+
180+
**Example:**
181+
```bash
182+
curl -X POST "http://localhost:3000/send-to-clients?connectionIds=conn_123,conn_456&encoding=base64" \
183+
-d "KjENCiQ0DQpQSU5HDQo="
184+
```
185+
186+
#### Send Data to All Clients
187+
```http
188+
POST /send-to-all-clients?encoding={base64|raw}
189+
```
190+
Broadcast data to all active client connections.
191+
192+
**Example:**
193+
```bash
194+
curl -X POST "http://localhost:3000/send-to-all-clients?encoding=base64" \
195+
-d "KjENCiQ0DQpQSU5HDQo="
196+
```
197+
198+
#### Close Connection
199+
```http
200+
DELETE /connections/{connectionId}
201+
```
202+
Forcefully close a specific client connection.
203+
204+
**Response:**
205+
```json
206+
{
207+
"success": true,
208+
"connectionId": "conn_123"
209+
}
210+
```
211+
212+
## Use Cases
213+
214+
### Testing Redis Applications
215+
Intercept and inspect Redis commands during development and testing.
216+
217+
### Response Injection
218+
Send custom Redis responses to specific clients for testing scenarios.
219+
220+
### Protocol Analysis
221+
Analyze Redis protocol communication patterns.
222+
223+
## Development
224+
225+
### Running Tests
226+
227+
```bash
228+
bun test
229+
```
230+
231+
### Development Mode
232+
233+
```bash
234+
bun run dev --targetHost=localhost --targetPort=6380
235+
```

bun.lock

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"lockfileVersion": 1,
3+
"workspaces": {
4+
"": {
5+
"name": "resp-proxy",
6+
"dependencies": {
7+
"@hono/zod-validator": "^0.7.2",
8+
"hono": "^4.8.5",
9+
"redis-monorepo": "github:redis/node-redis",
10+
"zod": "^4.0.8",
11+
},
12+
"devDependencies": {
13+
"@types/bun": "latest",
14+
},
15+
},
16+
},
17+
"packages": {
18+
"@hono/zod-validator": ["@hono/[email protected]", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-ub5eL/NeZ4eLZawu78JpW/J+dugDAYhwqUIdp9KYScI6PZECij4Hx4UsrthlEUutqDDhPwRI0MscUfNkvn/mqQ=="],
19+
20+
"@types/bun": ["@types/[email protected]", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="],
21+
22+
"@types/node": ["@types/[email protected]", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
23+
24+
"@types/react": ["@types/[email protected]", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
25+
26+
"bun-types": ["[email protected]", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="],
27+
28+
"csstype": ["[email protected]", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
29+
30+
"hono": ["[email protected]", "", {}, "sha512-Up2cQbtNz1s111qpnnECdTGqSIUIhZJMLikdKkshebQSEBcoUKq6XJayLGqSZWidiH0zfHRCJqFu062Mz5UuRA=="],
31+
32+
"redis-monorepo": ["redis-monorepo@github:redis/node-redis#e96db0d", {}, "redis-node-redis-e96db0d"],
33+
34+
"undici-types": ["[email protected]", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
35+
36+
"zod": ["[email protected]", "", {}, "sha512-+MSh9cZU9r3QKlHqrgHMTSr3QwMGv4PLfR0M4N/sYWV5/x67HgXEhIGObdBkpnX8G78pTgWnIrBL2lZcNJOtfg=="],
37+
}
38+
}

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "resp-proxy",
3+
"scripts": {
4+
"proxy": "bun run src/index.ts",
5+
"dev": "bun run --hot src/index.ts",
6+
"test": "bun test **/*.test.ts"
7+
},
8+
"dependencies": {
9+
"@hono/zod-validator": "^0.7.2",
10+
"hono": "^4.8.5",
11+
"redis-monorepo": "github:redis/node-redis",
12+
"zod": "^4.0.8"
13+
},
14+
"devDependencies": {
15+
"@types/bun": "latest"
16+
}
17+
}

0 commit comments

Comments
 (0)