BHTTP (RFC 9292) encoder and decoder for the Fetch API Request/Response interface


Keywords
bhttp, binary-http, rfc9292, fetch-api, request, response, encoder, decoder, cloudflare-workers
License
MIT
Install
npm install bhttp-ts@0.5.4

Documentation

bhttp-ts

A BHTTP (RFC 9292: Binary Representation of HTTP Messages) encoder and decoder for the Request/Response interface of Fetch API.

This module works on Node.js, Cloudflare Workers, and other JavaScript runtimes supporting the Fetch API.

Note: This is a fork of dajiaji/bhttp-js, converted from Deno to a standard npm package.

Installation

npm install bhttp-ts

Usage

Encode/Decode Request

import { BHttpDecoder, BHttpEncoder } from "bhttp-ts";

const req = new Request("https://www.example.com/hello.txt", {
  method: "GET",
  headers: {
    "User-Agent": "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3",
    "Accept-Language": "en, mi",
  },
});

// Encode a Request object to a BHTTP binary
const encoder = new BHttpEncoder();
const binReq = await encoder.encodeRequest(req);

// Decode the BHTTP binary to a Request object
const decoder = new BHttpDecoder();
const decodedReq = decoder.decodeRequest(binReq);

Encode/Decode Response

import { BHttpDecoder, BHttpEncoder } from "bhttp-ts";

const res = new Response("Hello World!", {
  status: 200,
  headers: { "Content-Type": "text/plain" },
});

// Encode a Response object to a BHTTP binary
const encoder = new BHttpEncoder();
const binRes = await encoder.encodeResponse(res);

// Decode the BHTTP binary to a Response object
const decoder = new BHttpDecoder();
const decodedRes = decoder.decodeResponse(binRes);

Streaming API

For indeterminate-length messages, use the streaming encoders and decoder:

import {
  BHttpRequestStreamEncoder,
  BHttpResponseStreamEncoder,
  BHttpStreamDecoder,
} from "bhttp-ts";

// Streaming request encoding
const reqEncoder = new BHttpRequestStreamEncoder();
yield reqEncoder.encodePreamble("POST", "https", "example.com", "/api", headers);
yield reqEncoder.encodeContentChunk(chunk1);
yield reqEncoder.encodeContentChunk(chunk2);
yield reqEncoder.encodeEnd();

// Streaming response encoding
const resEncoder = new BHttpResponseStreamEncoder();
yield resEncoder.encodePreamble(200, headers);
yield resEncoder.encodeContentChunk(chunk1);
yield resEncoder.encodeEnd(trailers);

// Streaming decode
const decoder = new BHttpStreamDecoder();
for (const chunk of incomingData) {
  for (const event of decoder.push(chunk)) {
    switch (event.type) {
      case "request-preamble":
        // event.method, event.scheme, event.authority, event.path, event.headers
        break;
      case "response-preamble":
        // event.status, event.headers
        break;
      case "content":
        // event.data
        break;
      case "trailers":
        // event.headers
        break;
    }
  }
}
for (const event of decoder.end()) {
  // handle final events
}

When working with Fetch Request and Response objects, the high-level streaming methods preserve backpressure and cancellation automatically:

const encoder = new BHttpEncoder();
const decoder = new BHttpDecoder();

const encoded = encoder.encodeRequestStream(request);
const decoded = await decoder.decodeRequestStream(encoded);

Response equivalents are encodeResponseStream and decodeResponseStream. The existing BHttpRequestStreamEncoder, BHttpResponseStreamEncoder, and BHttpStreamDecoder remain available when manual framing is required.

API

BHttpEncoder

  • encodeRequest(request: Request, options?: { maxMessageSize?: number }): Promise<Uint8Array> - Encode a Request to known-length BHTTP
  • encodeResponse(response: Response, options?: { maxMessageSize?: number }): Promise<Uint8Array> - Encode a Response to known-length BHTTP
  • encodeRequestStream(request: Request): ReadableStream<Uint8Array> - Encode a streaming Request to indeterminate-length BHTTP
  • encodeResponseStream(response: Response): ReadableStream<Uint8Array> - Encode a streaming Response to indeterminate-length BHTTP

BHttpDecoder

  • decodeRequest(data: ArrayBuffer | Uint8Array): Request - Decode BHTTP to a Request
  • decodeResponse(data: ArrayBuffer | Uint8Array): Response - Decode BHTTP to a Response
  • decodeRequestStream(stream: ReadableStream<Uint8Array>): Promise<Request> - Decode a streaming BHTTP request
  • decodeResponseStream(stream: ReadableStream<Uint8Array>): Promise<Response> - Decode a streaming BHTTP response

BHttpRequestStreamEncoder / BHttpResponseStreamEncoder

For encoding indeterminate-length messages incrementally.

BHttpStreamDecoder

For decoding BHTTP messages incrementally, emitting events as data arrives.

References

License

MIT - See LICENSE for details.