Skip to content

Commit 50af17f

Browse files
committed
feat(blog): add p2p web hosting entry
1 parent de4d51e commit 50af17f

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

source/_posts/p2p-web-hosting.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
title: P2P Web Hosting
3+
date: 25/04/2025
4+
---
5+
6+
# basic local example
7+
8+
### Client A
9+
#### Host a http web server via unix sockets.
10+
> server.py
11+
```python
12+
import http.server
13+
import json
14+
import os
15+
import socket
16+
import sys
17+
import traceback
18+
19+
def process_cmd(cmd, *args):
20+
print(f"In process_cmd({cmd}, {args})...")
21+
22+
class HTTPHandler(http.server.BaseHTTPRequestHandler):
23+
def do_POST(self):
24+
size = int(self.headers.get('Content-Length', 0))
25+
body = self.rfile.read(size)
26+
args = json.loads(body) if body else []
27+
try:
28+
result = process_cmd(self.path[1:], *args)
29+
self.send(200, result or 'Success')
30+
except Exception:
31+
self.send(500, str(traceback.format_exc()))
32+
33+
def do_GET(self):
34+
self.do_POST()
35+
36+
def send(self, code, reply):
37+
# avoid exception in server.py address_string()
38+
self.client_address = ('',)
39+
self.send_response(code)
40+
self.end_headers()
41+
self.wfile.write(reply.encode('utf-8'))
42+
43+
sock_file = sys.argv[1]
44+
try:
45+
os.remove(sock_file)
46+
except OSError:
47+
pass
48+
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
49+
sock.bind(sock_file)
50+
sock.listen(0)
51+
52+
server = http.server.HTTPServer(sock_file, HTTPHandler,
53+
False)
54+
server.socket = sock
55+
server.serve_forever()
56+
57+
sock.shutdown(socket.SHUT_RDWR)
58+
sock.close()
59+
os.remove(sock_file)
60+
```
61+
and run this with:
62+
63+
`python3 server.py /tmp/http.socket`
64+
65+
## Client B
66+
### Turn the web socket path into a tcp connection that the browser can understand
67+
```bash
68+
socat TCP-LISTEN:80,forever,reuseaddr,fork UNIX-CONNECT:/tmp/http.socket
69+
```
70+
71+
### Use browser to see web page:
72+
> `http://localhost`
73+
74+
75+
# same example using P2P
76+
77+
### Client A
78+
```bash
79+
python3 server.py /tmp/http.socket
80+
# From another terminal, pipe the server socket into dumbpipe
81+
socat UNIX-CONNECT:/tmp/http.socket,keepalive,ignoreeof EXEC:"dumbpipe listen",reuseaddr
82+
# Note down nodeId from the console.
83+
```
84+
85+
### Client B
86+
```bash
87+
export nodeId=">>The id from client A Console.<<"
88+
# Connect to dumbpipe and expose the socket via tcp.
89+
export CMD="dumbpipe connect $nodeId"
90+
socat EXEC:"$CMD" TCP-LISTEN:80,forever,reuseaddr,fork
91+
# Test from another terminal
92+
curl http://localhost
93+
```
94+
95+
> *So far this only accepts 1 http e2e and you have to kill `socat` on client B for `curl` to respond. This is due to unix-listen just stuck with the first request and it won't fork additional requests.*
96+

0 commit comments

Comments
 (0)