@smithers-orchestrator/server 0.16.9 → 0.18.0

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/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createServer, IncomingMessage, ServerResponse } from "node:http";
1
+ import { createServer } from "node:http";
2
2
  import { readFile, writeFile } from "node:fs/promises";
3
3
  import { createHash } from "node:crypto";
4
4
  import { pathToFileURL } from "node:url";
@@ -20,6 +20,7 @@ import { errorToJson } from "@smithers-orchestrator/errors/errorToJson";
20
20
  import { SmithersError } from "@smithers-orchestrator/errors/SmithersError";
21
21
  import { assertMaxBytes, assertMaxJsonDepth } from "@smithers-orchestrator/db/input-bounds";
22
22
  import { prometheusContentType, renderPrometheusMetrics, } from "@smithers-orchestrator/observability";
23
+ /** @typedef {import("node:http").ServerResponse} ServerResponse */
23
24
  /** @typedef {import("./ServerOptions.js").ServerOptions} ServerOptions */
24
25
 
25
26
  // Re-export the full public surface so the tsup-bundled `src/index.d.ts`
@@ -44,6 +45,8 @@ const DEFAULT_MAX_BODY_BYTES = 1_048_576;
44
45
  const DEFAULT_MAX_BODY_JSON_DEPTH = 32;
45
46
  const DEFAULT_SSE_HEARTBEAT_MS = 10_000;
46
47
  const COMPLETED_RUN_RETENTION_MS = 60_000;
48
+ const DEFAULT_HEADERS_TIMEOUT = 30_000;
49
+ const DEFAULT_REQUEST_TIMEOUT = 60_000;
47
50
  class HttpError extends Error {
48
51
  status;
49
52
  code;
@@ -355,7 +358,7 @@ function assertAuth(req, authToken) {
355
358
  req.headers["Authorization"] ??
356
359
  req.headers["x-smithers-key"];
357
360
  const value = Array.isArray(header) ? header[0] : header;
358
- const token = value?.startsWith("Bearer ") ? value.slice(7) : value;
361
+ const token = value?.slice(0, 7).toLowerCase() === "bearer " ? value.slice(7) : value;
359
362
  if (!token || token !== authToken) {
360
363
  throw new HttpError(401, "UNAUTHORIZED", "Missing or invalid authorization token");
361
364
  }
@@ -645,6 +648,8 @@ function startServerInternal(opts = {}) {
645
648
  const maxBodyBytes = opts.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
646
649
  const rootDir = opts.rootDir ? resolve(opts.rootDir) : undefined;
647
650
  const allowNetwork = Boolean(opts.allowNetwork);
651
+ const headersTimeout = opts.headersTimeout ?? DEFAULT_HEADERS_TIMEOUT;
652
+ const requestTimeout = opts.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT;
648
653
  if (serverDb) {
649
654
  ensureSmithersTables(serverDb);
650
655
  }
@@ -1206,6 +1211,8 @@ function startServerInternal(opts = {}) {
1206
1211
  await recordHttpRequestMetricsSafely(requestMethod, requestPathname, res.statusCode || 500, performance.now() - requestStart);
1207
1212
  }
1208
1213
  });
1214
+ server.headersTimeout = headersTimeout;
1215
+ server.requestTimeout = requestTimeout;
1209
1216
  server.on("close", () => {
1210
1217
  logInfo("stopping smithers server", {
1211
1218
  activeRuns: runs.size,
package/src/serve.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Hono } from "hono";
2
2
  import { streamSSE } from "hono/streaming";
3
3
  import { Effect, Metric } from "effect";
4
- import { SmithersDb } from "@smithers-orchestrator/db/adapter";
5
4
  import { approveNode, denyNode } from "@smithers-orchestrator/engine/approvals";
6
5
  import { isRunHeartbeatFresh } from "@smithers-orchestrator/engine";
7
6
  import { nowMs } from "@smithers-orchestrator/scheduler/nowMs";
@@ -119,7 +118,7 @@ export function createServeApp(opts) {
119
118
  return next();
120
119
  const authHeader = c.req.header("authorization");
121
120
  if (authHeader) {
122
- const token = authHeader.startsWith("Bearer ")
121
+ const token = authHeader.slice(0, 7).toLowerCase() === "bearer "
123
122
  ? authHeader.slice(7)
124
123
  : authHeader;
125
124
  if (token === authToken)