carriages

Protocol implementation crate for Railscale. Provides HTTP parsing/rewriting and TCP transport, built on train_track traits.

Module Layout

src/
  lib.rs          — re-exports
  http/
    frame.rs      — HttpFrame (implements Frame)
    codec.rs      — HttpStreamingCodec (tokio_util Decoder)
    parser.rs     — HttpParser (implements FrameParser)
    pipeline.rs   — HttpPipeline (implements FramePipeline)
  tcp/
    source.rs     — TcpSource (implements StreamSource)
    destination.rs — TcpDestination (implements StreamDestination)
    router.rs     — TcpRouter (implements DestinationRouter)

HTTP Layer

HttpFrame: Wraps a Bytes buffer with a routing flag. When routing is true, routing_key() returns Some(&self.data) — used for the Host header value.

HttpStreamingCodec: tokio_util::codec::Decoder that splits on \r\n boundaries. Includes CRLF in frame bytes. Header matching operates on &line[..line.len()-2] (strips CRLF).

HttpParser: Wraps the codec in a FramedRead. Identifies Host header as the routing frame. All other headers and body bytes pass through as ParsedData::Passthrough or ParsedData::Parsed.

HttpPipeline: Header rewriting engine. Takes a list of (Finder, Bytes) pairs — memchr Finder matches header names, Bytes is the replacement value. Uses rayon parallel iteration when multiple rules exist.

TCP Layer

TcpSource: Binds a TCP listener, accept() returns split (OwnedReadHalf, OwnedWriteHalf).

TcpDestination: Protocol-agnostic byte pipe over a connected TcpStream. write() sends bytes upstream, relay_response() copies the response back to the client.

TcpRouter: Two modes:

  • fixed(addr) — always connects to the same upstream
  • from_routing_key() — extracts host from routing key bytes, connects to host:80

Test Coverage

34 tests across both crates covering codec, frame, parser, pipeline, source, destination, routing, and integration scenarios.