Skip to content

Commit a58b08b

Browse files
Merge pull request #10 from CarterPerez-dev/project/secure-p2p-messaging
in progress debugging checkpoint
2 parents 3889bdd + 7b06195 commit a58b08b

File tree

18 files changed

+280
-21
lines changed

18 files changed

+280
-21
lines changed

.github/workflows/lint.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919

2020
defaults:
2121
run:
22-
working-directory: PROJECTS/api-security-scanner/backend
22+
working-directory: PROJECTS/backend
2323

2424
steps:
2525
- name: Checkout code
@@ -34,7 +34,7 @@ jobs:
3434
uses: actions/cache@v4
3535
with:
3636
path: ~/.cache/pip
37-
key: ${{ runner.os }}-pip-${{ hashFiles('PROJECTS/api-security-scanner/backend/pyproject.toml') }}
37+
key: ${{ runner.os }}-pip-${{ hashFiles('PROJECTS/backend/pyproject.toml') }}
3838
restore-keys: |
3939
${{ runner.os }}-pip-
4040
@@ -49,10 +49,10 @@ jobs:
4949
echo "Running pylint..."
5050
if pylint . > pylint-output.txt 2>&1; then
5151
echo "PYLINT_PASSED=true" >> $GITHUB_ENV
52-
echo "No pylint errors found!"
52+
echo "No pylint errors found!"
5353
else
5454
echo "PYLINT_PASSED=false" >> $GITHUB_ENV
55-
echo "⚠️ Pylint found issues!"
55+
echo "Pylint found issues!"
5656
fi
5757
cat pylint-output.txt
5858
continue-on-error: true
@@ -63,10 +63,10 @@ jobs:
6363
echo "Running ruff check..."
6464
if ruff check . > ruff-output.txt 2>&1; then
6565
echo "RUFF_PASSED=true" >> $GITHUB_ENV
66-
echo "No ruff errors found!"
66+
echo "No ruff errors found!"
6767
else
6868
echo "RUFF_PASSED=false" >> $GITHUB_ENV
69-
echo "⚠️ Ruff found issues"
69+
echo "Ruff found issues"
7070
fi
7171
cat ruff-output.txt
7272
continue-on-error: true
@@ -77,10 +77,10 @@ jobs:
7777
echo "Running mypy..."
7878
if mypy . > mypy-output.txt 2>&1; then
7979
echo "MYPY_PASSED=true" >> $GITHUB_ENV
80-
echo "No mypy errors found"
80+
echo "No mypy errors found"
8181
else
8282
echo "MYPY_PASSED=false" >> $GITHUB_ENV
83-
echo "⚠️ Mypy found issues"
83+
echo "Mypy found issues"
8484
fi
8585
cat mypy-output.txt
8686
continue-on-error: true
@@ -90,15 +90,15 @@ jobs:
9090
if: github.event_name == 'pull_request'
9191
run: |
9292
{
93-
echo '## 🔍 Lint & Type Check Results'
93+
echo '##Lint & Type Check Results'
9494
echo ''
9595
9696
# Pylint Status
9797
if [[ "${{ env.PYLINT_PASSED }}" == "true" ]]; then
98-
echo '###Pylint: **Passed**'
98+
echo '###Pylint: **Passed**'
9999
echo 'No pylint issues found.'
100100
else
101-
echo '### ⚠️ Pylint: **Issues Found**'
101+
echo '###Pylint: **Issues Found**'
102102
echo '<details><summary>View pylint output</summary>'
103103
echo ''
104104
echo '```'
@@ -110,7 +110,7 @@ jobs:
110110
111111
# Ruff Status
112112
if [[ "${{ env.RUFF_PASSED }}" == "true" ]]; then
113-
echo '###Ruff: **Passed**'
113+
echo '###Ruff: **Passed**'
114114
echo 'No ruff issues found.'
115115
else
116116
echo '### ⚠️ Ruff: **Issues Found**'
@@ -125,10 +125,10 @@ jobs:
125125
126126
# Mypy Status
127127
if [[ "${{ env.MYPY_PASSED }}" == "true" ]]; then
128-
echo '### Mypy: **Passed**'
128+
echo '### Mypy: **Passed**'
129129
echo 'No mypy issues found.'
130130
else
131-
echo '### ⚠️ Mypy: **Issues Found**'
131+
echo '### Mypy: **Issues Found**'
132132
echo '<details><summary>View mypy output</summary>'
133133
echo ''
134134
echo '```'

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
cyber-proj
2+
*.cache
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# WebSocket Implementation - Research & Prep (Milestone 1.5)
2+
3+
**Created:** 2025-11-16
4+
**Status:** Planning Phase
5+
6+
---
7+
8+
## 🎯 **The REAL Goal**
9+
10+
Not just "make WebSockets work" - that's easy.
11+
**Make WebSockets BETTER than nginx** and **solve the streaming/WebSocket conflict** that nginx has.
12+
13+
### **The Problem We're Solving** (From Real Experience)
14+
15+
> "streaming doesn't even work for me, and I remember hearing a while ago I have no clue if true but the thing to allow websockets to work conflict with what makes streaming work in nginx so I can't have both working"
16+
17+
**THIS is our target:** Make WebSockets + Streaming work SIMULTANEOUSLY without conflicts.
18+
19+
Nginx config issues:
20+
- `proxy_buffering off` needed for streaming (Ollama AI)
21+
- `proxy_http_version 1.1` + `Upgrade` + `Connection "upgrade"` needed for WebSockets
22+
- Timeouts configured differently (`proxy_read_timeout 86400` for WebSockets vs `300s` for streaming)
23+
- They conflict in nginx - can't have both perfect
24+
25+
**Our advantage:** We're building from scratch in Haskell - we can do BOTH right by design!
26+
27+
---
28+
29+
## 🧠 **Key Questions to Research**
30+
31+
### 1. **Technical Questions**
32+
- How does WAI/Warp handle WebSocket upgrades natively?
33+
- Does Haskell's `websockets` library play nice with Warp?
34+
- How do we detect WebSocket handshake vs regular HTTP?
35+
- Can we proxy WebSocket frames without parsing them? (performance)
36+
- How do we handle bidirectional streaming efficiently? (use STM channels? conduits?)
37+
38+
### 2. **The Conflict Question** ⚠️
39+
- WHY do streaming and WebSockets conflict in nginx?
40+
- Is it buffering? Connection reuse? Timeout handling?
41+
- How do we architect to avoid this entirely?
42+
43+
### 3. **Performance Questions**
44+
- What's the overhead of proxying WebSocket frames?
45+
- Can we do zero-copy WebSocket proxying?
46+
- How do we handle thousands of concurrent WebSocket connections?
47+
- Memory usage per connection?
48+
49+
### 4. **Protocol Questions**
50+
- WebSocket handshake: do we validate or just proxy it?
51+
- Do we need to parse WebSocket frames or pass through opaque?
52+
- How do we handle WebSocket extensions (compression, etc.)?
53+
- ping/pong frame handling - proxy or handle ourselves?
54+
55+
---
56+
57+
## 📚 **Research Needed**
58+
59+
### **Existing Research Docs**
60+
We have:
61+
-`http2-http3.md` - might have streaming info
62+
-`performance-optimization.md` - zero-copy, memory efficiency
63+
-`tls-ssl.md` - secure WebSockets (wss://)
64+
65+
Need to READ for relevant info.
66+
67+
### **New Research Required**
68+
69+
#### **1. Modern WebSocket Best Practices (2024/2025)**
70+
Sources to search:
71+
- RFC 6455 (WebSocket protocol) - official spec
72+
- Haskell `websockets` library docs - latest version
73+
- Warp WebSocket examples - production patterns
74+
- Stack Overflow - "nginx websocket streaming conflict" - find the root cause!
75+
- Modern WebSocket proxying techniques - what's changed since 2020?
76+
77+
#### **2. Haskell-Specific Patterns**
78+
- How does `websockets` library integrate with WAI?
79+
- Conduit vs Pipes vs Streaming for bidirectional data?
80+
- STM patterns for WebSocket message routing?
81+
- Resource cleanup on connection drop?
82+
83+
#### **3. Performance Benchmarks**
84+
- What's nginx WebSocket performance? (baseline)
85+
- What's Warp native WebSocket performance?
86+
- Overhead of proxying vs direct serving?
87+
- Can we beat nginx?
88+
89+
#### **4. Real-World Problems**
90+
Search for:
91+
- "nginx websocket not working"
92+
- "nginx streaming chunked transfer"
93+
- "websocket proxy buffering issues"
94+
- "socket.io nginx configuration problems"
95+
96+
Learn from what DOESN'T work!
97+
98+
---
99+
100+
## 🏗️ **High-Level Implementation Plan** (Tentative)
101+
102+
### **Phase 1: Detection & Handshake**
103+
**Goal:** Detect WebSocket upgrade request, proxy handshake
104+
105+
```
106+
Request comes in → Check headers (Upgrade: websocket) →
107+
If YES: WebSocket path
108+
If NO: Normal HTTP path (existing code)
109+
```
110+
111+
**Key:** Don't break existing HTTP proxying!
112+
113+
### **Phase 2: Connection Upgrade**
114+
**Goal:** Establish proxy connection to backend WebSocket
115+
116+
```
117+
Client ←→ Proxy ←→ Backend
118+
WebSocket WebSocket
119+
```
120+
121+
**Challenge:** Maintain two WebSocket connections, proxy frames bidirectionally
122+
123+
### **Phase 3: Bidirectional Streaming**
124+
**Goal:** Stream frames in BOTH directions simultaneously
125+
126+
```haskell
127+
-- Conceptual:
128+
forkIO $ forever $ do
129+
clientFrame <- receiveFromClient
130+
sendToBackend clientFrame
131+
132+
forkIO $ forever $ do
133+
backendFrame <- receiveFromBackend
134+
sendToClient backendFrame
135+
```
136+
137+
**Challenge:** Handle connection drops, timeouts, proper cleanup
138+
139+
### **Phase 4: Integration with Streaming**
140+
**Goal:** Ensure WebSockets + chunked transfer streaming coexist
141+
142+
**Test Case:**
143+
- WebSocket on `/api/socket.io/`
144+
- Chunked streaming on `/api/ollama/stream`
145+
- BOTH working simultaneously without conflicts!
146+
147+
---
148+
149+
## **Open Questions & Decisions**
150+
151+
### **1. Library Choice**
152+
**Options:**
153+
- A) Use `websockets` library (mature, battle-tested)
154+
- B) Use Warp's native WebSocket support
155+
- C) Roll our own (probably stupid)
156+
157+
**Need to research:** Which integrates better with our existing WAI app?
158+
159+
### **2. Frame Handling**
160+
**Options:**
161+
- A) Parse WebSocket frames (inspect, modify, validate)
162+
- B) Proxy frames opaquely (zero-copy, faster, less control)
163+
164+
**Trade-off:** Performance vs observability/security
165+
166+
### **3. Connection State**
167+
**How to track WebSocket connections?**
168+
- Add to load balancer stats?
169+
- Separate WebSocket connection pool?
170+
- Integrate with health checking?
171+
172+
### **4. Timeout Strategy**
173+
**Nginx problem:** Different timeouts for HTTP vs WebSocket vs Streaming
174+
175+
**Our approach:**
176+
- Configurable per-route?
177+
- Detect connection type and auto-adjust?
178+
- Global defaults with overrides?
179+
180+
---
181+
182+
## 🎯 **Success Criteria**
183+
184+
**Minimum (Just Working):**
185+
- ✅ Detects WebSocket handshake
186+
- ✅ Proxies upgrade to backend
187+
- ✅ Bidirectional frame proxying
188+
- ✅ Handles connection drops
189+
190+
**Good (Better than Basic):**
191+
- ✅ Zero-copy frame proxying (performance)
192+
- ✅ Works with TLS (wss://)
193+
- ✅ Integrates with load balancing
194+
- ✅ Health checks don't break WebSockets
195+
196+
**Excellent (Better than Nginx):**
197+
-**WebSockets + Streaming work SIMULTANEOUSLY without conflicts**
198+
- ✅ Auto-detection (no special config needed for WebSockets)
199+
- ✅ Better error messages than nginx
200+
- ✅ Observable (metrics on WebSocket connections)
201+
- ✅ Faster than nginx WebSocket proxying
202+
203+
---
204+
205+
## 📋 **Next Steps**
206+
207+
1. **Read existing research docs** (http2-http3.md, performance-optimization.md)
208+
2. **Deep dive into websockets library** - read source if needed
209+
3. **Find nginx conflict root cause** - search Stack Overflow, GitHub issues
210+
4. **Study WAI WebSocket examples** - how does Warp do it natively?
211+
5. **Benchmark nginx WebSocket performance** - set a target to beat
212+
6. **Design the architecture** - how it integrates with existing Proxy.hs
213+
7. **Write research doc** - `websockets-implementation.md` with full details
214+
215+
**Then:** Start coding with confidence, knowing we have a solid plan!
216+
217+
---
218+
219+
## 💡 **Insights to Remember**
220+
221+
- WebSockets are just HTTP upgrades - leverage existing HTTP proxying code
222+
- Bidirectional = two concurrent loops, not sequential
223+
- Connection cleanup is critical - use `bracket` pattern
224+
- Performance matters - socket.io can have 1000s of connections
225+
- The nginx conflict is REAL - don't repeat their mistakes
226+
227+
**Philosophy:** Research first, code smart, build something genuinely better.

PROJECTS/Aenebris/docs/research/config-design.md renamed to PROJECTS/Aenebris/docs/proxy-haskell-research/config-design.md

File renamed without changes.

PROJECTS/Aenebris/docs/research/ddos-mitigation.md renamed to PROJECTS/Aenebris/docs/proxy-haskell-research/ddos-mitigation.md

File renamed without changes.
File renamed without changes.

PROJECTS/Aenebris/docs/research/haskell-networking.md renamed to PROJECTS/Aenebris/docs/proxy-haskell-research/haskell-networking.md

File renamed without changes.
File renamed without changes.

PROJECTS/Aenebris/docs/research/load-balancing.md renamed to PROJECTS/Aenebris/docs/proxy-haskell-research/load-balancing.md

File renamed without changes.

PROJECTS/Aenebris/docs/research/ml-bot-detection.md renamed to PROJECTS/Aenebris/docs/proxy-haskell-research/ml-bot-detection.md

File renamed without changes.

0 commit comments

Comments
 (0)