Unverified Commit 95c4a49c authored by Hong Minhee's avatar Hong Minhee
Browse files

Deprecate treatHttps

parent 72faca94
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -8,6 +8,12 @@ Version 0.10.0

To be released.

 -  Deprecated `treatHttps` option in `FederationParameters` interface.
    Instead, use the [x-forwarded-fetch] library to recognize the
    `X-Forwarded-Host` and `X-Forwarded-Proto` headers.

[x-forwarded-fetch]: https://github.com/dahlia/x-forwarded-fetch


Version 0.9.0
-------------
+69 −12
Original line number Diff line number Diff line
@@ -133,23 +133,80 @@ load remote JSON-LD contexts. The type of the function is the same as the
[*Document loader vs. context loader*
section](./context.md#document-loader-vs-context-loader)).

### `treatHttps`

Whether to treat HTTP requests as HTTPS.  This affects how URLs are generated
as well.  According to the [*Object Identifiers* section][1] in the ActivityPub
specification, the public dereferenceable URIs should use HTTPS URIs, so this
option is useful for testing and local development, which is normally done
over HTTP.
How the `Federation` object recognizes the domain name
------------------------------------------------------

However, it should be disabled in production.  Turned off by default.
The `Federation` object recognizes the domain name of the server by
the [`Host`] header of the incoming HTTP requests.  The `Host` header is
a standard HTTP header that contains the domain name of the server.

However, the `Host` header is not always reliable because it can be
bypassed by a reverse proxy or a load balancer.  If you use a reverse
proxy or a load balancer, you should configure it to pass the original
`Host` header to the server.

Or you can make the `Federation` object recognize the domain name by looking
at the [`X-Forwarded-Host`] header instead of the `Host` header using
the [x-forwarded-fetch] middleware.  To use the `x-forwarded-fetch` middleware,
install the package:

::: code-group

~~~~ sh [Deno]
deno add @hongminhee/x-forwarded-fetch
~~~~

~~~~ sh [Node.js]
npm install x-forwarded-fetch
~~~~

~~~~ sh [Bun]
bun add x-forwarded-fetch
~~~~

:::

Then, import the package and place the `behindProxy()` middleware in front of
the `Federation.fetch()` method:

::: code-group

~~~~ typescript{1,4} [Deno]
import { behindProxy } from "@hongminhee/x-forwarded-fetch";

Deno.serve(
  behindProxy(request => federation.fetch(request, { contextData: undefined }))
);
~~~~

~~~~ typescript{2,5} [Node.js]
import { serve } from "@hono/node-server";
import { behindProxy } from "x-forwarded-fetch";

serve({
  fetch: behindProxy((request) => federation.fetch(request, { contextData: undefined }),
});
~~~~

~~~~ typescript{1,4} [Bun]
import { behindProxy } from "x-forwarded-fetch";

Bun.serve({
  fetch: behindProxy((request) => federation.fetch(request, { contextData: undefined })),
});
~~~~

:::

> [!TIP]
> This option is usually used together with tunneling services like [ngrok]
> in testing and local development.  See also the [*Exposing a local server
> to the public* section](./test.md#exposing-a-local-server-to-the-public).
> When your `Federation` object is integrated with a web framework, you should
> place the `behindProxy()` middleware in front of the framework's `fetch()`
> method, not the `Federation.fetch()` method.

[1]: https://www.w3.org/TR/activitypub/#obj-id
[ngrok]: https://ngrok.com/
[`Host`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
[`X-Forwarded-Host`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
[x-forwarded-fetch]: https://github.com/dahlia/x-forwarded-fetch


Integrating with web frameworks
+7 −12
Original line number Diff line number Diff line
@@ -41,23 +41,18 @@ that help you do that:
> cannot recognize if it is behind a reverse proxy, and if the reverse proxy
> is in HTTPS.  So the federation server will generate HTTP URLs in the
> ActivityPub messages, which cause interoperability issues.[^1]  In this case,
> you can use the [`treatHttps` option](./federation.md#treathttps) in
> the `new Federation()` constructor to force the federation server to generate
> HTTPS URLs:
> you can use the [x-forwarded-fetch] middleware in front of
> the `Federation.fetch()` method so that the `Federation` object recognizes
> the proper domain name and protocol of the incoming HTTP requests.
>
> ~~~~ typescript
> import { Federation } from "@fedify/fedify";
>
> const federation = new Federation({
>   // ...
>   treatHttps: true,   // [!code highlight]
> });
> ~~~~

> For more information, see [*How the <code>Federation</code> object recognizes
> the domain name* section](./federation.md#how-the-federation-object-recognizes-the-domain-name)
> in the *Federation* document.

[^1]: According to the [*Object Identifiers* section][1] in the ActivityPub
      specification, the public dereferenceable URIs should use HTTPS URIs.

[x-forwarded-fetch]: https://github.com/dahlia/x-forwarded-fetch
[1]: https://www.w3.org/TR/activitypub/#obj-id

<!-- cSpell: ignore serveo tailscale -->
+52 −6
Original line number Diff line number Diff line
@@ -545,15 +545,60 @@ a public URL that you can use to access your server from the internet.
However, since ngrok is a reverse proxy between the public internet and your
server, the server still is not aware the fact that it is exposed to the public
internet through HTTPS.  In order to make the server aware of it, you need to
set the `treatHttps` property to `true` in the `Federation` object:
place a [x-forwarded-fetch] middleware in front of the `Federation`.

~~~~ typescript
const federation = new Federation<void>({
  kv: new MemoryKvStore(),
  treatHttps: true,  // Treat HTTP requests as HTTPS // [!code highlight]
To do this, you need to install the package:

::: code-group

~~~~ sh [Deno]
deno add @hongminhee/x-forwarded-fetch
~~~~

~~~~ sh [Node.js]
npm install x-forwarded-fetch
~~~~

~~~~ sh [Bun]
bun add x-forwarded-fetch
~~~~

:::

Then, import the package and place the `behindProxy()` middleware in front of
the `Federation.fetch()` method:

::: code-group

~~~~ typescript{1,4} [Deno]
import { behindProxy } from "@hongminhee/x-forwarded-fetch";

Deno.serve(
  behindProxy(request => federation.fetch(request, { contextData: undefined }))
);
~~~~

~~~~ typescript{2,6} [Node.js]
import { serve } from "@hono/node-server";
import { behindProxy } from "x-forwarded-fetch";

serve({
  port: 8000,
  fetch: behindProxy((request) => federation.fetch(request, { contextData: undefined }),
});
~~~~

~~~~ typescript{1,5} [Bun]
import { behindProxy } from "x-forwarded-fetch";

Bun.serve({
  port: 8000,
  fetch: behindProxy((request) => federation.fetch(request, { contextData: undefined })),
});
~~~~

:::

To restart the server, you need to stop the server by pressing <kbd>^C</kbd> and
then run the server again:

@@ -574,7 +619,7 @@ bun server.ts
:::

Let's query the actor *me* again, but this time with the public URL (change
the domain name to the one ngrok provides you):
the domain name to the one ngrok provides you):[^3]

~~~~ sh
curl https://79e8-125-129-0-52.ngrok-free.app/.well-known/webfinger?resource=acct:me@7d2d-125-129-0-52.ngrok-free.app
@@ -592,6 +637,7 @@ ActivityPub servers because our server doesn't accept follow requests yet.

[ngrok]: https://ngrok.com/
[ngrok quickstart]: https://ngrok.com/docs/getting-started/
[x-forwarded-fetch]: https://github.com/dahlia/x-forwarded-fetch


Inbox listener
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ Usage
Start the project with the following command:

~~~~ sh
deno task start
deno task preview
~~~~

The above command will start the server on port 8000.  You can access the blog
Loading