net/http: don't panic serving dir in ServeFile with empty Request.URL.Path

Updates #30165
Updates #31622

Change-Id: I7a4b91aa7c5c3af8c0b1273cbb42046feddf7d78
Reviewed-on: https://go-review.googlesource.com/c/go/+/180499
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 41d46dc..4c4f0e4 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -585,7 +585,7 @@
 	// redirect if the directory name doesn't end in a slash
 	if d.IsDir() {
 		url := r.URL.Path
-		if url[len(url)-1] != '/' {
+		if url == "" || url[len(url)-1] != '/' {
 			localRedirect(w, r, path.Base(url)+"/")
 			return
 		}
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index 762e88b..047bb04 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -207,6 +207,18 @@
 	}
 }
 
+// Tests that this doesn't panic. (Issue 30165)
+func TestServeFileDirPanicEmptyPath(t *testing.T) {
+	rec := httptest.NewRecorder()
+	req := httptest.NewRequest("GET", "/", nil)
+	req.URL.Path = ""
+	ServeFile(rec, req, "testdata")
+	res := rec.Result()
+	if res.StatusCode != 301 {
+		t.Errorf("code = %v; want 301", res.Status)
+	}
+}
+
 var fsRedirectTestData = []struct {
 	original, redirect string
 }{