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

`fedify tunnel` command

parent 963265d0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ To be released.
     -  Added `Federation` interface.
     -  Removed `FederationParameters` interface.

 -  Added `fedify tunnel` command to expose a local HTTP server to the public
    internet.

 -  The `fedify init` command now generates a scaffold project with logging
    configuration using the [LogTape] library.

+2 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import { command as inbox } from "./inbox.tsx";
import { command as init } from "./init.ts";
import { recordingSink } from "./log.ts";
import { command as lookup } from "./lookup.ts";
import { command as tunnel } from "./tunnel.ts";

const command = new Command()
  .name("fedify")
@@ -46,6 +47,7 @@ const command = new Command()
  .command("init", init)
  .command("lookup", lookup)
  .command("inbox", inbox)
  .command("tunnel", tunnel)
  .command("completions", new CompletionsCommand())
  .command("help", new HelpCommand().global());

cli/tunnel.ts

0 → 100644
+35 −0
Original line number Diff line number Diff line
import { Command, EnumType } from "@cliffy/command";
import { openTunnel, type Tunnel } from "@hongminhee/localtunnel";
import ora from "ora";

const service = new EnumType(["localhost.run", "serveo.net"]);

export const command = new Command()
  .type("service", service)
  .arguments("<port:integer>")
  .description(
    "Expose a local HTTP server to the public internet using a secure tunnel.\n\n" +
      "Note that the HTTP requests through the tunnel have X-Forwarded-* headers.",
  )
  .option("-s, --service <service:service>", "The localtunnel service to use.")
  .action(async (options, port: number) => {
    const spinner = ora({
      text: "Creating a secure tunnel...",
      discardStdin: false,
    }).start();
    let tunnel: Tunnel;
    try {
      tunnel = await openTunnel({ port, service: options.service });
    } catch {
      spinner.fail("Failed to create a secure tunnel.");
      Deno.exit(1);
    }
    spinner.succeed(
      `Your local server at ${port} is now publicly accessible:\n`,
    );
    console.log(tunnel.url.href);
    console.error("\nPress ^C to close the tunnel.");
    Deno.addSignalListener("SIGINT", async () => {
      await tunnel.close();
    });
  });
+45 −0
Original line number Diff line number Diff line
@@ -640,6 +640,51 @@ about the security implications of exposing the server to the public internet.
> be served via HTTP instead of HTTPS.


`fedify tunnel`: Exposing a local HTTP server to the public internet
--------------------------------------------------------------------

*This command is available since Fedify 0.13.0.*

The `fedify tunnel` command is used to expose a local HTTP server to the public
internet using a secure tunnel.  It is useful when you want to test your
local ActivityPub server with the real-world ActivityPub instances.

To create a tunnel for a local server, for example, running on port 3000,
run the below command:

~~~~ sh
fedify tunnel 3000
~~~~

> [!TIP]
>
> The HTTP requests through the tunnel have the following headers:
>
>  `X-Forwarded-For`
>  :   The IP address of the client.
>
>  `X-Forwarded-Proto`
>  :   The protocol of the client, either `http` or `https`.
>
>  `X-Forwarded-Host`
>  :   The host of the public tunnel server.
>
> If you want to make your local server aware of these headers, you can use
> the [x-forwarded-fetch] package.

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

### `-s`/`--service`: The tunneling service

The `-s`/`--service` option is used to specify the tunneling service to use.
Available services can be found in the output of the `fedify tunnel --help`
command.  For example, to use the serveo.net, run the below command:

~~~~ sh
fedify tunnel --service serveo.net 3000
~~~~


Shell completions
-----------------