From dc4ba250120ff2147dcc06a458a28a7ef680ba42 Mon Sep 17 00:00:00 2001 From: Jamal Carvalho Date: Thu, 26 Nov 2020 10:49:53 -0500 Subject: [PATCH] support custom host in serve api --- cmd/esbuild/main.go | 2 +- cmd/esbuild/service.go | 4 ++++ lib/common.ts | 3 +++ lib/stdio_protocol.ts | 2 ++ lib/types.ts | 2 ++ pkg/api/api.go | 2 ++ pkg/api/api_impl.go | 6 +++++- pkg/cli/cli_impl.go | 14 ++++++++++---- 8 files changed, 29 insertions(+), 6 deletions(-) diff --git a/cmd/esbuild/main.go b/cmd/esbuild/main.go index 7966059ed3..54aa4ef57d 100644 --- a/cmd/esbuild/main.go +++ b/cmd/esbuild/main.go @@ -37,7 +37,7 @@ Options: --outdir=... The output directory (for multiple entry points) --outfile=... The output file (for one entry point) --platform=... Platform target (browser | node, default browser) - --serve=... Start a local HTTP server on this port for outputs + --serve=... Start a local HTTP server on this [host]:port for outputs --sourcemap Emit a source map --splitting Enable code splitting (currently only for esm) --target=... Environment target (e.g. es2017, chrome58, firefox57, diff --git a/cmd/esbuild/service.go b/cmd/esbuild/service.go index 3b025f3ff7..21fd13697d 100644 --- a/cmd/esbuild/service.go +++ b/cmd/esbuild/service.go @@ -508,6 +508,9 @@ func (service *serviceType) handleBuildRequest(id uint32, request map[string]int if port, ok := serve["port"]; ok { serveOptions.Port = uint16(port.(int)) } + if host, ok := serve["host"]; ok { + serveOptions.Host = host.(string) + } serveOptions.OnRequest = func(args api.ServeOnRequestArgs) { service.sendRequest(map[string]interface{}{ "command": "serve-request", @@ -527,6 +530,7 @@ func (service *serviceType) handleBuildRequest(id uint32, request map[string]int } response := map[string]interface{}{ "port": int(result.Port), + "host": result.Host, } // Asynchronously wait for the server to stop, then fulfil the "wait" promise diff --git a/lib/common.ts b/lib/common.ts index 40577e8705..1cba0a4815 100644 --- a/lib/common.ts +++ b/lib/common.ts @@ -565,6 +565,7 @@ export function createChannel(streamIn: StreamIn): StreamOut { let buildServeData = (options: types.ServeOptions, request: protocol.BuildRequest): ServeData => { let keys: OptionKeys = {}; let port = getFlag(options, keys, 'port', mustBeInteger); + let host = getFlag(options, keys, 'host', mustBeString); let onRequest = getFlag(options, keys, 'onRequest', mustBeFunction); let serveID = nextServeID++; let onWait: ServeCallbacks['onWait']; @@ -578,6 +579,7 @@ export function createChannel(streamIn: StreamIn): StreamOut { request.serve = { serveID }; checkForInvalidFlags(options, keys); if (port !== void 0) request.serve.port = port; + if (host !== void 0) request.serve.host = host; serveCallbacks.set(serveID, { onRequest, onWait: onWait!, @@ -653,6 +655,7 @@ export function createChannel(streamIn: StreamIn): StreamOut { let serveResponse = response as any as protocol.ServeResponse; let result: types.ServeResult = { port: serveResponse.port, + host: serveResponse.host, wait: serve.wait, stop: serve.stop, }; diff --git a/lib/stdio_protocol.ts b/lib/stdio_protocol.ts index 5b88e7b529..cc0b19a69f 100644 --- a/lib/stdio_protocol.ts +++ b/lib/stdio_protocol.ts @@ -21,10 +21,12 @@ export interface BuildRequest { export interface ServeRequest { serveID: number; port?: number; + host?: string; } export interface ServeResponse { port: number; + host: string; } export interface ServeStopRequest { diff --git a/lib/types.ts b/lib/types.ts index 4a070a402f..358dd9b0ea 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -101,6 +101,7 @@ export interface BuildFailure extends Error { export interface ServeOptions { port?: number; + host?: string; onRequest?: (args: ServeOnRequestArgs) => void; } @@ -114,6 +115,7 @@ export interface ServeOnRequestArgs { export interface ServeResult { port: number; + host: string; wait: Promise; stop: () => void; } diff --git a/pkg/api/api.go b/pkg/api/api.go index 1a2817283a..34087a31dd 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -325,6 +325,7 @@ func Transform(input string, options TransformOptions) TransformResult { type ServeOptions struct { Port uint16 + Host string OnRequest func(ServeOnRequestArgs) } @@ -338,6 +339,7 @@ type ServeOnRequestArgs struct { type ServeResult struct { Port uint16 + Host string Wait func() error Stop func() } diff --git a/pkg/api/api_impl.go b/pkg/api/api_impl.go index 0781992bb5..90da3999e5 100644 --- a/pkg/api/api_impl.go +++ b/pkg/api/api_impl.go @@ -1151,6 +1151,9 @@ func serveImpl(serveOptions ServeOptions, buildOptions BuildOptions) (ServeResul // Pick the port var listener net.Listener host := "127.0.0.1" + if serveOptions.Host != "" { + host = serveOptions.Host + } if serveOptions.Port == 0 { // Default to picking a "800X" port for port := 8000; port <= 8009; port++ { @@ -1174,9 +1177,10 @@ func serveImpl(serveOptions ServeOptions, buildOptions BuildOptions) (ServeResul // Extract the real port in case we passed a port of "0" var result ServeResult - if _, text, err := net.SplitHostPort(addr); err == nil { + if host, text, err := net.SplitHostPort(addr); err == nil { if port, err := strconv.ParseInt(text, 10, 32); err == nil { result.Port = uint16(port) + result.Host = host } } diff --git a/pkg/cli/cli_impl.go b/pkg/cli/cli_impl.go index e96d5345e8..3252e60917 100644 --- a/pkg/cli/cli_impl.go +++ b/pkg/cli/cli_impl.go @@ -3,6 +3,7 @@ package cli import ( "fmt" "io/ioutil" + "net" "os" "sort" "strconv" @@ -502,7 +503,7 @@ func runImpl(osArgs []string) int { // Special-case running a server for i, arg := range osArgs { if arg == "--serve" { - arg = "--serve=0" + arg = "--serve=:0" } if strings.HasPrefix(arg, "--serve=") { serve := arg[len("--serve="):] @@ -575,7 +576,11 @@ func runImpl(osArgs []string) int { return 0 } -func serveImpl(portText string, osArgs []string) error { +func serveImpl(serveText string, osArgs []string) error { + host, portText, err := net.SplitHostPort(serveText) + if err != nil { + return err + } port, err := strconv.ParseInt(portText, 10, 32) if err != nil { return err @@ -597,6 +602,7 @@ func serveImpl(portText string, osArgs []string) error { serveOptions := api.ServeOptions{ Port: uint16(port), + Host: host, OnRequest: func(args api.ServeOnRequestArgs) { logger.PrintTextToStderr(logger.LevelInfo, osArgs, func(colors logger.Colors) string { statusColor := colors.Red @@ -617,8 +623,8 @@ func serveImpl(portText string, osArgs []string) error { // Show what actually got bound if the port was 0 logger.PrintTextToStderr(logger.LevelInfo, osArgs, func(colors logger.Colors) string { - return fmt.Sprintf("%s\n > %shttp://localhost:%d/%s\n\n", - colors.Default, colors.Underline, result.Port, colors.Default) + return fmt.Sprintf("%s\n > %shttp://%s:%d/%s\n\n", + colors.Default, colors.Underline, result.Host, result.Port, colors.Default) }) return result.Wait() }