Exposes http caching to the browser by adding functionality to XMLHttpRequest, and then running XMLHttpRequest over http2 over WebSockets
This library provides a user-space based HTTP/2 client implementation and cache that slots in under traditional network Browser APIs such as XHR (eventually Fetch). This project is intended to be useful for 1. providing HTTP/2 emulation when not natively available and 2. allowing backends to pre-populate a browser-side cache via HTTP/2 push.
This project is designed to be 100% spec compliant. It should be removable without loss of functionality when there is universal support for HTTP/2 with a consistent H2-cache implementation.
HTTP/2 (RFC-7540) runs in userspace by running it on top of WebSocket. An HTTP (RFC-7234) in memory cache implementation stores cacheable responses. The XHR API can be configured to route a subset of requests via this transport stack.
A consistent implementation for caching HTTP/2 push requests has not yet emerged. See discussion for current the state of the world. This HTTP/2 implementation will not use the cache for any request (Including HTTP/2 pushed) that contains the request cache-directive "no-cache". HTTP/2 pushed requests that do not include this directive may have their HTTP/2 stream aborted by the client if the cache already contains a cached response for that request. I.E. use the request cache-directive "no-cache" when doing cache-busting. This should work in all cases where you want to do a cache replacement.
HTTP/2 push requests require an established stream to send the push request. The API provides a means to open a long-lived upstream request to an arbitrary location that may be used to send push requests. Alternatively, streams may be left open for sending future pushed responses via "long-pushing", that is sending the push promise for a future response, prior to completing the response to an existing request. I.e. always maintain one response in flight, by sending the push promise for it prior to completing a response.
The API attaches to the XMLHttpRequest object.
XMLHttpRequest.proxy([urls of configurations])
The proxy([urls of configurations])
triggers fetching of JSON configurations on the backend
server. The configurations should be of the following form:
{
// Logger debugLevel true='info' or (info|debug|trace)
"clientLogLevel": false,
// Transport endpoint
"transport": "wss://where-the-underlying-ws-transport-connects:443/",
// Transport push path
"push": "optional-path-that-is-opened-for-pushes",
// Transport reconnect settings
"reconnect": true,
"reconnectInterval": 100,
"maximumReconnectInterval": 4000,
// AccelerationStrategy default to "always" can be "connected"
// - Value "always" means always/don't make requests if they are proxied but no ws connection is open.
// - Value "connected" means make requests when connected via websocket.
"accelerationStrategy": "always",
"proxy": [
"http://origin-to-send-via-http2:80/path/",
"http://origin-to-send-via-http2:80/path2/",
"http://other-origin-to-send-via-http2:80"
]
}
In full
<script type="text/javascript" src="http2-cache.js"></script>
<script type="text/javascript">
XMLHttpRequest.proxy(["http://localhost:8000/config"]);
</script>
The integration tests require Java JDK 8 be installed.
npm i
npm run build
npm run test:browser