A BHTTP (Binary Representation of HTTP Messages) Encoder and Decoder written in TypeScript.
Attributes
Includes Deno configuration
Repository
Current version released
2 months ago
bhttp-js
[![JSR](https://jsr.io/badges/@dajiaji/bhttp)](https://jsr.io/@dajiaji/bhttp)
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/bhttp/mod.ts)
![Browsers CI](https://github.com/dajiaji/bhttp-js/actions/workflows/ci_browsers.yml/badge.svg)
![Node.js CI](https://github.com/dajiaji/bhttp-js/actions/workflows/ci_node.yml/badge.svg)
![Deno CI](https://github.com/dajiaji/bhttp-js/actions/workflows/ci.yml/badge.svg)
![Cloudflare Workers CI](https://github.com/dajiaji/bhttp-js/actions/workflows/ci_cloudflare.yml/badge.svg)
![@fastly/js-compute CI](https://github.com/dajiaji/bhttp-js/actions/workflows/ci_fastly.yml/badge.svg)
![bun CI](https://github.com/dajiaji/bhttp-js/actions/workflows/ci_bun.yml/badge.svg)
[![codecov](https://codecov.io/gh/dajiaji/bhttp-js/branch/main/graph/badge.svg?token=7I7JGKDDJ2)](https://codecov.io/gh/dajiaji/bhttp-js)
A BHTTP (RFC9292: Binary Representation of HTTP Messages) encoder and decoder written in TypeScript
for the Request/Response interface of Fetch API.
This module works on web browsers, Node.js, Deno and various other JavaScript runtimes.
for the Request/Response interface of Fetch API.
This module works on web browsers, Node.js, Deno and various other JavaScript runtimes.
Index
Supported Environments
- Web browsers which support Request/Response interface of Fetch API.
- Node.js: 18.x, 19.x, 20.x
- Deno: 1.x
- bun: 0.3-
- Cloudflare Workers
- @fastly/js-compute
Installation
Web Browser
Followings are how to use with typical CDNs. Other CDNs can be used as well.
Using esm.sh:
<!-- use a specific version -->
<script type="module">
import * as bhttp from "https://esm.sh/bhttp-js@0.3.3";
// ...
</script>
<!-- use the latest stable version -->
<script type="module">
import * as bhttp from "https://esm.sh/bhttp-js";
// ...
</script>
Using unpkg:
<!-- use a specific version -->
<script type="module">
import * as bhttp from "https://unpkg.com/bhttp-js@0.3.3/esm/mod.js";
// ...
</script>
Node.js
Using npm:
npm install bhttp-js
Using yarn:
yarn add bhttp-js
Deno
Using jsr:
deno add @dajiaji/bhttp
import * as bhttp from "@dajiaji/bhttp";
Cloudflare Workers
Using jsr:
npx jsr add @dajiaji/bhttp
import * as bhttp from "@dajiaji/bhttp";
Usage
This section shows some typical usage examples.
Web Browser / Cloudflare Workers
BHTTP client on Web Browser:
<html>
<head></head>
<body>
<script type="module">
import { BHttpEncoder, BHttpDecoder } from 'https://esm.sh/bhttp-js@0.3.3';
globalThis.doBHttp = async () => {
try {
const encoder = new BHttpEncoder();
const req = new Request("https://target.example/query?foo=bar");
const bReq = await encoder.encodeRequest(req);
const res = await fetch("https://bin.example/to_target", {
method: "POST",
headers: {
"Content-Type": "message/bhttp",
},
body: bReq,
});
const decoder = new BHttpDecoder();
const decodedRes = decoder.decodeResponse(await res.arrayBuffer());
// decodedRes.status === 200;
const body = await decodedRes.text();
// body === "baz"
} catch (err) {
alert(err.message);
}
}
</script>
<button type="button" onclick="doBHttp()">do BHTTP</button>
</body>
</html>
BHTTP server on Cloutflare Workers:
import { BHttpDecoder, BHttpEncoder } from "./bhttp.js";
export default {
async fetch(request) {
const decoder = new BHttpDecoder();
const encoder = new BHttpEncoder();
const url = new URL(request.url);
if (url.pathname === "/to_target") {
try {
if (request.headers.get("content-type") !== "message/bhttp") {
throw new Error("Invalid content-type.");
}
const reqBody = await request.arrayBuffer();
const decodedReq = decoder.decodeRequest(reqBody);
const res = new Response("baz", {
headers: { "Content-Type": "text/plain" },
});
const bRes = await encoder.encodeResponse(res);
return new Response(bRes, {
headers: { "Content-Type": "message/bhttp" },
});
} catch (err) {
return new Response(
await encoder.encodeResponse(
new Response(err.message, { status: 400 }),
),
{ status: 400, headers: { "Content-Type": "message/bhttp" } },
);
}
}
return new Response(
await encoder.encodeResponse(new Response("", { status: 404 })),
{ status: 404, headers: { "Content-Type": "message/bhttp" } },
);
},
};
Node.js
const { BHttpEncoder, BHttpDecoder } = require("bhttp-js");
async function doBHttp() {
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 string.
const encoder = new BHttpEncoder();
const binReq = await encoder.encodeRequest(req);
// Decode the BHTTP binary string to a Request object.
const decoder = new BHttpDecoder();
const decodedReq = decoder.decodeRequest(binReq);
}
doBHttp();
Deno
import { BHttpDecoder, BHttpEncoder } from "@dajiaji/bhttp";
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 string.
const encoder = new BHttpEncoder();
const binReq = await encoder.encodeRequest(req);
// Decode the BHTTP binary string to a Request object.
const decoder = new BHttpDecoder();
const decodedReq = decoder.decodeRequest(binReq);
Contributing
We welcome all kind of contributions, filing issues, suggesting new features or sending PRs.