소스 검색

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

* use random port when no port specified

* remove debugging print statement
Margaret Nolan 7 년 전
부모
커밋
7a927a9cd7
No account linked to committer's email address
2개의 변경된 파일65개의 추가작업 그리고 11개의 파일을 삭제
  1. 30
    11
      internal/driver/webui.go
  2. 35
    0
      internal/driver/webui_test.go

+ 30
- 11
internal/driver/webui.go 파일 보기

83
 }
83
 }
84
 
84
 
85
 func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, wantBrowser bool) error {
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
 	if err != nil {
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
 	interactiveMode = true
90
 	interactiveMode = true
99
 	ui := makeWebInterface(p, o)
91
 	ui := makeWebInterface(p, o)
100
 	for n, c := range pprofCommands {
92
 	for n, c := range pprofCommands {
112
 		server = defaultWebServer
104
 		server = defaultWebServer
113
 	}
105
 	}
114
 	args := &plugin.HTTPServerArgs{
106
 	args := &plugin.HTTPServerArgs{
115
-		Hostport: net.JoinHostPort(host, portStr),
107
+		Hostport: net.JoinHostPort(host, strconv.Itoa(port)),
116
 		Host:     host,
108
 		Host:     host,
117
 		Port:     port,
109
 		Port:     port,
118
 		Handlers: map[string]http.Handler{
110
 		Handlers: map[string]http.Handler{
131
 	return server(args)
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
 func defaultWebServer(args *plugin.HTTPServerArgs) error {
153
 func defaultWebServer(args *plugin.HTTPServerArgs) error {
135
 	ln, err := net.Listen("tcp", args.Hostport)
154
 	ln, err := net.Listen("tcp", args.Hostport)
136
 	if err != nil {
155
 	if err != nil {

+ 35
- 0
internal/driver/webui_test.go 파일 보기

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
 func TestIsLocalHost(t *testing.T) {
266
 func TestIsLocalHost(t *testing.T) {
232
 	for _, s := range []string{"localhost:10000", "[::1]:10000", "127.0.0.1:10000"} {
267
 	for _, s := range []string{"localhost:10000", "[::1]:10000", "127.0.0.1:10000"} {
233
 		host, _, err := net.SplitHostPort(s)
268
 		host, _, err := net.SplitHostPort(s)