Skip to content

Commit

Permalink
cameras: fix fetch timeout bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Mar 28, 2024
1 parent 456faea commit 30f9e35
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 56 deletions.
4 changes: 2 additions & 2 deletions plugins/amcrest/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/amcrest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/amcrest",
"version": "0.0.142",
"version": "0.0.143",
"description": "Amcrest Plugin for Scrypted",
"author": "Scrypted",
"license": "Apache",
Expand Down
4 changes: 2 additions & 2 deletions plugins/hikvision/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/hikvision/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/hikvision",
"version": "0.0.144",
"version": "0.0.145",
"description": "Hikvision Plugin for Scrypted",
"author": "Scrypted",
"license": "Apache",
Expand Down
4 changes: 2 additions & 2 deletions plugins/onvif/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/onvif/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/onvif",
"version": "0.1.11",
"version": "0.1.12",
"description": "ONVIF Camera Plugin for Scrypted",
"author": "Scrypted",
"license": "Apache",
Expand Down
4 changes: 2 additions & 2 deletions plugins/reolink/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/reolink/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/reolink",
"version": "0.0.63",
"version": "0.0.64",
"description": "Reolink Plugin for Scrypted",
"author": "Scrypted",
"license": "Apache",
Expand Down
4 changes: 2 additions & 2 deletions plugins/snapshot/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/snapshot/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/snapshot",
"version": "0.2.40",
"version": "0.2.41",
"description": "Snapshot Plugin for Scrypted",
"scripts": {
"scrypted-setup-project": "scrypted-setup-project",
Expand Down
57 changes: 37 additions & 20 deletions server/src/fetch/http-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,44 +93,61 @@ export async function httpFetch<T extends HttpFetchOptions<Readable>>(options: T
}
}

let controller: AbortController;
let timeout: NodeJS.Timeout;
if (options.timeout) {
controller = new AbortController();
timeout = setTimeout(() => controller.abort(), options.timeout);
}

const request = proto.request(url, {
method: getFetchMethod(options),
rejectUnauthorized: options.rejectUnauthorized,
family: options.family,
headers: nodeHeaders,
signal: controller?.signal || options.signal,
timeout: options.timeout,
});

options.signal?.addEventListener('abort', () => request.destroy(new Error('abort')));
if (controller)
options.signal?.addEventListener('abort', () => controller.abort('abort'));
else
options.signal?.addEventListener('abort', () => request.destroy(new Error('abort')));

if (body)
body.pipe(request);
else
request.end();
const [response] = await once(request, 'response') as [IncomingMessage];

if (!options?.ignoreStatusCode) {
try {
checkStatus(response.statusCode);
}
catch (e) {
readMessageBuffer(response).catch(() => { });
throw e;
try {
const [response] = await once(request, 'response') as [IncomingMessage];

if (!options?.ignoreStatusCode) {
try {
checkStatus(response.statusCode);
}
catch (e) {
readMessageBuffer(response).catch(() => { });
throw e;
}
}
}

const incomingHeaders = new Headers();
for (const [k, v] of Object.entries(response.headers)) {
for (const vv of (typeof v === 'string' ? [v] : v)) {
incomingHeaders.append(k, vv)
const incomingHeaders = new Headers();
for (const [k, v] of Object.entries(response.headers)) {
for (const vv of (typeof v === 'string' ? [v] : v)) {
incomingHeaders.append(k, vv)
}
}
}

return {
statusCode: response.statusCode,
headers: incomingHeaders,
body: await httpFetchParseIncomingMessage(response, options.responseType),
};
return {
statusCode: response.statusCode,
headers: incomingHeaders,
body: await httpFetchParseIncomingMessage(response, options.responseType),
};
}
finally {
clearTimeout(timeout);
}
}

function ensureType<T>(v: T) {
Expand Down
54 changes: 33 additions & 21 deletions server/src/fetch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,30 +124,42 @@ export async function domFetch<T extends HttpFetchOptions<BodyInit>>(options: T)
body = createStringOrBufferBody(headers, body);
}

const { url } = options;
const response = await fetch(url, {
method: getFetchMethod(options),
credentials: options.withCredentials ? 'include' : undefined,
headers,
signal: options.signal || options.timeout ? AbortSignal.timeout(options.timeout) : undefined,
body,
});
let controller: AbortController;
let timeout: NodeJS.Timeout;
if (options.timeout) {
controller = new AbortController();
timeout = setTimeout(() => controller.abort(), options.timeout);
}

if (!options?.ignoreStatusCode) {
try {
checkStatus(response.status);
}
catch (e) {
response.arrayBuffer().catch(() => { });
throw e;
try {
const { url } = options;
const response = await fetch(url, {
method: getFetchMethod(options),
credentials: options.withCredentials ? 'include' : undefined,
headers,
signal: controller?.signal || options.signal,
body,
});

if (!options?.ignoreStatusCode) {
try {
checkStatus(response.status);
}
catch (e) {
response.arrayBuffer().catch(() => { });
throw e;
}
}
}

return {
statusCode: response.status,
headers: response.headers,
body: await domFetchParseIncomingMessage(response, options.responseType),
};
return {
statusCode: response.status,
headers: response.headers,
body: await domFetchParseIncomingMessage(response, options.responseType),
};
}
finally {
clearTimeout(timeout);
}
}

function ensureType<T>(v: T) {
Expand Down

0 comments on commit 30f9e35

Please sign in to comment.