Sfoglia il codice sorgente

Use random port when no port specified with -http (#316)

* use random port when no port specified

* remove debugging print statement
Margaret Nolan 7 anni fa
parent
commit
7a927a9cd7
No account linked to committer's email address
2 ha cambiato i file con 65 aggiunte e 11 eliminazioni
  1. 30
    11
      internal/driver/webui.go
  2. 35
    0
      internal/driver/webui_test.go

+ 30
- 11
internal/driver/webui.go Vedi File

@@ -83,18 +83,10 @@ type webArgs struct {
83 83
 }
84 84
 
85 85
 func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, wantBrowser bool) error {
86
-	host, portStr, err := net.SplitHostPort(hostport)
87
-	if err != nil {
88
-		return fmt.Errorf("could not split http address: %v", err)
89
-	}
90
-	port, err := strconv.Atoi(portStr)
86
+	host, port, err := getHostAndPort(hostport)
91 87
 	if err != nil {
92
-		return fmt.Errorf("invalid port number: %v", err)
93
-	}
94
-	if host == "" {
95
-		host = "localhost"
88
+		return err
96 89
 	}
97
-
98 90
 	interactiveMode = true
99 91
 	ui := makeWebInterface(p, o)
100 92
 	for n, c := range pprofCommands {
@@ -112,7 +104,7 @@ func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, w
112 104
 		server = defaultWebServer
113 105
 	}
114 106
 	args := &plugin.HTTPServerArgs{
115
-		Hostport: net.JoinHostPort(host, portStr),
107
+		Hostport: net.JoinHostPort(host, strconv.Itoa(port)),
116 108
 		Host:     host,
117 109
 		Port:     port,
118 110
 		Handlers: map[string]http.Handler{
@@ -131,6 +123,33 @@ func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, w
131 123
 	return server(args)
132 124
 }
133 125
 
126
+func getHostAndPort(hostport string) (string, int, error) {
127
+	host, portStr, err := net.SplitHostPort(hostport)
128
+	if err != nil {
129
+		return "", 0, fmt.Errorf("could not split http address: %v", err)
130
+	}
131
+	if host == "" {
132
+		host = "localhost"
133
+	}
134
+	var port int
135
+	if portStr == "" {
136
+		ln, err := net.Listen("tcp", net.JoinHostPort(host, "0"))
137
+		if err != nil {
138
+			return "", 0, fmt.Errorf("could not generate random port: %v", err)
139
+		}
140
+		port = ln.Addr().(*net.TCPAddr).Port
141
+		err = ln.Close()
142
+		if err != nil {
143
+			return "", 0, fmt.Errorf("could not generate random port: %v", err)
144
+		}
145
+	} else {
146
+		port, err = strconv.Atoi(portStr)
147
+		if err != nil {
148
+			return "", 0, fmt.Errorf("invalid port number: %v", err)
149
+		}
150
+	}
151
+	return host, port, nil
152
+}
134 153
 func defaultWebServer(args *plugin.HTTPServerArgs) error {
135 154
 	ln, err := net.Listen("tcp", args.Hostport)
136 155
 	if err != nil {

+ 35
- 0
internal/driver/webui_test.go Vedi File

@@ -228,6 +228,41 @@ func makeFakeProfile() *profile.Profile {
228 228
 	}
229 229
 }
230 230
 
231
+func TestGetHostAndPort(t *testing.T) {
232
+	if runtime.GOOS == "nacl" {
233
+		t.Skip("test assumes tcp available")
234
+	}
235
+
236
+	type testCase struct {
237
+		hostport       string
238
+		wantHost       string
239
+		wantPort       int
240
+		wantRandomPort bool
241
+	}
242
+
243
+	testCases := []testCase{
244
+		{":", "localhost", 0, true},
245
+		{":4681", "localhost", 4681, false},
246
+		{"localhost:4681", "localhost", 4681, false},
247
+	}
248
+	for _, tc := range testCases {
249
+		host, port, err := getHostAndPort(tc.hostport)
250
+		if err != nil {
251
+			t.Errorf("could not get host and port for %q: %v", tc.hostport, err)
252
+		}
253
+		if got, want := host, tc.wantHost; got != want {
254
+			t.Errorf("for %s, got host %s, want %s", tc.hostport, got, want)
255
+			continue
256
+		}
257
+		if !tc.wantRandomPort {
258
+			if got, want := port, tc.wantPort; got != want {
259
+				t.Errorf("for %s, got port %d, want %d", tc.hostport, got, want)
260
+				continue
261
+			}
262
+		}
263
+	}
264
+}
265
+
231 266
 func TestIsLocalHost(t *testing.T) {
232 267
 	for _, s := range []string{"localhost:10000", "[::1]:10000", "127.0.0.1:10000"} {
233 268
 		host, _, err := net.SplitHostPort(s)