@caido-utils/backend 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.js +3 -9
- package/dist/index.d.ts +7 -1
- package/dist/index.js +5 -4
- package/dist/jobs/index.d.ts +3 -0
- package/dist/jobs/index.js +2 -0
- package/dist/jobs/manager.d.ts +18 -0
- package/dist/jobs/manager.js +98 -0
- package/dist/jobs/types.d.ts +10 -0
- package/dist/jobs/types.js +0 -0
- package/dist/jobs/worker-pool.d.ts +14 -0
- package/dist/jobs/worker-pool.js +41 -0
- package/dist/requests/index.d.ts +15 -0
- package/dist/requests/index.js +10 -0
- package/package.json +1 -1
- package/dist/http/helpers/index.d.ts +0 -5
- package/dist/http/helpers/index.js +0 -5
- package/dist/http/helpers/request.d.ts +0 -16
- package/dist/http/helpers/request.js +0 -77
- /package/dist/{http/helpers/headers.d.ts → headers/index.d.ts} +0 -0
- /package/dist/{http/helpers/headers.js → headers/index.js} +0 -0
- /package/dist/http/{helpers/status.d.ts → status/index.d.ts} +0 -0
- /package/dist/http/{helpers/status.js → status/index.js} +0 -0
- /package/dist/{http/helpers/query.d.ts → query/index.d.ts} +0 -0
- /package/dist/{http/helpers/query.js → query/index.js} +0 -0
- /package/dist/{http/helpers/url.d.ts → url/index.d.ts} +0 -0
- /package/dist/{http/helpers/url.js → url/index.js} +0 -0
package/dist/http/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { applyCloseConnection, applyContentLength, checkSignal, HttpClient, RawHttpClient, resolveRedirectUrl, sendRawRequest, waitForUnpause, type BatchCallbacks, type HttpClientOptions, type HttpClientRequest, type HttpClientResponse, type HttpMethod, type RawHttpConfig, type RawHttpSettings, type RawRequest, type RawSendResult, type RedirectPolicy, type Result, type Signal, } from "./client";
|
|
2
|
+
export { getStatusText } from "./status";
|
package/dist/http/index.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
export {
|
|
2
|
-
HttpClient,
|
|
3
|
-
RawHttpClient,
|
|
4
2
|
applyCloseConnection,
|
|
5
3
|
applyContentLength,
|
|
6
4
|
checkSignal,
|
|
5
|
+
HttpClient,
|
|
6
|
+
RawHttpClient,
|
|
7
7
|
resolveRedirectUrl,
|
|
8
8
|
sendRawRequest,
|
|
9
9
|
waitForUnpause
|
|
10
10
|
} from "./client/index.js";
|
|
11
|
-
export {
|
|
12
|
-
HttpRequest,
|
|
13
|
-
filterAuthHeaders,
|
|
14
|
-
getStatusText,
|
|
15
|
-
parseUrl,
|
|
16
|
-
queryRequests
|
|
17
|
-
} from "./helpers/index.js";
|
|
11
|
+
export { getStatusText } from "./status/index.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
export { spawnCommand } from "./process";
|
|
2
2
|
export { sha256 } from "./crypto";
|
|
3
3
|
export { resolveFilterQuery } from "./filter";
|
|
4
|
-
export { HttpClient,
|
|
4
|
+
export { HttpClient, RawHttpClient, applyCloseConnection, applyContentLength, checkSignal, getStatusText, resolveRedirectUrl, sendRawRequest, waitForUnpause, type BatchCallbacks, type HttpClientOptions, type HttpClientRequest, type HttpClientResponse, type HttpMethod, type RawHttpConfig, type RawHttpSettings, type RawRequest, type RawSendResult, type RedirectPolicy, type Result, type Signal, } from "./http";
|
|
5
|
+
export { JobManager, WorkerPool } from "./jobs";
|
|
6
|
+
export type { Job, JobSignal, JobStatus } from "./jobs";
|
|
5
7
|
export { Queue } from "./pool";
|
|
6
8
|
export type { PoolCallbacks, PoolConfig } from "./pool";
|
|
9
|
+
export { filterAuthHeaders } from "./headers";
|
|
7
10
|
export { getProjectId } from "./project";
|
|
11
|
+
export { queryRequests, type QueryRequestsOptions } from "./query";
|
|
12
|
+
export { parseUrl } from "./url";
|
|
13
|
+
export { getRequestResponse, type RequestResponseData } from "./requests";
|
|
8
14
|
export { deleteFile, fileExists, readFile, storeFile } from "./storage";
|
package/dist/index.js
CHANGED
|
@@ -3,19 +3,20 @@ export { sha256 } from "./crypto/index.js";
|
|
|
3
3
|
export { resolveFilterQuery } from "./filter/index.js";
|
|
4
4
|
export {
|
|
5
5
|
HttpClient,
|
|
6
|
-
HttpRequest,
|
|
7
6
|
RawHttpClient,
|
|
8
7
|
applyCloseConnection,
|
|
9
8
|
applyContentLength,
|
|
10
9
|
checkSignal,
|
|
11
|
-
filterAuthHeaders,
|
|
12
10
|
getStatusText,
|
|
13
|
-
parseUrl,
|
|
14
|
-
queryRequests,
|
|
15
11
|
resolveRedirectUrl,
|
|
16
12
|
sendRawRequest,
|
|
17
13
|
waitForUnpause
|
|
18
14
|
} from "./http/index.js";
|
|
15
|
+
export { JobManager, WorkerPool } from "./jobs/index.js";
|
|
19
16
|
export { Queue } from "./pool/index.js";
|
|
17
|
+
export { filterAuthHeaders } from "./headers/index.js";
|
|
20
18
|
export { getProjectId } from "./project/index.js";
|
|
19
|
+
export { queryRequests } from "./query/index.js";
|
|
20
|
+
export { parseUrl } from "./url/index.js";
|
|
21
|
+
export { getRequestResponse } from "./requests/index.js";
|
|
21
22
|
export { deleteFile, fileExists, readFile, storeFile } from "./storage/index.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Job } from "./types";
|
|
2
|
+
export declare class JobManager<TType extends string = string> {
|
|
3
|
+
private jobs;
|
|
4
|
+
private completionListeners;
|
|
5
|
+
createJob(type: TType): Job<TType>;
|
|
6
|
+
getJob(id: string): Job<TType> | undefined;
|
|
7
|
+
getAllJobs(): Job<TType>[];
|
|
8
|
+
getJobsByType(type: TType): Job<TType>[];
|
|
9
|
+
completeJob(id: string): void;
|
|
10
|
+
failJob(id: string): void;
|
|
11
|
+
stopJob(id: string): void;
|
|
12
|
+
pauseJob(id: string): void;
|
|
13
|
+
resumeJob(id: string): void;
|
|
14
|
+
removeJob(id: string): void;
|
|
15
|
+
onJobDone(id: string, callback: () => void): void;
|
|
16
|
+
clearCompleted(): void;
|
|
17
|
+
private notifyDone;
|
|
18
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
let nextId = 1;
|
|
2
|
+
function generateId() {
|
|
3
|
+
return String(nextId++);
|
|
4
|
+
}
|
|
5
|
+
export class JobManager {
|
|
6
|
+
jobs = /* @__PURE__ */ new Map();
|
|
7
|
+
completionListeners = /* @__PURE__ */ new Map();
|
|
8
|
+
createJob(type) {
|
|
9
|
+
const id = generateId();
|
|
10
|
+
const job = {
|
|
11
|
+
id,
|
|
12
|
+
type,
|
|
13
|
+
status: "running",
|
|
14
|
+
signal: { stopped: false, paused: false },
|
|
15
|
+
createdAt: Date.now()
|
|
16
|
+
};
|
|
17
|
+
this.jobs.set(id, job);
|
|
18
|
+
return job;
|
|
19
|
+
}
|
|
20
|
+
getJob(id) {
|
|
21
|
+
return this.jobs.get(id);
|
|
22
|
+
}
|
|
23
|
+
getAllJobs() {
|
|
24
|
+
return [...this.jobs.values()];
|
|
25
|
+
}
|
|
26
|
+
getJobsByType(type) {
|
|
27
|
+
return [...this.jobs.values()].filter((j) => j.type === type);
|
|
28
|
+
}
|
|
29
|
+
completeJob(id) {
|
|
30
|
+
const job = this.jobs.get(id);
|
|
31
|
+
if (job !== void 0 && job.status === "running") {
|
|
32
|
+
job.status = "completed";
|
|
33
|
+
this.notifyDone(id);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
failJob(id) {
|
|
37
|
+
const job = this.jobs.get(id);
|
|
38
|
+
if (job !== void 0) {
|
|
39
|
+
job.status = "error";
|
|
40
|
+
this.notifyDone(id);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
stopJob(id) {
|
|
44
|
+
const job = this.jobs.get(id);
|
|
45
|
+
if (job === void 0) return;
|
|
46
|
+
if (job.status !== "running" && job.status !== "paused") return;
|
|
47
|
+
job.signal.stopped = true;
|
|
48
|
+
job.status = "stopped";
|
|
49
|
+
this.notifyDone(id);
|
|
50
|
+
}
|
|
51
|
+
pauseJob(id) {
|
|
52
|
+
const job = this.jobs.get(id);
|
|
53
|
+
if (job === void 0) return;
|
|
54
|
+
if (job.status !== "running") return;
|
|
55
|
+
job.signal.paused = true;
|
|
56
|
+
job.status = "paused";
|
|
57
|
+
}
|
|
58
|
+
resumeJob(id) {
|
|
59
|
+
const job = this.jobs.get(id);
|
|
60
|
+
if (job === void 0) return;
|
|
61
|
+
if (job.status !== "paused") return;
|
|
62
|
+
job.signal.paused = false;
|
|
63
|
+
job.status = "running";
|
|
64
|
+
}
|
|
65
|
+
removeJob(id) {
|
|
66
|
+
const job = this.jobs.get(id);
|
|
67
|
+
if (job === void 0) return;
|
|
68
|
+
if (job.status === "running" || job.status === "paused") {
|
|
69
|
+
job.signal.stopped = true;
|
|
70
|
+
job.status = "stopped";
|
|
71
|
+
}
|
|
72
|
+
this.jobs.delete(id);
|
|
73
|
+
}
|
|
74
|
+
onJobDone(id, callback) {
|
|
75
|
+
const existing = this.completionListeners.get(id);
|
|
76
|
+
if (existing !== void 0) {
|
|
77
|
+
existing.push(callback);
|
|
78
|
+
} else {
|
|
79
|
+
this.completionListeners.set(id, [callback]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
clearCompleted() {
|
|
83
|
+
for (const [id, job] of this.jobs) {
|
|
84
|
+
if (job.status === "completed" || job.status === "error" || job.status === "stopped") {
|
|
85
|
+
this.jobs.delete(id);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
notifyDone(id) {
|
|
90
|
+
const listeners = this.completionListeners.get(id);
|
|
91
|
+
if (listeners !== void 0) {
|
|
92
|
+
for (const cb of listeners) {
|
|
93
|
+
cb();
|
|
94
|
+
}
|
|
95
|
+
this.completionListeners.delete(id);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Signal } from "../http/client/types";
|
|
2
|
+
export type JobStatus = "running" | "paused" | "completed" | "error" | "stopped";
|
|
3
|
+
export type { Signal as JobSignal };
|
|
4
|
+
export type Job<TType extends string = string> = {
|
|
5
|
+
id: string;
|
|
6
|
+
type: TType;
|
|
7
|
+
status: JobStatus;
|
|
8
|
+
signal: Signal;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JobManager } from "./manager";
|
|
2
|
+
export declare class WorkerPool<TRequest> {
|
|
3
|
+
private readonly maxConcurrency;
|
|
4
|
+
private active;
|
|
5
|
+
private queue;
|
|
6
|
+
private dispatcher;
|
|
7
|
+
private jobManager;
|
|
8
|
+
constructor(maxConcurrency: number, dispatcher: (request: TRequest) => string, jobManager: JobManager);
|
|
9
|
+
submit(request: TRequest): void;
|
|
10
|
+
get pending(): number;
|
|
11
|
+
get running(): number;
|
|
12
|
+
private dispatch;
|
|
13
|
+
private drain;
|
|
14
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class WorkerPool {
|
|
2
|
+
maxConcurrency;
|
|
3
|
+
active = 0;
|
|
4
|
+
queue = [];
|
|
5
|
+
dispatcher;
|
|
6
|
+
jobManager;
|
|
7
|
+
constructor(maxConcurrency, dispatcher, jobManager) {
|
|
8
|
+
this.maxConcurrency = maxConcurrency;
|
|
9
|
+
this.dispatcher = dispatcher;
|
|
10
|
+
this.jobManager = jobManager;
|
|
11
|
+
}
|
|
12
|
+
submit(request) {
|
|
13
|
+
if (this.active < this.maxConcurrency) {
|
|
14
|
+
this.dispatch({ request });
|
|
15
|
+
} else {
|
|
16
|
+
this.queue.push({ request });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
get pending() {
|
|
20
|
+
return this.queue.length;
|
|
21
|
+
}
|
|
22
|
+
get running() {
|
|
23
|
+
return this.active;
|
|
24
|
+
}
|
|
25
|
+
dispatch(task) {
|
|
26
|
+
this.active++;
|
|
27
|
+
const jobId = this.dispatcher(task.request);
|
|
28
|
+
this.jobManager.onJobDone(jobId, () => {
|
|
29
|
+
this.active--;
|
|
30
|
+
this.drain();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
drain() {
|
|
34
|
+
while (this.active < this.maxConcurrency && this.queue.length > 0) {
|
|
35
|
+
const next = this.queue.shift();
|
|
36
|
+
if (next !== void 0) {
|
|
37
|
+
this.dispatch(next);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { SDK } from "caido:plugin";
|
|
2
|
+
export type RequestResponseData = {
|
|
3
|
+
request: string | undefined;
|
|
4
|
+
response: string | undefined;
|
|
5
|
+
url: string | undefined;
|
|
6
|
+
headers: Record<string, string[]> | undefined;
|
|
7
|
+
};
|
|
8
|
+
type RequestResponseOptions = {
|
|
9
|
+
request?: boolean;
|
|
10
|
+
response?: boolean;
|
|
11
|
+
url?: boolean;
|
|
12
|
+
headers?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function getRequestResponse(sdk: SDK<Record<string, never>, Record<string, never>>, caidoId: string, options?: RequestResponseOptions): Promise<RequestResponseData | undefined>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export async function getRequestResponse(sdk, caidoId, options) {
|
|
2
|
+
const result = await sdk.requests.get(caidoId);
|
|
3
|
+
if (result === void 0) return void 0;
|
|
4
|
+
return {
|
|
5
|
+
request: options?.request === false ? void 0 : result.request.getRaw().toText(),
|
|
6
|
+
response: options?.response === false ? void 0 : result.response?.getRaw().toText(),
|
|
7
|
+
url: options?.url === false ? void 0 : result.request.getUrl(),
|
|
8
|
+
headers: options?.headers === false ? void 0 : result.request.getHeaders()
|
|
9
|
+
};
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { SDK } from "caido:plugin";
|
|
2
|
-
export type HttpRequestOptions = {
|
|
3
|
-
url: string;
|
|
4
|
-
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
|
|
5
|
-
headers?: Record<string, string> | Array<{
|
|
6
|
-
name: string;
|
|
7
|
-
value: string;
|
|
8
|
-
}>;
|
|
9
|
-
body?: string;
|
|
10
|
-
};
|
|
11
|
-
export declare class HttpRequest {
|
|
12
|
-
private sdk;
|
|
13
|
-
private maxRedirects;
|
|
14
|
-
constructor(sdk: SDK, maxRedirects?: number);
|
|
15
|
-
send(options: HttpRequestOptions): Promise<any>;
|
|
16
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { RequestSpec } from "caido:utils";
|
|
2
|
-
import parse from "url-parse";
|
|
3
|
-
const DEFAULT_HEADERS = {
|
|
4
|
-
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
|
|
5
|
-
"Sec-Fetch-Site": "same-origin",
|
|
6
|
-
"Sec-Fetch-Mode": "navigate",
|
|
7
|
-
"Sec-Fetch-User": "?1",
|
|
8
|
-
"Sec-Fetch-Dest": "document"
|
|
9
|
-
};
|
|
10
|
-
function normalizeHeaders(headers) {
|
|
11
|
-
if (headers === void 0) {
|
|
12
|
-
return {};
|
|
13
|
-
}
|
|
14
|
-
if (Array.isArray(headers)) {
|
|
15
|
-
return headers.reduce(
|
|
16
|
-
(acc, { name, value }) => {
|
|
17
|
-
acc[name] = value;
|
|
18
|
-
return acc;
|
|
19
|
-
},
|
|
20
|
-
{}
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
return headers;
|
|
24
|
-
}
|
|
25
|
-
function resolveRedirectUrl(currentUrl, location) {
|
|
26
|
-
if (location.startsWith("http://") || location.startsWith("https://")) {
|
|
27
|
-
return location;
|
|
28
|
-
}
|
|
29
|
-
const parsed = parse(currentUrl);
|
|
30
|
-
if (location.startsWith("/")) {
|
|
31
|
-
return `${parsed.protocol}//${parsed.host}${location}`;
|
|
32
|
-
}
|
|
33
|
-
const basePath = parsed.pathname.substring(
|
|
34
|
-
0,
|
|
35
|
-
parsed.pathname.lastIndexOf("/") + 1
|
|
36
|
-
);
|
|
37
|
-
return `${parsed.protocol}//${parsed.host}${basePath}${location}`;
|
|
38
|
-
}
|
|
39
|
-
export class HttpRequest {
|
|
40
|
-
sdk;
|
|
41
|
-
maxRedirects;
|
|
42
|
-
constructor(sdk, maxRedirects = 5) {
|
|
43
|
-
this.sdk = sdk;
|
|
44
|
-
this.maxRedirects = maxRedirects;
|
|
45
|
-
}
|
|
46
|
-
async send(options) {
|
|
47
|
-
let currentUrl = options.url;
|
|
48
|
-
let redirectCount = 0;
|
|
49
|
-
while (redirectCount <= this.maxRedirects) {
|
|
50
|
-
const spec = new RequestSpec(currentUrl);
|
|
51
|
-
if (options.method !== void 0) {
|
|
52
|
-
spec.setMethod(options.method);
|
|
53
|
-
}
|
|
54
|
-
const normalizedHeaders = normalizeHeaders(options.headers);
|
|
55
|
-
const headers = { ...DEFAULT_HEADERS, ...normalizedHeaders };
|
|
56
|
-
for (const [name, value] of Object.entries(headers)) {
|
|
57
|
-
spec.setHeader(name, value);
|
|
58
|
-
}
|
|
59
|
-
if (options.body !== void 0) {
|
|
60
|
-
spec.setBody(options.body);
|
|
61
|
-
}
|
|
62
|
-
const result = await this.sdk.requests.send(spec);
|
|
63
|
-
const statusCode = result.response.getCode();
|
|
64
|
-
if ([301, 302, 303, 307, 308].includes(statusCode)) {
|
|
65
|
-
const locationHeader = result.response.getHeader("Location");
|
|
66
|
-
if (!locationHeader) {
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
currentUrl = resolveRedirectUrl(currentUrl, locationHeader.toString());
|
|
70
|
-
redirectCount++;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
throw new Error(`Too many redirects (max: ${this.maxRedirects})`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|