lws-range: HTTP Range Request Middleware for lws
This package, `lws-range`, is a middleware plugin designed for the `local-web-server` (`lws`) ecosystem, specifically adding robust support for HTTP Range Requests. It effectively wraps the `koa-range` library to integrate this functionality seamlessly into `lws` servers. As of version 4.0.1, it provides compliant handling of partial content requests, enabling clients to request specific byte ranges of a resource, which is crucial for features like video streaming, large file downloads with resume capabilities, and efficient caching. The project appears to be actively maintained, indicated by recent version releases and continuous integration. Its primary differentiator is its deep integration with the `lws` server, providing a simple `--stack` activation for this common HTTP feature without needing to manually configure low-level range request parsing. It mandates Node.js version 12.17 or higher.
Common errors
-
HTTP/1.1 416 Range Not Satisfiable
cause The client requested a byte range that is invalid, out of bounds, or exceeds the file size of the resource being served.fixVerify the `Range` header sent by the client. Ensure the requested start and end bytes are valid and within the actual file's length. This error can also occur if the resource does not exist. -
Error: Middleware must be a function.
cause `lws-range` was not correctly imported or called as a function when added to the `lws` stack, typically meaning it was passed as `lwsRange` instead of `lwsRange()`.fixEnsure you are calling `lwsRange()` (with parentheses) when adding it to the `lws` stack, e.g., `stack: [lwsRange(), ...]` for programmatic usage or ensure the CLI option is correctly formatted. -
Missing 'Accept-Ranges: bytes' header in response.
cause The `lws-range` middleware is either not loaded in the `lws` stack, is placed incorrectly after a static file handler, or another middleware is interfering with HTTP headers.fixVerify that `lws-range` is included in your `lws` stack and that its position is correct (e.g., before `lws-static`). Check for other middleware that might modify or remove the `Accept-Ranges` header.
Warnings
- breaking `lws-range` v3.x removed the ability to pass options directly to the underlying `koa-range` library. Configuration for range handling must now be managed at the `lws` framework level or via environment variables if supported by `lws` itself.
- breaking `lws-range` v4.x requires `lws` (local-web-server) v5.x or higher due to significant API changes in the `lws` core that this middleware integrates with.
- gotcha For HTTP Range Requests to function correctly, the `lws-range` middleware must be placed *before* any static file serving middleware (e.g., `lws-static`) in the `lws` stack. If placed incorrectly, static files may be served in their entirety without honoring range headers.
Install
-
npm install lws-range -
yarn add lws-range -
pnpm add lws-range
Imports
- lwsRange
import { lwsRange } from 'lws-range';import lwsRange from 'lws-range';
- lwsRange
const lwsRange = require('lws-range');
Quickstart
import lws from 'lws';
import lwsRange from 'lws-range';
import lwsStatic from 'lws-static'; // Assuming lws-static is also installed
import { resolve } from 'path';
import { writeFileSync, mkdirSync } from 'fs';
const publicDir = resolve(__dirname, './public');
mkdirSync(publicDir, { recursive: true });
// Create a sample large file for testing range requests
const largeFilePath = resolve(publicDir, 'large-file.txt');
const dummyContent = 'This is a sample text file to demonstrate HTTP Range requests. '.
repeat(100) + 'It should be sufficiently long to make range requests meaningful.';
writeFileSync(largeFilePath, dummyContent);
// Create a simple lws server with range request support and static file serving
const server = lws.create({
// The middleware stack defines the order of processing
stack: [
// lws-range must come before lws-static to handle range requests for static files
lwsRange(),
lwsStatic({
root: publicDir, // Serve files from the 'public' directory
index: ['index.html', 'index.htm'] // Specify default index files
})
],
port: process.env.PORT ?? 8000 // Listen on port 8000 or specified by env var
});
server.listen(server.port, () => {
console.log(`lws server with range support listening on http://localhost:${server.port}`);
console.log('To test, create a file named ' + largeFilePath + ' (or use the one created by this script).');
console.log('Then try sending a curl request with a Range header, e.g.,');
console.log(`curl -I -H "Range: bytes=0-100" http://localhost:${server.port}/large-file.txt`);
console.log(`curl -H "Range: bytes=0-10" http://localhost:${server.port}/large-file.txt`);
});