miniflare 0.0.0-e4fe35cc5 → 0.0.0-e5ebdb143

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.
@@ -10,7 +10,11 @@ var assets_kv_worker_default = {
10
10
  if (entry === void 0)
11
11
  return new Response("Not Found", { status: 404 });
12
12
  let { filePath, contentType } = entry, response = await env[SharedBindings.MAYBE_SERVICE_BLOBS].fetch(
13
- new URL(filePath, "http://placeholder")
13
+ new URL(
14
+ // somewhere in blobservice I think this is being decoded again
15
+ filePath.split("/").map((x) => encodeURIComponent(x)).join("/"),
16
+ "http://placeholder"
17
+ )
14
18
  ), newResponse = new Response(response.body, response);
15
19
  return newResponse.headers.append(
16
20
  "cf-kv-metadata",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/workers/assets/assets-kv.worker.ts"],
4
- "mappings": ";AAAA,SAAS,sBAAsB;AAW/B,IAAO,2BAA8B;AAAA,EACpC,MAAM,MAAM,SAAS,KAAK;AAEzB,QAAI,QAAQ,WAAW,OAAO;AAC7B,UAAM,UAAU,UAAU,QAAQ,OAAO,YAAY;AACrD,aAAO,IAAI,SAAS,SAAS,EAAE,QAAQ,KAAK,YAAY,QAAQ,CAAC;AAAA;AAGlE,QAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE,SAAS,UAAU,CAAC,GACpD,QAAQ,IAAI,mBAAmB,QAAQ;AAC7C,QAAI,UAAU;AACb,aAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAGjD,QAAM,EAAE,UAAU,YAAY,IAAI,OAE5B,WAAW,MADI,IAAI,eAAe,mBAAmB,EACvB;AAAA,MACnC,IAAI,IAAI,UAAU,oBAAoB;AAAA,IACvC,GACM,cAAc,IAAI,SAAS,SAAS,MAAM,QAAQ;AAExD,uBAAY,QAAQ;AAAA,MACnB;AAAA,MACA,oBAAoB;AAAA,IACrB,GACO;AAAA,EACR;AACD;",
4
+ "mappings": ";AAAA,SAAS,sBAAsB;AAW/B,IAAO,2BAA8B;AAAA,EACpC,MAAM,MAAM,SAAS,KAAK;AAEzB,QAAI,QAAQ,WAAW,OAAO;AAC7B,UAAM,UAAU,UAAU,QAAQ,OAAO,YAAY;AACrD,aAAO,IAAI,SAAS,SAAS,EAAE,QAAQ,KAAK,YAAY,QAAQ,CAAC;AAAA;AAGlE,QAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,EAAE,SAAS,UAAU,CAAC,GACpD,QAAQ,IAAI,mBAAmB,QAAQ;AAC7C,QAAI,UAAU;AACb,aAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAGjD,QAAM,EAAE,UAAU,YAAY,IAAI,OAE5B,WAAW,MADI,IAAI,eAAe,mBAAmB,EACvB;AAAA,MACnC,IAAI;AAAA;AAAA,QAEH,SACE,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,mBAAmB,CAAC,CAAC,EAChC,KAAK,GAAG;AAAA,QACV;AAAA,MACD;AAAA,IACD,GACM,cAAc,IAAI,SAAS,SAAS,MAAM,QAAQ;AAExD,uBAAY,QAAQ;AAAA,MACnB;AAAA,MACA,oBAAoB;AAAA,IACrB,GACO;AAAA,EACR;AACD;",
5
5
  "names": []
6
6
  }
@@ -8622,6 +8622,17 @@ var require_index_cjs = __commonJS({
8622
8622
  // ../workers-shared/asset-worker/src/index.ts
8623
8623
  import { WorkerEntrypoint } from "cloudflare:workers";
8624
8624
 
8625
+ // ../workers-shared/utils/performance.ts
8626
+ var PerformanceTimer = class {
8627
+ performanceTimer;
8628
+ constructor(performanceTimer) {
8629
+ this.performanceTimer = performanceTimer;
8630
+ }
8631
+ now() {
8632
+ return this.performanceTimer ? this.performanceTimer.timeOrigin + this.performanceTimer.now() : Date.now();
8633
+ }
8634
+ };
8635
+
8625
8636
  // ../workers-shared/utils/sentry.ts
8626
8637
  var import_toucan_js = __toESM(require_index_cjs());
8627
8638
  function setupSentry(request, context, dsn, clientId, clientSecret) {
@@ -8657,6 +8668,55 @@ function setupSentry(request, context, dsn, clientId, clientSecret) {
8657
8668
  return sentry.setUser({ userAgent, colo }), sentry;
8658
8669
  }
8659
8670
 
8671
+ // ../workers-shared/asset-worker/src/analytics.ts
8672
+ var Analytics = class {
8673
+ data = {};
8674
+ readyAnalytics;
8675
+ constructor(readyAnalytics) {
8676
+ this.readyAnalytics = readyAnalytics;
8677
+ }
8678
+ setData(newData) {
8679
+ this.data = { ...this.data, ...newData };
8680
+ }
8681
+ getData(key) {
8682
+ return this.data[key];
8683
+ }
8684
+ write() {
8685
+ this.readyAnalytics && this.readyAnalytics.logEvent({
8686
+ version: 1,
8687
+ accountId: 0,
8688
+ // TODO: need to plumb through
8689
+ indexId: this.data.hostname?.substring(0, 96),
8690
+ doubles: [
8691
+ this.data.requestTime ?? -1,
8692
+ // double1
8693
+ this.data.coloId ?? -1,
8694
+ // double2
8695
+ this.data.metalId ?? -1,
8696
+ // double3
8697
+ this.data.coloTier ?? -1
8698
+ // double4
8699
+ ],
8700
+ blobs: [
8701
+ this.data.hostname?.substring(0, 256),
8702
+ // blob1 - trim to 256 bytes
8703
+ this.data.userAgent?.substring(0, 256),
8704
+ // blob2 - trim to 256 bytes
8705
+ this.data.htmlHandling,
8706
+ // blob3
8707
+ this.data.notFoundHandling,
8708
+ // blob4
8709
+ this.data.error?.substring(0, 256),
8710
+ // blob5 - trim to 256 bytes
8711
+ this.data.version,
8712
+ // blob6
8713
+ this.data.coloRegion
8714
+ // blob7
8715
+ ]
8716
+ });
8717
+ }
8718
+ };
8719
+
8660
8720
  // ../workers-shared/asset-worker/src/assets-manifest.ts
8661
8721
  var AssetsManifest = class {
8662
8722
  data;
@@ -8716,7 +8776,8 @@ var AssetsManifest = class {
8716
8776
  // ../workers-shared/asset-worker/src/configuration.ts
8717
8777
  var applyConfigurationDefaults = (configuration) => ({
8718
8778
  html_handling: configuration?.html_handling ?? "auto-trailing-slash",
8719
- not_found_handling: configuration?.not_found_handling ?? "none"
8779
+ not_found_handling: configuration?.not_found_handling ?? "none",
8780
+ serve_directly: configuration?.serve_directly ?? !0
8720
8781
  });
8721
8782
 
8722
8783
  // ../workers-shared/asset-worker/src/responses.ts
@@ -8788,18 +8849,25 @@ function isCacheable(request) {
8788
8849
  }
8789
8850
 
8790
8851
  // ../workers-shared/asset-worker/src/handler.ts
8791
- var handleRequest = async (request, configuration, exists, getByETag) => {
8792
- let { pathname, search } = new URL(request.url), intent = await getIntent(pathname, configuration, exists);
8852
+ var handleRequest = async (request, env, configuration, exists, getByETag) => {
8853
+ let { pathname, search } = new URL(request.url), decodedPathname = decodePath(pathname);
8854
+ decodedPathname = decodedPathname.replace(/\/+/g, "/");
8855
+ let intent = await getIntent(decodedPathname, configuration, exists);
8793
8856
  if (!intent)
8794
8857
  return new NotFoundResponse();
8795
8858
  let method = request.method.toUpperCase();
8796
8859
  if (!["GET", "HEAD"].includes(method))
8797
8860
  return new MethodNotAllowedResponse();
8798
- if (intent.redirect)
8799
- return new TemporaryRedirectResponse(intent.redirect + search);
8861
+ let decodedDestination = intent.redirect ?? decodedPathname, encodedDestination = encodePath(decodedDestination);
8862
+ if (encodedDestination !== pathname && intent.asset || intent.redirect)
8863
+ return new TemporaryRedirectResponse(encodedDestination + search);
8800
8864
  if (!intent.asset)
8801
8865
  return new InternalServerErrorResponse(new Error("Unknown action"));
8802
- let asset = await getByETag(intent.asset.eTag), headers = getHeaders(intent.asset.eTag, asset.contentType, request), strongETag = `"${intent.asset.eTag}"`, weakETag = `W/${strongETag}`, ifNoneMatch = request.headers.get("If-None-Match") || "";
8866
+ let asset = await env.JAEGER.enterSpan("getByETag", async (span) => (span.setTags({
8867
+ pathname,
8868
+ eTag: intent.asset.eTag,
8869
+ status: intent.asset.status
8870
+ }), await getByETag(intent.asset.eTag))), headers = getHeaders(intent.asset.eTag, asset.contentType, request), strongETag = `"${intent.asset.eTag}"`, weakETag = `W/${strongETag}`, ifNoneMatch = request.headers.get("If-None-Match") || "";
8803
8871
  if ([weakETag, strongETag].includes(ifNoneMatch))
8804
8872
  return new NotModifiedResponse(null, { headers });
8805
8873
  let body = method === "HEAD" ? null : asset.readableStream;
@@ -8839,7 +8907,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8839
8907
  let redirectResult = null, eTagResult = null, exactETag = await exists(pathname);
8840
8908
  if (pathname.endsWith("/index")) {
8841
8909
  if (exactETag)
8842
- return { asset: { eTag: exactETag, status: 200 }, redirect: null };
8910
+ return {
8911
+ asset: { eTag: exactETag, status: 200 },
8912
+ redirect: null
8913
+ };
8843
8914
  if (redirectResult = await safeRedirect(
8844
8915
  `${pathname}.html`,
8845
8916
  pathname.slice(0, -5),
@@ -8875,7 +8946,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8875
8946
  return redirectResult;
8876
8947
  } else if (pathname.endsWith("/")) {
8877
8948
  if (eTagResult = await exists(`${pathname}index.html`))
8878
- return { asset: { eTag: eTagResult, status: 200 }, redirect: null };
8949
+ return {
8950
+ asset: { eTag: eTagResult, status: 200 },
8951
+ redirect: null
8952
+ };
8879
8953
  if (redirectResult = await safeRedirect(
8880
8954
  `${pathname.slice(0, -1)}.html`,
8881
8955
  pathname.slice(0, -1),
@@ -8902,7 +8976,13 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8902
8976
  ))
8903
8977
  return redirectResult;
8904
8978
  }
8905
- return exactETag ? { asset: { eTag: exactETag, status: 200 }, redirect: null } : (eTagResult = await exists(`${pathname}.html`)) ? { asset: { eTag: eTagResult, status: 200 }, redirect: null } : (redirectResult = await safeRedirect(
8979
+ return exactETag ? {
8980
+ asset: { eTag: exactETag, status: 200 },
8981
+ redirect: null
8982
+ } : (eTagResult = await exists(`${pathname}.html`)) ? {
8983
+ asset: { eTag: eTagResult, status: 200 },
8984
+ redirect: null
8985
+ } : (redirectResult = await safeRedirect(
8906
8986
  `${pathname}/index.html`,
8907
8987
  `${pathname}/`,
8908
8988
  configuration,
@@ -8913,7 +8993,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8913
8993
  let redirectResult = null, eTagResult = null, exactETag = await exists(pathname);
8914
8994
  if (pathname.endsWith("/index")) {
8915
8995
  if (exactETag)
8916
- return { asset: { eTag: exactETag, status: 200 }, redirect: null };
8996
+ return {
8997
+ asset: { eTag: exactETag, status: 200 },
8998
+ redirect: null
8999
+ };
8917
9000
  if (redirectResult = await safeRedirect(
8918
9001
  `${pathname}.html`,
8919
9002
  pathname.slice(0, -5),
@@ -8949,9 +9032,15 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8949
9032
  return redirectResult;
8950
9033
  } else if (pathname.endsWith("/")) {
8951
9034
  if (eTagResult = await exists(`${pathname}index.html`))
8952
- return { asset: { eTag: eTagResult, status: 200 }, redirect: null };
9035
+ return {
9036
+ asset: { eTag: eTagResult, status: 200 },
9037
+ redirect: null
9038
+ };
8953
9039
  if (eTagResult = await exists(`${pathname.slice(0, -1)}.html`))
8954
- return { asset: { eTag: eTagResult, status: 200 }, redirect: null };
9040
+ return {
9041
+ asset: { eTag: eTagResult, status: 200 },
9042
+ redirect: null
9043
+ };
8955
9044
  } else if (pathname.endsWith(".html")) {
8956
9045
  if (redirectResult = await safeRedirect(
8957
9046
  pathname,
@@ -8962,7 +9051,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8962
9051
  ))
8963
9052
  return redirectResult;
8964
9053
  if (exactETag)
8965
- return { asset: { eTag: exactETag, status: 200 }, redirect: null };
9054
+ return {
9055
+ asset: { eTag: exactETag, status: 200 },
9056
+ redirect: null
9057
+ };
8966
9058
  if (redirectResult = await safeRedirect(
8967
9059
  `${pathname.slice(0, -5)}/index.html`,
8968
9060
  `${pathname.slice(0, -5)}/`,
@@ -8972,7 +9064,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8972
9064
  ))
8973
9065
  return redirectResult;
8974
9066
  }
8975
- return exactETag ? { asset: { eTag: exactETag, status: 200 }, redirect: null } : (redirectResult = await safeRedirect(
9067
+ return exactETag ? {
9068
+ asset: { eTag: exactETag, status: 200 },
9069
+ redirect: null
9070
+ } : (redirectResult = await safeRedirect(
8976
9071
  `${pathname}.html`,
8977
9072
  `${pathname}/`,
8978
9073
  configuration,
@@ -8989,7 +9084,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
8989
9084
  let redirectResult = null, eTagResult = null, exactETag = await exists(pathname);
8990
9085
  if (pathname.endsWith("/index")) {
8991
9086
  if (exactETag)
8992
- return { asset: { eTag: exactETag, status: 200 }, redirect: null };
9087
+ return {
9088
+ asset: { eTag: exactETag, status: 200 },
9089
+ redirect: null
9090
+ };
8993
9091
  if (pathname === "/index") {
8994
9092
  if (redirectResult = await safeRedirect(
8995
9093
  "/index.html",
@@ -9037,7 +9135,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
9037
9135
  ))
9038
9136
  return redirectResult;
9039
9137
  if (exactETag)
9040
- return { asset: { eTag: exactETag, status: 200 }, redirect: null };
9138
+ return {
9139
+ asset: { eTag: exactETag, status: 200 },
9140
+ redirect: null
9141
+ };
9041
9142
  if (redirectResult = await safeRedirect(
9042
9143
  `${pathname.slice(0, -11)}.html`,
9043
9144
  pathname.slice(0, -11),
@@ -9050,7 +9151,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
9050
9151
  else if (pathname.endsWith("/"))
9051
9152
  if (pathname === "/") {
9052
9153
  if (eTagResult = await exists("/index.html"))
9053
- return { asset: { eTag: eTagResult, status: 200 }, redirect: null };
9154
+ return {
9155
+ asset: { eTag: eTagResult, status: 200 },
9156
+ redirect: null
9157
+ };
9054
9158
  } else {
9055
9159
  if (redirectResult = await safeRedirect(
9056
9160
  `${pathname.slice(0, -1)}.html`,
@@ -9087,15 +9191,30 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
9087
9191
  ))
9088
9192
  return redirectResult;
9089
9193
  }
9090
- return exactETag ? { asset: { eTag: exactETag, status: 200 }, redirect: null } : (eTagResult = await exists(`${pathname}.html`)) ? { asset: { eTag: eTagResult, status: 200 }, redirect: null } : (eTagResult = await exists(`${pathname}/index.html`)) ? { asset: { eTag: eTagResult, status: 200 }, redirect: null } : notFound(pathname, configuration, exists);
9194
+ return exactETag ? {
9195
+ asset: { eTag: exactETag, status: 200 },
9196
+ redirect: null
9197
+ } : (eTagResult = await exists(`${pathname}.html`)) ? {
9198
+ asset: { eTag: eTagResult, status: 200 },
9199
+ redirect: null
9200
+ } : (eTagResult = await exists(`${pathname}/index.html`)) ? {
9201
+ asset: { eTag: eTagResult, status: 200 },
9202
+ redirect: null
9203
+ } : notFound(pathname, configuration, exists);
9091
9204
  }, htmlHandlingNone = async (pathname, configuration, exists) => {
9092
9205
  let exactETag = await exists(pathname);
9093
- return exactETag ? { asset: { eTag: exactETag, status: 200 }, redirect: null } : notFound(pathname, configuration, exists);
9206
+ return exactETag ? {
9207
+ asset: { eTag: exactETag, status: 200 },
9208
+ redirect: null
9209
+ } : notFound(pathname, configuration, exists);
9094
9210
  }, notFound = async (pathname, configuration, exists) => {
9095
9211
  switch (configuration.not_found_handling) {
9096
9212
  case "single-page-application": {
9097
9213
  let eTag = await exists("/index.html");
9098
- return eTag ? { asset: { eTag, status: 200 }, redirect: null } : null;
9214
+ return eTag ? {
9215
+ asset: { eTag, status: 200 },
9216
+ redirect: null
9217
+ } : null;
9099
9218
  }
9100
9219
  case "404-page": {
9101
9220
  let cwd = pathname;
@@ -9103,7 +9222,10 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
9103
9222
  cwd = cwd.slice(0, cwd.lastIndexOf("/"));
9104
9223
  let eTag = await exists(`${cwd}/404.html`);
9105
9224
  if (eTag)
9106
- return { asset: { eTag, status: 404 }, redirect: null };
9225
+ return {
9226
+ asset: { eTag, status: 404 },
9227
+ redirect: null
9228
+ };
9107
9229
  }
9108
9230
  return null;
9109
9231
  }
@@ -9123,18 +9245,46 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
9123
9245
  };
9124
9246
  }
9125
9247
  return null;
9126
- };
9248
+ }, decodePath = (pathname) => pathname.split("/").map((x) => {
9249
+ try {
9250
+ return decodeURIComponent(x);
9251
+ } catch {
9252
+ return x;
9253
+ }
9254
+ }).join("/"), encodePath = (pathname) => pathname.split("/").map((x) => {
9255
+ try {
9256
+ return encodeURIComponent(x);
9257
+ } catch {
9258
+ return x;
9259
+ }
9260
+ }).join("/");
9127
9261
 
9128
9262
  // ../workers-shared/asset-worker/src/utils/kv.ts
9129
- async function getAssetWithMetadataFromKV(assetsKVNamespace, assetKey, retries = 1) {
9263
+ async function getAssetWithMetadataFromKV(assetsKVNamespace, assetKey, sentry, retries = 1) {
9130
9264
  let attempts = 0;
9131
9265
  for (; attempts <= retries; )
9132
9266
  try {
9133
- return await assetsKVNamespace.getWithMetadata(assetKey, {
9134
- type: "stream",
9135
- cacheTtl: 31536e3
9136
- // 1 year
9137
- });
9267
+ let asset = await assetsKVNamespace.getWithMetadata(
9268
+ assetKey,
9269
+ {
9270
+ type: "stream",
9271
+ cacheTtl: 31536e3
9272
+ // 1 year
9273
+ }
9274
+ );
9275
+ if (asset.value === null) {
9276
+ let retriedAsset = await assetsKVNamespace.getWithMetadata(assetKey, {
9277
+ type: "stream",
9278
+ cacheTtl: 60
9279
+ // Minimum value allowed
9280
+ });
9281
+ return retriedAsset.value !== null && sentry && sentry.captureException(
9282
+ new Error(
9283
+ `Initial request for asset ${assetKey} failed, but subsequent request succeeded.`
9284
+ )
9285
+ ), retriedAsset;
9286
+ }
9287
+ return asset;
9138
9288
  } catch {
9139
9289
  if (attempts >= retries)
9140
9290
  throw new Error(
@@ -9146,38 +9296,105 @@ async function getAssetWithMetadataFromKV(assetsKVNamespace, assetKey, retries =
9146
9296
  }
9147
9297
  }
9148
9298
 
9299
+ // ../workers-shared/asset-worker/src/utils/mocks.ts
9300
+ function mockJaegerBindingSpan() {
9301
+ return {
9302
+ addLogs: () => {
9303
+ },
9304
+ setTags: () => {
9305
+ },
9306
+ end: () => {
9307
+ },
9308
+ isRecording: !0
9309
+ };
9310
+ }
9311
+ function mockJaegerBinding() {
9312
+ return {
9313
+ enterSpan: (_, span, ...args) => span(mockJaegerBindingSpan(), ...args),
9314
+ getSpanContext: () => ({
9315
+ traceId: "test-trace",
9316
+ spanId: "test-span",
9317
+ parentSpanId: "test-parent-span",
9318
+ traceFlags: 0
9319
+ }),
9320
+ runWithSpanContext: (_, callback, ...args) => callback(...args),
9321
+ traceId: "test-trace",
9322
+ spanId: "test-span",
9323
+ parentSpanId: "test-parent-span",
9324
+ cfTraceIdHeader: "test-trace:test-span:0"
9325
+ };
9326
+ }
9327
+
9149
9328
  // ../workers-shared/asset-worker/src/index.ts
9150
9329
  var src_default = class extends WorkerEntrypoint {
9151
9330
  async fetch(request) {
9152
- let sentry;
9331
+ let sentry, analytics = new Analytics(this.env.ANALYTICS), performance = new PerformanceTimer(this.env.UNSAFE_PERFORMANCE), startTimeMs = performance.now();
9153
9332
  try {
9154
- return sentry = setupSentry(
9333
+ this.env.JAEGER || (this.env.JAEGER = mockJaegerBinding()), sentry = setupSentry(
9155
9334
  request,
9156
9335
  this.ctx,
9157
9336
  this.env.SENTRY_DSN,
9158
9337
  this.env.SENTRY_ACCESS_CLIENT_ID,
9159
9338
  this.env.SENTRY_ACCESS_CLIENT_SECRET
9160
- ), handleRequest(
9339
+ );
9340
+ let config = applyConfigurationDefaults(this.env.CONFIG), userAgent = request.headers.get("user-agent") ?? "UA UNKNOWN";
9341
+ if (sentry) {
9342
+ let colo = this.env.COLO_METADATA.coloId;
9343
+ sentry.setTag("colo", this.env.COLO_METADATA.coloId), sentry.setTag("metal", this.env.COLO_METADATA.metalId), sentry.setUser({ userAgent, colo });
9344
+ }
9345
+ let url = new URL(request.url);
9346
+ return this.env.COLO_METADATA && this.env.VERSION_METADATA && analytics.setData({
9347
+ coloId: this.env.COLO_METADATA.coloId,
9348
+ metalId: this.env.COLO_METADATA.metalId,
9349
+ coloTier: this.env.COLO_METADATA.coloTier,
9350
+ coloRegion: this.env.COLO_METADATA.coloRegion,
9351
+ version: this.env.VERSION_METADATA.id,
9352
+ hostname: url.hostname,
9353
+ htmlHandling: config.html_handling,
9354
+ notFoundHandling: config.not_found_handling,
9355
+ userAgent
9356
+ }), this.env.JAEGER.enterSpan("handleRequest", async (span) => (span.setTags({
9357
+ hostname: url.hostname,
9358
+ eyeballPath: url.pathname,
9359
+ env: this.env.ENVIRONMENT,
9360
+ version: this.env.VERSION_METADATA?.id
9361
+ }), handleRequest(
9161
9362
  request,
9162
- applyConfigurationDefaults(this.env.CONFIG),
9363
+ this.env,
9364
+ config,
9163
9365
  this.unstable_exists.bind(this),
9164
9366
  this.unstable_getByETag.bind(this)
9165
- );
9367
+ ))).catch((err) => this.handleError(sentry, analytics, err)).finally(() => this.submitMetrics(analytics, performance, startTimeMs));
9166
9368
  } catch (err) {
9369
+ let errorResponse = this.handleError(sentry, analytics, err);
9370
+ return this.submitMetrics(analytics, performance, startTimeMs), errorResponse;
9371
+ }
9372
+ }
9373
+ handleError(sentry, analytics, err) {
9374
+ try {
9167
9375
  let response = new InternalServerErrorResponse(err);
9168
- return sentry && sentry.captureException(err), response;
9376
+ return sentry && sentry.captureException(err), err instanceof Error && analytics.setData({ error: err.message }), response;
9377
+ } catch (e) {
9378
+ return console.error("Error handling error", e), new InternalServerErrorResponse(e);
9379
+ }
9380
+ }
9381
+ submitMetrics(analytics, performance, startTimeMs) {
9382
+ try {
9383
+ analytics.setData({ requestTime: performance.now() - startTimeMs }), analytics.write();
9384
+ } catch (e) {
9385
+ console.error("Error submitting metrics", e);
9169
9386
  }
9170
9387
  }
9171
9388
  async unstable_canFetch(request) {
9172
- let url = new URL(request.url), method = request.method.toUpperCase(), intent = await getIntent(
9173
- url.pathname,
9389
+ let url = new URL(request.url), decodedPathname = decodePath(url.pathname);
9390
+ return await getIntent(
9391
+ decodedPathname,
9174
9392
  {
9175
9393
  ...applyConfigurationDefaults(this.env.CONFIG),
9176
9394
  not_found_handling: "none"
9177
9395
  },
9178
9396
  this.unstable_exists.bind(this)
9179
- );
9180
- return intent && ["GET", "HEAD"].includes(method) ? new MethodNotAllowedResponse() : intent !== null;
9397
+ ) !== null;
9181
9398
  }
9182
9399
  async unstable_getByETag(eTag) {
9183
9400
  let asset = await getAssetWithMetadataFromKV(