Skip to content

Commit 7d033f1

Browse files
committed
fix uws polling
1 parent a463d26 commit 7d033f1

File tree

1 file changed

+42
-12
lines changed

1 file changed

+42
-12
lines changed

lib/transports-uws/polling.ts

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,18 @@ export class Polling extends Transport {
122122
return;
123123
}
124124

125+
const contentLengthHeader = Number(req.headers["content-length"]);
126+
if (!contentLengthHeader) {
127+
this.onError("invalid content-length header");
128+
res.writeStatus("400 Invalid content-length header").end();
129+
return;
130+
}
131+
if (contentLengthHeader > this.maxHttpBufferSize) {
132+
this.onError("payload too large");
133+
res.writeStatus("413 Payload Too Large").end();
134+
return;
135+
}
136+
125137
const isBinary = "application/octet-stream" === req.headers["content-type"];
126138

127139
if (isBinary && this.protocol === 4) {
@@ -131,11 +143,11 @@ export class Polling extends Transport {
131143
this.dataReq = req;
132144
this.dataRes = res;
133145

134-
let chunks = [];
146+
let buffer;
135147
let contentLength = 0;
136148

137149
const cleanup = () => {
138-
this.dataReq = this.dataRes = chunks = null;
150+
this.dataReq = this.dataRes = null;
139151
};
140152

141153
const onClose = () => {
@@ -154,8 +166,8 @@ export class Polling extends Transport {
154166
res.writeHeader(key, String(headers[key]));
155167
});
156168

157-
const onEnd = () => {
158-
this.onData(Buffer.concat(chunks).toString());
169+
const onEnd = (buffer) => {
170+
this.onData(buffer.toString());
159171

160172
if (this.readyState !== "closing") {
161173
res.end("ok");
@@ -165,18 +177,36 @@ export class Polling extends Transport {
165177

166178
res.onAborted(onClose);
167179

168-
res.onData((chunk, isLast) => {
169-
chunks.push(Buffer.from(chunk));
170-
contentLength += Buffer.byteLength(chunk);
171-
if (contentLength > this.maxHttpBufferSize) {
172-
this.onError("payload too large");
173-
res.writeStatus("413 Payload Too Large");
174-
res.end();
180+
res.onData((arrayBuffer, isLast) => {
181+
const totalLength = contentLength + arrayBuffer.byteLength;
182+
if (totalLength > contentLengthHeader) {
183+
this.onError("content-length mismatch");
184+
res.close(); // calls onAborted
175185
return;
176186
}
187+
188+
if (!buffer) {
189+
if (isLast) {
190+
onEnd(Buffer.from(arrayBuffer));
191+
return;
192+
}
193+
buffer = Buffer.allocUnsafe(contentLengthHeader);
194+
}
195+
196+
Buffer.from(arrayBuffer).copy(buffer, contentLength);
197+
177198
if (isLast) {
178-
onEnd();
199+
if (totalLength != contentLengthHeader) {
200+
this.onError("content-length mismatch");
201+
res.writeStatus("400 content-length mismatch").end();
202+
cleanup();
203+
return;
204+
}
205+
onEnd(buffer);
206+
return;
179207
}
208+
209+
contentLength = totalLength;
180210
});
181211
}
182212

0 commit comments

Comments
 (0)