@fedify/relay 2.2.0-dev.606 → 2.2.0-dev.610

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.
@@ -3,7 +3,7 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { exportSpki, getDocumentLoader, isRelayFollowerData } from "./types-Ccc77gS6.js";
6
+ import { exportSpki, getDocumentLoader, isRelayFollowerData } from "./types-BtK4yx3p.js";
7
7
  import { MemoryKvStore, signRequest } from "@fedify/fedify";
8
8
  import { createRelay } from "@fedify/relay";
9
9
  import { Accept, Announce, Create, Delete, Follow, Move, Note, Person, Undo, Update } from "@fedify/vocab";
@@ -3,7 +3,7 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { exportSpki, getDocumentLoader, isRelayFollowerData } from "./types-Ccc77gS6.js";
6
+ import { exportSpki, getDocumentLoader, isRelayFollowerData } from "./types-BtK4yx3p.js";
7
7
  import { MemoryKvStore, signRequest } from "@fedify/fedify";
8
8
  import { createRelay } from "@fedify/relay";
9
9
  import { Create, Delete, Follow, Move, Note, Person, Undo, Update } from "@fedify/vocab";
@@ -25677,7 +25677,7 @@ const preloadedContexts = {
25677
25677
  };
25678
25678
  var contexts_default = preloadedContexts;
25679
25679
  var name = "@fedify/vocab-runtime";
25680
- var version = "2.2.0-dev.606+3a976326";
25680
+ var version = "2.2.0-dev.610+2d418352";
25681
25681
  var license = "MIT";
25682
25682
  var exports$1 = {
25683
25683
  ".": "./src/mod.ts",
@@ -26024,6 +26024,7 @@ const logger = getLogger([
26024
26024
  "runtime",
26025
26025
  "docloader"
26026
26026
  ]);
26027
+ const DEFAULT_MAX_REDIRECTION = 20;
26027
26028
  /**
26028
26029
  * Gets a {@link RemoteDocument} from the given response.
26029
26030
  * @param url The URL of the document to load.
@@ -26139,34 +26140,37 @@ async function getRemoteDocument(url, response, fetch$1) {
26139
26140
  * @returns The document loader.
26140
26141
  * @since 1.3.0
26141
26142
  */
26142
- function getDocumentLoader({ allowPrivateAddress, skipPreloadedContexts, userAgent } = {}) {
26143
+ function getDocumentLoader({ allowPrivateAddress, maxRedirection, skipPreloadedContexts, userAgent } = {}) {
26143
26144
  const tracerProvider = trace.getTracerProvider();
26144
26145
  const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
26145
- async function load(url, options) {
26146
+ const maximumRedirection = maxRedirection ?? DEFAULT_MAX_REDIRECTION;
26147
+ async function load(url, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
26146
26148
  options?.signal?.throwIfAborted();
26147
- if (!skipPreloadedContexts && url in contexts_default) {
26148
- logger.debug("Using preloaded context: {url}.", { url });
26149
+ const currentUrl = new URL(url).href;
26150
+ if (!skipPreloadedContexts && currentUrl in contexts_default) {
26151
+ logger.debug("Using preloaded context: {url}.", { url: currentUrl });
26149
26152
  return {
26150
26153
  contextUrl: null,
26151
- document: contexts_default[url],
26152
- documentUrl: url
26154
+ document: contexts_default[currentUrl],
26155
+ documentUrl: currentUrl
26153
26156
  };
26154
26157
  }
26155
26158
  if (!allowPrivateAddress) try {
26156
- await validatePublicUrl(url);
26159
+ await validatePublicUrl(currentUrl);
26157
26160
  } catch (error) {
26158
26161
  if (error instanceof UrlError) logger.error("Disallowed private URL: {url}", {
26159
- url,
26162
+ url: currentUrl,
26160
26163
  error
26161
26164
  });
26162
26165
  throw error;
26163
26166
  }
26167
+ visited.add(currentUrl);
26164
26168
  return await tracer.startActiveSpan("activitypub.fetch_document", {
26165
26169
  kind: SpanKind.CLIENT,
26166
- attributes: { "url.full": url }
26170
+ attributes: { "url.full": currentUrl }
26167
26171
  }, async (span) => {
26168
26172
  try {
26169
- const request = createActivityPubRequest(url, { userAgent });
26173
+ const request = createActivityPubRequest(currentUrl, { userAgent });
26170
26174
  logRequest(logger, request);
26171
26175
  const response = await fetch(request, {
26172
26176
  redirect: "manual",
@@ -26174,11 +26178,25 @@ function getDocumentLoader({ allowPrivateAddress, skipPreloadedContexts, userAge
26174
26178
  });
26175
26179
  span.setAttribute("http.response.status_code", response.status);
26176
26180
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
26177
- const redirectUrl = response.headers.get("Location");
26181
+ if (redirected >= maximumRedirection) {
26182
+ logger.error("Too many redirections ({redirections}) while fetching document.", {
26183
+ redirections: redirected + 1,
26184
+ url: currentUrl
26185
+ });
26186
+ throw new FetchError(currentUrl, `Too many redirections (${redirected + 1})`);
26187
+ }
26188
+ const redirectUrl = new URL(response.headers.get("Location"), response.url === "" ? currentUrl : response.url).href;
26178
26189
  span.setAttribute("http.redirect.url", redirectUrl);
26179
- return await load(redirectUrl, options);
26190
+ if (visited.has(redirectUrl)) {
26191
+ logger.error("Detected a redirect loop while fetching document: {url} -> {redirectUrl}", {
26192
+ url: currentUrl,
26193
+ redirectUrl
26194
+ });
26195
+ throw new FetchError(currentUrl, `Redirect loop detected: ${redirectUrl}`);
26196
+ }
26197
+ return await load(redirectUrl, options, redirected + 1, visited);
26180
26198
  }
26181
- const result = await getRemoteDocument(url, response, load);
26199
+ const result = await getRemoteDocument(currentUrl, response, load);
26182
26200
  span.setAttribute("docloader.document_url", result.documentUrl);
26183
26201
  if (result.contextUrl != null) span.setAttribute("docloader.context_url", result.contextUrl);
26184
26202
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/relay",
3
- "version": "2.2.0-dev.606+3a976326",
3
+ "version": "2.2.0-dev.610+2d418352",
4
4
  "description": "ActivityPub relay support for Fedify",
5
5
  "keywords": [
6
6
  "Fedify",
@@ -50,14 +50,14 @@
50
50
  "dependencies": {
51
51
  "@js-temporal/polyfill": "^0.5.1",
52
52
  "@logtape/logtape": "^2.0.5",
53
- "@fedify/vocab": "2.2.0-dev.606+3a976326",
54
- "@fedify/fedify": "^2.2.0-dev.606+3a976326"
53
+ "@fedify/fedify": "^2.2.0-dev.610+2d418352",
54
+ "@fedify/vocab": "2.2.0-dev.610+2d418352"
55
55
  },
56
56
  "devDependencies": {
57
57
  "tsdown": "^0.12.9",
58
58
  "typescript": "^5.9.3",
59
59
  "urlpattern-polyfill": "^10.1.0",
60
- "@fedify/vocab-runtime": "^2.2.0-dev.606+3a976326"
60
+ "@fedify/vocab-runtime": "^2.2.0-dev.610+2d418352"
61
61
  },
62
62
  "scripts": {
63
63
  "build:self": "tsdown",