A one-byte asset is served with Content-Length: 0 and its byte still written, which corrupts a keep-alive connection
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 75/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- javascript, node.js, webpack
Línea de trabajo
El error está en src/utils/compatibleAPI.js (o src/utils.js en webpack-dev-middleware) donde byteLength se calcula incorrectamente para un recurso de un byte. Comience examinando la función createReadStreamOrReadFileSync y la función auxiliar calcStartAndEnd. El script de reproducción demuestra el problema; ejecútelo para ver el Content-Length incorrecto. La solución implica ajustar el cálculo de la longitud en bytes para el caso límite donde el inicio y el final son ambos cero pero el archivo tiene un byte.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
a compilation asset of exactly one byte is served with Content-Length: 0, and the byte is still written after the headers. on a keep-alive socket the next response then fails to parse (HPE_INVALID_CONSTANT in a Node client). an empty asset and a two-byte asset are fine
the cause is the stream length in createReadStreamOrReadFileSync, src/utils/compatibleAPI.js in 2.0.4
byteLength = end === 0 ? 0 : end - start + 1;
calcStartAndEnd clamps end to Math.max(offset, offset + len - 1), so an empty file and a one-byte file both arrive as start = 0, end = 0. the special case was written for the empty one and swallows the other. webpack-dev-middleware 8.3.0 has the same line in src/utils.js
repro
const http = require("node:http"), net = require("node:net");
const webpack = require("webpack"), middleware = require("@rspack/dev-middleware");
const { sources } = webpack;
const compiler = webpack({
mode: "development", devtool: false, context: __dirname, entry: "./src/index.js",
output: { path: __dirname + "/dist", filename: "bundle.js" },
plugins: [{ apply(c) { c.hooks.thisCompilation.tap("one", (compilation) => {
compilation.hooks.processAssets.tap({ name: "one", stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL }, () => {
compilation.emitAsset("one.txt", new sources.RawSource("a"));
compilation.emitAsset("two.txt", new sources.RawSource("ab"));
});
}); } }],
});
const mw = middleware(compiler, { stats: false });
const server = http.createServer((req, res) => mw(req, res, () => { res.statusCode = 404; res.end(); }));
server.listen(0, () => mw.waitUntilValid(async () => {
const port = server.address().port;
for (const f of ["one.txt", "two.txt"]) {
const raw = await new Promise((resolve) => {
const s = net.connect(port, "127.0.0.1", () => s.write(`GET /${f} HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n`));
const c = []; s.on("data", (d) => c.push(d)); s.on("close", () => resolve(Buffer.concat(c).toString()));
});
console.log(`--- ${f}\n${raw}`);
}
server.close(); mw.close();
}));
actual
--- one.txt
HTTP/1.1 200 OK
Content-Length: 0
a
--- two.txt
HTTP/1.1 200 OK
Content-Length: 2
ab
expected
Content-Length: 1 for one.txt
seen in practice through rspack's dev server: an empty stylesheet compiles to a single line feed in development, and every such stylesheet was served empty. I have a fix ready that sizes the stream from the byte count the caller already holds
- Lenguaje dominante
- JavaScript
- Estrellas
- 6
- Forks
- 1
- Merge medio
- 7 h 42 min
- PR fusionados (30 d)
- 2
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de rstackjs/rspack-dev-middleware
-
Dependency DashboardAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 25/100
Todos los issues de rstackjs/rspack-dev-middleware
Issues similares
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 65/100
521xueweihan/HelloGitHub#4025 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
yetone/magpie#2844 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
c1overzz/dsh-bili-scroll#22 ·
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
maproulette/maproulette-frontend#2944 ·
Los mantenedores suelen responder en 1 día