Skip to content

Commit

Permalink
Add command line arguments --bind and --port to set host and port, de…
Browse files Browse the repository at this point in the history
…fault is localhost and 7070.
  • Loading branch information
tiezhuli001 committed Jun 5, 2024
1 parent 7fa581a commit b2c3ae1
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 34 deletions.
2 changes: 1 addition & 1 deletion cmd/go-tool-debug-compile/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func dlvExecListen(dir string, env []string, compilerBinary string, args []strin
}
break
}
return netutil.ServePort(2345, true, 500*time.Millisecond, func(port int) {
return netutil.ServePort("localhost", 2345, true, 500*time.Millisecond, func(port int) {
prompt := debug.FormatDlvPromptOptions(port, &debug.FormatDlvOptions{
VscodeExtra: vscodeExtra,
})
Expand Down
4 changes: 2 additions & 2 deletions cmd/xgo/runtime_gen/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

const VERSION = "1.0.39"
const REVISION = "e6ba142b8a4c344bfd9e009090d1666635e1c9e5+1"
const NUMBER = 261
const REVISION = "7fa581a5041d839180502f1d2377ea043803bde7+1"
const NUMBER = 262

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down
2 changes: 1 addition & 1 deletion cmd/xgo/test-explorer/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func debug(ctx *RunContext) error {
if err != nil {
return err
}
err = netutil.ServePort(2345, true, 500*time.Millisecond, func(port int) {
err = netutil.ServePort("localhost", 2345, true, 500*time.Millisecond, func(port int) {
fmt.Fprintln(stderr, debug_util.FormatDlvPrompt(port))
}, func(port int) error {
// dlv exec --api-version=2 --listen=localhost:2345 --accept-multiclient --headless ./debug.bin
Expand Down
26 changes: 23 additions & 3 deletions cmd/xgo/test-explorer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ type Options struct {
Flags []string

Config string
Port string
Bind string
}

func Main(args []string, opts *Options) error {
Expand Down Expand Up @@ -93,6 +95,23 @@ func Main(args []string, opts *Options) error {
if ok {
continue
}
if arg == "--port" {
if i+1 >= n {
return fmt.Errorf("%s requires value", arg)
}
opts.Port = args[i+1]
i++
continue
}
if arg == "--bind" {
if i+1 >= n {
return fmt.Errorf("%s requires value", arg)
}
opts.Bind = args[i+1]
i++
continue
}

if !strings.HasPrefix(arg, "-") {
remainArgs = append(remainArgs, arg)
continue
Expand Down Expand Up @@ -281,9 +300,10 @@ func handle(opts *Options) error {
setupTestHandler(server, opts.ProjectDir, getTestConfig)
setupOpenHandler(server)

return netutil.ServePortHTTP(server, 7070, true, 500*time.Millisecond, func(port int) {
url = fmt.Sprintf("http://localhost:%d", port)
fmt.Printf("Server listen at %s\n", url)
host, port := netutil.GetHostAndIP(opts.Bind, opts.Port)
autoIncrPort := true
return netutil.ServePortHTTP(server, host, port, autoIncrPort, 500*time.Millisecond, func(port int) {
url := netutil.BuildAndDisplayURL(host, port)
openURL(url)
})
}
Expand Down
42 changes: 24 additions & 18 deletions cmd/xgo/trace/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"os/exec"
"runtime"
"runtime/debug"
"strconv"
"strings"
"time"

Expand All @@ -36,6 +35,7 @@ See https://github.com/xhd2015/xgo for documentation.
func Main(args []string) {
var files []string
var port string
var bind string
n := len(args)

var showHelp bool
Expand All @@ -61,6 +61,20 @@ func Main(args []string) {
port = strings.TrimPrefix(arg, "--port=")
continue
}
// add --bind
if arg == "--bind" {
if i+1 >= n {
fmt.Fprintf(os.Stderr, "--bind requires arg\n")
os.Exit(1)
}
bind = args[i+1]
i++
continue
} else if strings.HasPrefix(arg, "--bind=") {
bind = strings.TrimPrefix(arg, "--bind=")
continue
}

if !strings.HasPrefix(arg, "-") {
files = append(files, arg)
continue
Expand All @@ -84,15 +98,18 @@ func Main(args []string) {
if port == "" {
port = os.Getenv("PORT")
}
err := serveFile(port, file)
if bind == "" {
bind = "localhost"
}
err := serveFile(bind, port, file)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}

}

func serveFile(portStr string, file string) error {
func serveFile(bindStr string, portStr string, file string) error {
stat, err := os.Stat(file)
if err != nil {
return err
Expand Down Expand Up @@ -149,22 +166,11 @@ func serveFile(portStr string, file string) error {
}
w.Write(output)
})
var autoIncrPort bool
var port int
if portStr == "" {
port = 7070
autoIncrPort = true
} else {
parsePort, err := strconv.ParseInt(portStr, 10, 64)
if err != nil {
return fmt.Errorf("bad port: %s", portStr)
}
port = int(parsePort)
}
err = netutil.ServePortHTTP(server, port, autoIncrPort, 500*time.Millisecond, func(port int) {
url := fmt.Sprintf("http://localhost:%d", port)
fmt.Printf("Server listen at %s\n", url)

host, port := netutil.GetHostAndIP(bindStr, portStr)
autoIncrPort := true
err = netutil.ServePortHTTP(server, host, port, autoIncrPort, 500*time.Millisecond, func(port int) {
url := netutil.BuildAndDisplayURL(host, port)
openURL(url)
})
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package main
import "fmt"

const VERSION = "1.0.39"
const REVISION = "e6ba142b8a4c344bfd9e009090d1666635e1c9e5+1"
const NUMBER = 261
const REVISION = "7fa581a5041d839180502f1d2377ea043803bde7+1"
const NUMBER = 262

func getRevision() string {
revSuffix := ""
Expand Down
4 changes: 2 additions & 2 deletions runtime/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

const VERSION = "1.0.39"
const REVISION = "e6ba142b8a4c344bfd9e009090d1666635e1c9e5+1"
const NUMBER = 261
const REVISION = "7fa581a5041d839180502f1d2377ea043803bde7+1"
const NUMBER = 262

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down
91 changes: 86 additions & 5 deletions support/netutil/netutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ func IsTCPAddrServing(url string, timeout time.Duration) (bool, error) {
return true, nil
}

func ServePortHTTP(server *http.ServeMux, port int, autoIncrPort bool, watchTimeout time.Duration, watch func(port int)) error {
return ServePort(port, autoIncrPort, watchTimeout, watch, func(port int) error {
return http.ListenAndServe(fmt.Sprintf("localhost:%d", port), server)
func ServePortHTTP(server *http.ServeMux, host string, port int, autoIncrPort bool, watchTimeout time.Duration, watch func(port int)) error {
return ServePort(host, port, autoIncrPort, watchTimeout, watch, func(port int) error {
return http.ListenAndServe(fmt.Sprintf("%s:%d", host, port), server)
})
}

// suggested watch timeout: 500ms
func ServePort(port int, autoIncrPort bool, watchTimeout time.Duration, watch func(port int), doWithPort func(port int) error) error {
func ServePort(host string, port int, autoIncrPort bool, watchTimeout time.Duration, watch func(port int), doWithPort func(port int) error) error {
for {
addr := net.JoinHostPort("localhost", strconv.Itoa(port))
addr := net.JoinHostPort(host, strconv.Itoa(port))
serving, err := IsTCPAddrServing(addr, 20*time.Millisecond)
if err != nil {
return err
Expand Down Expand Up @@ -72,3 +72,84 @@ func watchSignalWithinTimeout(timeout time.Duration, errSignal chan struct{}, ac
}
action()
}

// get the local area network IP address by ipType
func GetLocalHostByIPType(ipType string) []string {
addresses, err := net.InterfaceAddrs()
if err != nil {
fmt.Printf("\nnet.InterfaceAddrs failed, err: %v\n", err.Error())
return nil
}
// ipv4 + ipv6
var ips []string
for _, address := range addresses {
if ipNet, ok := address.(*net.IPNet); ok {
// IPv4
if ipNet.IP.To4() != nil && (ipType == "all" || ipType == "ipv4") {
ips = append(ips, ipNet.IP.String())
}
// IPv6
if ipNet.IP.To16() != nil && ipNet.IP.To4() == nil && (ipType == "all" || ipType == "ipv6") {
ips = append(ips, ipNet.IP.String())
}
}
}
if len(ips) == 0 {
fmt.Println("no network interface found")
return nil
}
return ips
}

// provide default values for host and port
func GetHostAndIP(bindStr string, portStr string) (host string, port int) {
// default host=localhost, ipv4 127.0.0.1 or ipv6 ::1
host = "localhost"
port = 7070

if portStr != "" {
parsePort, err := strconv.ParseInt(portStr, 10, 64)
if err == nil {
port = int(parsePort)
}
}

localIPs := GetLocalHostByIPType("all")
if localIPs == nil {
return
}
// add default router
localIPs = append(localIPs, []string{"0.0.0.0", "::"}...)
for _, localIP := range localIPs {
if localIP == bindStr {
host = bindStr
break
}
}
// parse ipv6
ip := net.ParseIP(host)
if ip != nil {
// IP is valid, check if it is IPv4 or IPv6
if ip.To4() == nil {
// ip is not a v4 addr, must be v6
host = fmt.Sprintf("[%s]", host)
}
}
return
}

// build URL based on host and port
func BuildAndDisplayURL(host string, port int) string {
url := fmt.Sprintf("http://%s:%d", host, port)
fmt.Println("Server listen at:")
fmt.Printf("- Open: %s \r\n", url)
fmt.Printf("- Local: http://localhost:%d \r\n", port)
// only print ipv4
if host == "0.0.0.0" {
ipv4IPs := GetLocalHostByIPType("ipv4")
for _, ipv4IP := range ipv4IPs {
fmt.Printf("- Network: http://%s:%d \r\n", ipv4IP, port)
}
}
return url
}
73 changes: 73 additions & 0 deletions support/netutil/netutil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package netutil

import (
"fmt"
"testing"
)

func TestGetLocalHostByIPType(t *testing.T) {

tests := []struct {
name string
ipType string
want bool
}{
{name: "Test with all IPs", ipType: "all", want: true},
{name: "Test with IPv4", ipType: "ipv4", want: true},
{name: "Test unknow ipType", ipType: "test", want: false},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ips := GetLocalHostByIPType(tt.ipType)
if got := len(ips); got > 0 != tt.want {
t.Errorf("GetLocalHostByIPType(%v) = %v; want %v", tt.ipType, got, tt.want)
}
})
}
}

func TestGetHostAndIP(t *testing.T) {
ipv4IPs := GetLocalHostByIPType("ipv4")
var tests = []struct {
bindStr string
portStr string
wantHost string
wantPort int
}{
{"", "", "localhost", 7070}, // default host and port
{ipv4IPs[0], "", ipv4IPs[0], 7070}, // provide host
{"", "8080", "localhost", 8080}, // provide port
{ipv4IPs[0], "8080", ipv4IPs[0], 8080}, // provide host and port
}

for _, tt := range tests {
host, port := GetHostAndIP(tt.bindStr, tt.portStr)
if host != tt.wantHost || port != tt.wantPort {
t.Errorf("GetHostAndIP(%v, %v) => (%v, %v), want (%v, %v)", tt.bindStr, tt.portStr, host, port, tt.wantHost, tt.wantPort)
}
}
}

func TestBuildAndDisplayURL(t *testing.T) {
ipv4IPs := GetLocalHostByIPType("ipv4")
url := fmt.Sprintf("http://%s:7070", ipv4IPs[0])
var tests = []struct {
host string
port int
wantURL string
}{
{"localhost", 7070, "http://localhost:7070"},
{"127.0.0.1", 7070, "http://127.0.0.1:7070"},
{"0.0.0.0", 7070, "http://0.0.0.0:7070"},
{ipv4IPs[0], 7070, url},
{"::1", 7070, "http://::1:7070"},
}

for _, tt := range tests {
gotURL := BuildAndDisplayURL(tt.host, tt.port)
if gotURL != tt.wantURL {
t.Errorf("BuildAndDisplayURL(%v, %v) => %v, want %v", tt.host, tt.port, gotURL, tt.wantURL)
}
}
}

0 comments on commit b2c3ae1

Please sign in to comment.