Unverified Commit a0fdeee4 authored by Hong Minhee's avatar Hong Minhee
Browse files

Context.{host,hostname,origin} properties

parent 0b8a9121
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@
    "Misskey",
    "multibase",
    "multikey",
    "multitenancy",
    "nodeinfo",
    "phensley",
    "Pixelfed",
+7 −0
Original line number Diff line number Diff line
@@ -10,6 +10,13 @@ To be released.

 -  Added `ChatMessage` class to Activity Vocabulary API.  [[#85]]

 -  Improved multitenancy (virtual hosting) support.  [[#66]]

     -  Added `Context.hostname` property.
     -  Added `Context.host` property.
     -  Added `Context.origin` property.

[#66]: https://github.com/dahlia/fedify/issues/66
[#85]: https://github.com/dahlia/fedify/issues/85


+17 −0
Original line number Diff line number Diff line
@@ -61,6 +61,23 @@ export async function handler(request: Request) {
~~~~


Getting the base URL
--------------------

*This API is available since Fedify 0.12.0.*

The `Context` object has properties to get the base URL of the current request:

| Property           | Description                             | Value example              |
|--------------------|-----------------------------------------|----------------------------|
| `Context.hostname` | A hostname                              | `"example.com"`            |
| `Context.host`     | A hostname followed by an optional port | `"example.com:88"`         |
| `Context.origin`   | A scheme followed by a host             | `"https://example.com:88"` |

For `RequestContext`, there is an additional property named `~RequestContext.url` that
contains the full URL of the current request.


Building the object URIs
------------------------

+12 −62
Original line number Diff line number Diff line
@@ -281,72 +281,22 @@ incoming HTTP request. See the [next section](#virtual-hosting) for details.
Virtual hosting
---------------

*This API is available since Fedify 0.12.0.*

You may want to support multiple domains on the same server, so-called
*virtual hosts*.  To determine the virtual host of the server based on the
incoming HTTP request, you can set the `TContextData` type to a type that
contains the virtual host information:

~~~~ typescript
import { createFederation } from "@fedify/fedify";

export interface VirtualHost {
  host: string;
}

export function parseVirtualHost(url: URL | string): VirtualHost {
  url = typeof url === "string" ? new URL(url) : url;
  return { host: url.hostname };
}

const federation = createFederation<VirtualHost>({
  // Omitted for brevity; see the related section for details.
});
~~~~

Then, you can pass the virtual host information to the `Federation.fetch()`
as the `contextData` option:

::: code-group

~~~~ typescript [Deno]
Deno.serve(
  request => federation.fetch(request, {
    contextData: parseVirtualHost(request.url), // [!code highlight]
  })
);
~~~~

~~~~ typescript [Node.js]
import { serve } from "@hono/node-server";
incoming HTTP request, you can use `Context.host` that contains
the virtual host information:

serve({
  fetch(request) {
    return federation.fetch(request, {
      contextData: parseVirtualHost(request.url), // [!code highlight]
    });
  }
})
~~~~

~~~~ typescript [Bun]
Bun.serve({
  fetch(request) {
    return federation.fetch(request, {
      contextData: parseVirtualHost(request.url), // [!code highlight]
    });
  }
});
~~~~

:::

Now you can access the virtual host information in the actor dispatcher,
inbox listener, and other callback functions:

~~~~ typescript{2-3}
~~~~ typescript{2}
federation.setActorDispatcher("/@{handle}", (ctx, handle) => {
  const { host } = ctx.data;
  const fullHandle = `${handle}@${host}`;
  const fullHandle = `${handle}@${ctx.host}`;
  // Omitted for brevity
});
~~~~

You can access the virtual host information in the actor dispatcher,
inbox listener, and other callback functions.

See also the [*Getting the base URL* section](./context.md#getting-the-base-url)
in the *Context* document.
+22 −0
Original line number Diff line number Diff line
@@ -12,6 +12,28 @@ import type { SenderKeyPair } from "./send.ts";
 * A context.
 */
export interface Context<TContextData> {
  /**
   * The origin of the federated server, including the scheme (`http://` or
   * `https://`) and the host (e.g., `example.com:8080`).
   * @since 0.12.0
   */
  readonly origin: string;

  /**
   * The host of the federated server, including the hostname
   * (e.g., `example.com`) and the port following a colon (e.g., `:8080`)
   * if it is not the default port for the scheme.
   * @since 0.12.0
   */
  readonly host: string;

  /**
   * The hostname of the federated server (e.g., `example.com`).  This is
   * the same as the host without the port.
   * @since 0.12.0
   */
  readonly hostname: string;

  /**
   * The user-defined data associated with the context.
   */
Loading