Skip to content

Commit 6f786d6

Browse files
committed
Implemented advanced proxy configuration
1 parent 2c0c73f commit 6f786d6

File tree

3 files changed

+167
-4
lines changed

3 files changed

+167
-4
lines changed

README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ environment:
4242
ALLOW_HASH_CONTENT_PATHS: "true" # Optional: Allow /[40-hex-char]/* paths without auth (for Stremio, etc.)
4343
```
4444
45+
**Proxy Behavior (Advanced):**
46+
```yaml
47+
# These have sensible defaults - only override if needed
48+
PROXY_BUFFERING: "off" # Default: off. Use "on" for caching/rate-limiting support
49+
PROXY_REQUEST_BUFFERING: "off" # Default: off. Use "on" if backend needs full body before processing
50+
PROXY_CONNECT_TIMEOUT: "300s" # Default: 300s. Time to establish backend connection
51+
PROXY_SEND_TIMEOUT: "300s" # Default: 300s. Timeout between write operations to backend
52+
PROXY_READ_TIMEOUT: "300s" # Default: 300s. Timeout between read operations from backend
53+
CLIENT_MAX_BODY_SIZE: "0" # Default: 0 (unlimited). Use "10G" or "100M" to limit uploads
54+
```
55+
4556
## Authentication Modes
4657
4758
The system automatically selects the authentication mode based on which environment variables are configured:
@@ -483,6 +494,73 @@ The `ALLOW_HASH_CONTENT_PATHS` feature is useful for:
483494
- Applications where the content hash acts as an access token
484495
- Stremio and similar streaming applications
485496
497+
### Supported Features
498+
499+
| Feature | Status | Notes |
500+
|---------|--------|-------|
501+
| Standard HTTP/1.1 apps | ✅ | Fully supported |
502+
| WebSocket connections | ✅ | Automatic detection and upgrade |
503+
| Video/audio streaming | ✅ | Buffering disabled by default |
504+
| Large file uploads | ✅ | Unlimited by default |
505+
| Server-Sent Events (SSE) | ✅ | Proper headers configured |
506+
| Long-polling requests | ✅ | 5-minute timeouts |
507+
| REST APIs | ✅ | All methods supported |
508+
509+
### Known Limitations
510+
511+
| Feature | Status | Reason |
512+
|---------|--------|--------|
513+
| gRPC | ❌ | Requires `grpc_pass` directive and HTTP/2 - fundamentally different from HTTP proxying |
514+
| HTTP/2 to backend | ❌ | Uses HTTP/1.1 for backend connections (sufficient for 99% of apps) |
515+
| Headers with underscores | ⚠️ | Ignored by default (nginx default behavior) |
516+
517+
**Note on gRPC:** Applications using gRPC (some CI/CD tools, Kubernetes services) cannot be proxied through NGINX Hash Lock. gRPC requires a completely different nginx configuration using `grpc_pass` instead of `proxy_pass`.
518+
519+
## Proxy Behavior Configuration
520+
521+
NGINX Hash Lock is designed to work with **any application** out of the box. The defaults prioritize compatibility over performance.
522+
523+
### Environment Variables Reference
524+
525+
| Variable | Default | Description |
526+
|----------|---------|-------------|
527+
| `PROXY_BUFFERING` | `off` | Response buffering. `off` = streaming-friendly, `on` = better for caching |
528+
| `PROXY_REQUEST_BUFFERING` | `off` | Request buffering. `off` = large uploads work, `on` = backend gets full body first |
529+
| `PROXY_CONNECT_TIMEOUT` | `300s` | Time allowed to establish connection with backend |
530+
| `PROXY_SEND_TIMEOUT` | `300s` | Timeout between successive write operations to backend |
531+
| `PROXY_READ_TIMEOUT` | `300s` | Timeout between successive read operations from backend |
532+
| `CLIENT_MAX_BODY_SIZE` | `0` | Maximum upload size. `0` = unlimited, or use `10G`, `100M`, etc. |
533+
534+
### When to Override Defaults
535+
536+
**Most apps need no configuration** - the defaults handle:
537+
- Video/audio streaming (Stremio, Jellyfin, Plex)
538+
- Large file uploads (ConvertX, file managers)
539+
- WebSocket connections (terminals, real-time apps)
540+
- Server-Sent Events (SSE)
541+
- Long-polling requests
542+
543+
**Override only if:**
544+
545+
| Scenario | Setting |
546+
|----------|---------|
547+
| Need nginx-level caching | `PROXY_BUFFERING=on` |
548+
| Need nginx rate-limiting | `PROXY_BUFFERING=on` |
549+
| Backend requires full request before processing | `PROXY_REQUEST_BUFFERING=on` |
550+
| Want to limit upload sizes | `CLIENT_MAX_BODY_SIZE=10G` |
551+
| Very long operations (>5 min) | `PROXY_READ_TIMEOUT=3600s` |
552+
553+
### What's Fixed Automatically
554+
555+
These issues are handled without configuration:
556+
557+
| Feature | Implementation |
558+
|---------|----------------|
559+
| WebSocket support | Correct `Connection` header via nginx `map` directive |
560+
| Forwarded headers | `X-Forwarded-Proto`, `X-Forwarded-Host`, `X-Forwarded-Port` |
561+
| SSE support | `X-Accel-Buffering: no` header |
562+
| Backend redirects | Proper redirect rewriting |
563+
486564
## Building & Publishing
487565
488566
The Docker image is automatically built and published to GitHub Container Registry via GitHub Actions on every push to `main`.

entrypoint.sh

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@ sed -i "s/BACKEND_HOST_PLACEHOLDER/$BACKEND_HOST/g" /etc/nginx/nginx.conf
3636
sed -i "s/BACKEND_PORT_PLACEHOLDER/$BACKEND_PORT/g" /etc/nginx/nginx.conf
3737
sed -i "s/LISTEN_PORT_PLACEHOLDER/$LISTEN_PORT/g" /etc/nginx/nginx.conf
3838

39+
# These defaults prioritize compatibility over performance
40+
PROXY_BUFFERING="${PROXY_BUFFERING:-off}"
41+
PROXY_REQUEST_BUFFERING="${PROXY_REQUEST_BUFFERING:-off}"
42+
PROXY_CONNECT_TIMEOUT="${PROXY_CONNECT_TIMEOUT:-300s}"
43+
PROXY_SEND_TIMEOUT="${PROXY_SEND_TIMEOUT:-300s}"
44+
PROXY_READ_TIMEOUT="${PROXY_READ_TIMEOUT:-300s}"
45+
CLIENT_MAX_BODY_SIZE="${CLIENT_MAX_BODY_SIZE:-0}"
46+
47+
echo "========================================="
48+
echo "Proxy Configuration:"
49+
echo " PROXY_BUFFERING: $PROXY_BUFFERING"
50+
echo " PROXY_REQUEST_BUFFERING: $PROXY_REQUEST_BUFFERING"
51+
echo " PROXY_CONNECT_TIMEOUT: $PROXY_CONNECT_TIMEOUT"
52+
echo " PROXY_SEND_TIMEOUT: $PROXY_SEND_TIMEOUT"
53+
echo " PROXY_READ_TIMEOUT: $PROXY_READ_TIMEOUT"
54+
echo " CLIENT_MAX_BODY_SIZE: $CLIENT_MAX_BODY_SIZE"
55+
echo "========================================="
56+
57+
# Replace proxy behavior placeholders
58+
sed -i "s/PROXY_BUFFERING_PLACEHOLDER/$PROXY_BUFFERING/g" /etc/nginx/nginx.conf
59+
sed -i "s/PROXY_REQUEST_BUFFERING_PLACEHOLDER/$PROXY_REQUEST_BUFFERING/g" /etc/nginx/nginx.conf
60+
sed -i "s/PROXY_CONNECT_TIMEOUT_PLACEHOLDER/$PROXY_CONNECT_TIMEOUT/g" /etc/nginx/nginx.conf
61+
sed -i "s/PROXY_SEND_TIMEOUT_PLACEHOLDER/$PROXY_SEND_TIMEOUT/g" /etc/nginx/nginx.conf
62+
sed -i "s/PROXY_READ_TIMEOUT_PLACEHOLDER/$PROXY_READ_TIMEOUT/g" /etc/nginx/nginx.conf
63+
sed -i "s/CLIENT_MAX_BODY_SIZE_PLACEHOLDER/$CLIENT_MAX_BODY_SIZE/g" /etc/nginx/nginx.conf
64+
3965
# Determine authentication mode
4066
AUTH_MODE="none"
4167
if [ -n "$AUTH_HASH" ] && [ -n "$USER" ] && [ -n "$PASSWORD" ]; then
@@ -207,11 +233,18 @@ if [ "$ALLOW_HASH_CONTENT_PATHS" = "true" ] || [ "$ALLOW_HASH_CONTENT_PATHS" = "
207233
set \$backend_upstream "$BACKEND_HOST:$BACKEND_PORT";
208234
proxy_pass http://\$backend_upstream;
209235
proxy_http_version 1.1;
236+
237+
# === Standard proxy headers ===
210238
proxy_set_header Host \$host;
211239
proxy_set_header X-Real-IP \$remote_addr;
212240
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
241+
proxy_set_header X-Forwarded-Proto \$scheme;
242+
proxy_set_header X-Forwarded-Host \$host;
243+
proxy_set_header X-Forwarded-Port \$server_port;
244+
245+
# === WebSocket support (uses map for correct behavior) ===
213246
proxy_set_header Upgrade \$http_upgrade;
214-
proxy_set_header Connection "upgrade";
247+
proxy_set_header Connection \$connection_upgrade;
215248
}
216249
EOF
217250

nginx.conf

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,22 @@ http {
1414
tcp_nodelay on;
1515
keepalive_timeout 65;
1616

17+
# Automatically sets Connection header based on whether it's a WebSocket request
18+
map $http_upgrade $connection_upgrade {
19+
default upgrade;
20+
'' close;
21+
}
22+
1723
# Trust proxy headers for proper redirects
1824
map $http_x_forwarded_proto $redirect_scheme {
1925
default $scheme;
2026
https https;
2127
http http;
2228
}
2329

30+
# === Client body size (for file uploads) ===
31+
client_max_body_size CLIENT_MAX_BODY_SIZE_PLACEHOLDER;
32+
2433
# Use container cache directories
2534
client_body_temp_path /var/cache/nginx/client_temp;
2635
proxy_temp_path /var/cache/nginx/proxy_temp;
@@ -38,6 +47,23 @@ http {
3847
# Force relative redirects (don't include scheme/host/port)
3948
absolute_redirect off;
4049

50+
# === Proxy buffering (configurable for streaming vs caching) ===
51+
proxy_buffering PROXY_BUFFERING_PLACEHOLDER;
52+
proxy_request_buffering PROXY_REQUEST_BUFFERING_PLACEHOLDER;
53+
54+
# === Extended timeouts for streaming/WebSocket/long-polling ===
55+
proxy_connect_timeout PROXY_CONNECT_TIMEOUT_PLACEHOLDER;
56+
proxy_send_timeout PROXY_SEND_TIMEOUT_PLACEHOLDER;
57+
proxy_read_timeout PROXY_READ_TIMEOUT_PLACEHOLDER;
58+
59+
# === Buffer sizes (used when buffering is enabled) ===
60+
proxy_buffer_size 128k;
61+
proxy_buffers 4 256k;
62+
proxy_busy_buffers_size 256k;
63+
64+
# === SSE/EventSource support ===
65+
proxy_set_header X-Accel-Buffering no;
66+
4167
# Custom error pages
4268
error_page 403 /403.html;
4369
location = /403.html {
@@ -88,23 +114,37 @@ http {
88114
set $backend_upstream "BACKEND_HOST_PLACEHOLDER:BACKEND_PORT_PLACEHOLDER";
89115
proxy_pass http://$backend_upstream;
90116
proxy_http_version 1.1;
117+
118+
# === Standard proxy headers ===
91119
proxy_set_header Host $host;
92120
proxy_set_header X-Real-IP $remote_addr;
93121
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
122+
proxy_set_header X-Forwarded-Proto $scheme;
123+
proxy_set_header X-Forwarded-Host $host;
124+
proxy_set_header X-Forwarded-Port $server_port;
125+
126+
# === WebSocket support (uses map for correct behavior) ===
94127
proxy_set_header Upgrade $http_upgrade;
95-
proxy_set_header Connection "upgrade";
128+
proxy_set_header Connection $connection_upgrade;
96129
}
97130

98131
# Allow specific file extensions if configured (optional static assets)
99132
location ~* \.(ALLOWED_EXTENSIONS_PLACEHOLDER)$ {
100133
set $backend_upstream "BACKEND_HOST_PLACEHOLDER:BACKEND_PORT_PLACEHOLDER";
101134
proxy_pass http://$backend_upstream;
102135
proxy_http_version 1.1;
136+
137+
# === Standard proxy headers ===
103138
proxy_set_header Host $host;
104139
proxy_set_header X-Real-IP $remote_addr;
105140
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
141+
proxy_set_header X-Forwarded-Proto $scheme;
142+
proxy_set_header X-Forwarded-Host $host;
143+
proxy_set_header X-Forwarded-Port $server_port;
144+
145+
# === WebSocket support (uses map for correct behavior) ===
106146
proxy_set_header Upgrade $http_upgrade;
107-
proxy_set_header Connection "upgrade";
147+
proxy_set_header Connection $connection_upgrade;
108148
}
109149

110150
# Main location - authentication logic will be inserted here
@@ -113,12 +153,24 @@ AUTH_CHECK_BLOCK_PLACEHOLDER
113153
set $backend_upstream "BACKEND_HOST_PLACEHOLDER:BACKEND_PORT_PLACEHOLDER";
114154
proxy_pass http://$backend_upstream;
115155
proxy_http_version 1.1;
156+
157+
# === Standard proxy headers ===
116158
proxy_set_header Host $host;
117159
proxy_set_header X-Real-IP $remote_addr;
118160
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
161+
proxy_set_header X-Forwarded-Proto $scheme;
162+
proxy_set_header X-Forwarded-Host $host;
163+
proxy_set_header X-Forwarded-Port $server_port;
164+
165+
# === WebSocket support (uses map for correct behavior) ===
119166
proxy_set_header Upgrade $http_upgrade;
120-
proxy_set_header Connection "upgrade";
167+
proxy_set_header Connection $connection_upgrade;
168+
121169
proxy_set_header Cookie $http_cookie;
170+
171+
# === Handle redirects from backend ===
172+
proxy_redirect http://$backend_upstream/ /;
173+
proxy_redirect https://$backend_upstream/ /;
122174
}
123175
}
124176
}

0 commit comments

Comments
 (0)