mirror of
https://github.com/koush/scrypted.git
synced 2026-05-04 21:30:30 +01:00
http auth: improve status code handling
This commit is contained in:
@@ -91,20 +91,26 @@ export function createAuthFetch<B, M>(
|
||||
const initialResponse = await h({
|
||||
...options,
|
||||
signal: controller.signal,
|
||||
ignoreStatusCode: true,
|
||||
// need to intercept the status code to check for 401.
|
||||
// all other status codes will be handled according to the initial request options.
|
||||
checkStatusCode(statusCode) {
|
||||
// can handle a 401 if an credential is provided.
|
||||
// however, not providing a credential is also valid, and should
|
||||
// fall through to the normal response handling which may be interested
|
||||
// in the 401 response.
|
||||
if (statusCode === 401 && options.credential)
|
||||
return true;
|
||||
if (options?.checkStatusCode === undefined || options?.checkStatusCode) {
|
||||
const checker = typeof options?.checkStatusCode === 'function' ? options.checkStatusCode : checkStatus;
|
||||
return checker(statusCode);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
responseType: 'readable',
|
||||
});
|
||||
|
||||
if (initialResponse.statusCode !== 401 || !options.credential) {
|
||||
if (!options?.ignoreStatusCode) {
|
||||
try {
|
||||
checkStatus(initialResponse.statusCode);
|
||||
}
|
||||
catch (e) {
|
||||
controller.abort('Invalid status code');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
// if it's not a 401, just return the response.
|
||||
if (initialResponse.statusCode !== 401) {
|
||||
return {
|
||||
...initialResponse,
|
||||
body: await parser(initialResponse.body, options.responseType),
|
||||
|
||||
@@ -5,7 +5,7 @@ export async function getDeviceInfo(credential: AuthFetchCredentialState, addres
|
||||
const response = await authHttpFetch({
|
||||
credential,
|
||||
url: `http://${address}/ISAPI/System/deviceInfo`,
|
||||
ignoreStatusCode: true,
|
||||
checkStatusCode: false,
|
||||
responseType: 'text',
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ export class TapoAPI {
|
||||
const response = await authHttpFetch({
|
||||
credential: undefined,
|
||||
url: url,
|
||||
ignoreStatusCode: true,
|
||||
checkStatusCode: false,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/mixed; boundary=--client-stream-boundary--',
|
||||
|
||||
@@ -122,9 +122,12 @@ export async function httpFetch<T extends HttpFetchOptions<Readable>>(options: T
|
||||
try {
|
||||
const [response] = await once(request, 'response') as [IncomingMessage];
|
||||
|
||||
if (!options?.ignoreStatusCode) {
|
||||
|
||||
if (options?.checkStatusCode === undefined || options?.checkStatusCode) {
|
||||
try {
|
||||
checkStatus(response.statusCode);
|
||||
const checker = typeof options?.checkStatusCode === 'function' ? options.checkStatusCode : checkStatus;
|
||||
if (!checker(response.statusCode))
|
||||
throw new Error(`http response statusCode ${response.statusCode}`);
|
||||
}
|
||||
catch (e) {
|
||||
readMessageBuffer(response).catch(() => { });
|
||||
|
||||
@@ -7,7 +7,10 @@ export interface HttpFetchOptionsBase<B> {
|
||||
signal?: AbortSignal,
|
||||
timeout?: number;
|
||||
rejectUnauthorized?: boolean;
|
||||
ignoreStatusCode?: boolean;
|
||||
/**
|
||||
* Checks the status code. Defaults to true.
|
||||
*/
|
||||
checkStatusCode?: boolean | ((statusCode: number) => boolean);
|
||||
body?: B | string | ArrayBufferView | any;
|
||||
withCredentials?: boolean;
|
||||
}
|
||||
@@ -40,6 +43,7 @@ export function fetchStatusCodeOk(statusCode: number) {
|
||||
export function checkStatus(statusCode: number) {
|
||||
if (!fetchStatusCodeOk(statusCode))
|
||||
throw new Error(`http response statusCode ${statusCode}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
export function getFetchMethod(options: HttpFetchOptions<any>) {
|
||||
@@ -190,9 +194,11 @@ export async function domFetch<T extends HttpFetchOptions<BodyInit>>(options: T)
|
||||
body,
|
||||
});
|
||||
|
||||
if (!options?.ignoreStatusCode) {
|
||||
if (options?.checkStatusCode === undefined || options?.checkStatusCode) {
|
||||
try {
|
||||
checkStatus(response.status);
|
||||
const checker = typeof options?.checkStatusCode === 'function' ? options.checkStatusCode : checkStatus;
|
||||
if (!checker(response.status))
|
||||
throw new Error(`http response statusCode ${response.status}`);
|
||||
}
|
||||
catch (e) {
|
||||
response.arrayBuffer().catch(() => { });
|
||||
|
||||
Reference in New Issue
Block a user