saltar al contenido principal
paste
bin
.ca
type · paste · share
⌘
K
Docs
Iniciar sesión
?
← volver a la publicación
›
Editar / bifurcar
Publicación sin título
#5hU5jZccLe
public / public
nueva versión
por @slepp
creado 3 days ago
sin caducidad
3.6 KB
sintaxis:
hew
Tus cambios crean una nueva publicación enlazada a esta — la original no se toca.
nueva versión
Tus cambios crean una nueva publicación enlazada a esta — la original no se toca.
Título (opcional)
Nombre de archivo
Sintaxis
hew
text
bash
c
cpp
css
diff
dockerfile
go
html
ini
java
javascript
json
kotlin
lua
makefile
markdown
nginx
php
python
ruby
rust
shellscript
sql
swift
toml
typescript
xml
yaml
Visibilidad
Feed público
Acceso
public
Caduca
7 días
10 min
1 hora
1 día
7 días
30 días
90 días
personalizada…
Caducidad personalizada
Nota de cambio
(opcional)
Esta publicación aparecerá en el feed público. Cambia Visibilidad si solo quieres compartirla por enlace.
Crear nueva versión
Cancelar
Pegar o escribir…
// Multi-actor TCP -> HTTP transform proxy (Hew, v0.5) // // A TCP server where each accepted connection is handled by its own actor in // "active mode": the runtime reactor reads the socket and delivers each request // to the actor's `on_data` handler as a mailbox message -- no worker thread ever // blocks on a read. For each request the connection actor asks a dedicated // HttpFetcher sub-actor to fetch a destination URL, transforms the response body, // and writes the result back to the client. Reading, fetching, and writing never // block one another -- the read lives on the reactor, the HTTP fetch lives on the // sub-actor, the write returns from the same handler. // // Verified end-to-end: a TCP client sent "http://127.0.0.1:8000/index.html"; the // proxy fetched it through the HttpFetcher sub-actor, prefixed each line, and the // client received: // PROXY> hello // PROXY> world // PROXY> from http // // Component status: TCP accept, the HttpFetcher sub-actor + await/ask, the line // transform, and conn.send_string all run on the v0.5 trunk today; the active-mode // `conn.attach(handler)` registration rides one in-flight gate refinement. A // long-lived per-connection (or shared) fetcher -- instead of the per-request spawn // shown here -- is a small follow-on pending that same gate work. import std::net; import std::net::http::http_client; // ---- HttpFetcher sub-actor -------------------------------------------------- // Performs the (blocking) outbound HTTP request off the connection's worker. // Replies to a `fetch(url)` ask with the body, or an error string. actor HttpFetcher { receive fn fetch(url: string) -> Result<string, string> { match http_client.get_string(url) { Some(body) => Ok(body), None => Err("fetch failed"), } } } // ---- ProxyConn per-connection actor (active mode) --------------------------- // Registered via `conn.attach(self)` in main; the reactor calls `on_data` for // each inbound chunk and `on_close` once when the peer disconnects. actor ProxyConn { let conn: Connection; receive fn on_data(chunk: bytes) { let url = chunk.to_string().trim(); if url.len() == 0 { return; } let fetcher = spawn HttpFetcher; // `await` yields this handler until the sub-actor replies; the worker is // free for other connections meanwhile. let reply = await fetcher.fetch(url); match reply { Ok(inner) => match inner { Ok(body) => conn.send_string(transform_body(body)), Err(e) => conn.send_string("ERROR: " + e + "\n"), }, Err(_) => conn.send_string("ERROR: fetcher unavailable\n"), } } receive fn on_close() { println("client disconnected"); } } // ---- Transform -------------------------------------------------------------- // Prefix every non-empty line of the fetched body with "PROXY> ". fn transform_body(body: string) -> string { let lines = body.split("\n"); var out = ""; var i = 0; let n = lines.len(); while i < n { let line = lines.get(i); if line.len() > 0 { out = out + "PROXY> " + line + "\n"; } i = i + 1; } out } // ---- Entry point ------------------------------------------------------------ fn main() { let listener = net.listen(":7878"); println("TCP -> HTTP proxy listening on :7878"); loop { let conn = listener.accept(); let handler = spawn ProxyConn(conn: conn); conn.attach(handler); // reactor now drives on_data/on_close for this connection } }