Skip to content

Commit 8e361d5

Browse files
check if writable end in both fileResponse as well as response end
1 parent 037b8a3 commit 8e361d5

2 files changed

Lines changed: 18 additions & 6 deletions

File tree

src/handlers/file_handler.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export class FileHandler {
119119
});
120120
}
121121

122-
protected sendFileAsResponse(filePath: string, mimeType: MIME_TYPE) {
122+
private sendFileAsResponse_(filePath: string, mimeType: MIME_TYPE) {
123123
return promise((res, rej) => {
124124
const handler = this.option;
125125
const readStream = Fs.createReadStream(filePath);
@@ -136,12 +136,16 @@ export class FileHandler {
136136
}
137137

138138
send(filePathInfo: IFileResultInfo) {
139+
const response = this.option.response;
140+
if (response.writableEnded || response.headersSent) {
141+
console.warn("FileHandler.send called after response was already sent/ended");
142+
return;
143+
}
139144
const { fileInfo, filePath } = filePathInfo;
140145
const lastModified = fileInfo.mtime.toUTCString();
141146
const eTagValue = etag(fileInfo, {
142147
weak: this.option.global.eTag.type === ETAG_TYPE.Weak
143148
});
144-
const response = this.option.response;
145149
response.setHeader('Etag', eTagValue);
146150
const extension = path.parse(filePath).ext;
147151
const contentType = response.getHeader(CONTENT_TYPE);
@@ -154,7 +158,7 @@ export class FileHandler {
154158
}
155159
else {
156160
response.setHeader('Last-Modified', lastModified);
157-
return this.sendFileAsResponse(filePath, mimeType);
161+
return this.sendFileAsResponse_(filePath, mimeType);
158162
}
159163
}
160164

src/handlers/request_handler_helper.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export class RequestHandlerHelper {
7777
// which was not supposed to be done
7878
// then you don't follow regular rules but just throw them from anywhere
7979
onErrorOccured(error) {
80+
if (this.response.headersSent) {
81+
console.log("Response already sent, cannot send error response");
82+
return;
83+
}
8084
if (typeof error === 'string') {
8185
error = {
8286
message: error
@@ -162,14 +166,18 @@ export class RequestHandlerHelper {
162166
}
163167
) : "";
164168

165-
if (this.response.headersSent) {
169+
const response = this.response;
170+
171+
// double check to avoid multiple end calls
172+
// placement is before writing head to avoid writing head multiple times
173+
if (response.headersSent || response.writableEnded) {
166174
console.trace("Request is finished, but triggered again");
167175
return;
168176
}
169177

170-
this.response.writeHead(this.controllerResult.statusCode || HTTP_STATUS_CODE.Ok,
178+
response.writeHead(this.controllerResult.statusCode || HTTP_STATUS_CODE.Ok,
171179
{ [CONTENT_TYPE]: negotiateMimeType });
172-
this.response.end(data);
180+
response.end(data);
173181
}
174182

175183
private async handleCustomResult_() {

0 commit comments

Comments
 (0)