fix return code when request /logs with long file name

This commit is contained in:
Haleygo 2021-04-26 16:54:02 +08:00
parent c90427d42e
commit 2cde15029a
2 changed files with 68 additions and 0 deletions

View File

@ -18,7 +18,9 @@ package routes
import (
"net/http"
"os"
"path"
"syscall"
"github.com/emicklei/go-restful"
)
@ -42,6 +44,12 @@ func (l Logs) Install(c *restful.Container) {
func logFileHandler(req *restful.Request, resp *restful.Response) {
logdir := "/var/log"
actual := path.Join(logdir, req.PathParameter("logpath"))
// check filename length first, return 404 if it's oversize.
if logFileNameIsTooLong(actual) {
http.Error(resp, "file not found", http.StatusNotFound)
return
}
http.ServeFile(resp.ResponseWriter, req.Request, actual)
}
@ -49,3 +57,15 @@ func logFileListHandler(req *restful.Request, resp *restful.Response) {
logdir := "/var/log"
http.ServeFile(resp.ResponseWriter, req.Request, logdir)
}
// logFileNameIsTooLong checks filename length, returns true if it's longer than 255.
// cause http.ServeFile returns default error code 500 except for NotExist and Forbidden, but we need to separate the real 500 from oversize filename here.
func logFileNameIsTooLong(filePath string) bool {
_, err := os.Stat(filePath)
if err != nil {
if e, ok := err.(*os.PathError); ok && e.Err == syscall.ENAMETOOLONG {
return true
}
}
return false
}

48
pkg/routes/logs_test.go Normal file
View File

@ -0,0 +1,48 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package routes
import (
"fmt"
"os"
"testing"
)
func TestPreCheckLogFileNameLength(t *testing.T) {
oversizeFileName := fmt.Sprintf("%0256s", "a")
normalFileName := fmt.Sprintf("%0255s", "a")
// check file with oversize name.
if !logFileNameIsTooLong(oversizeFileName) {
t.Error("failed to check oversize filename")
}
// check file with normal name which doesn't exist.
if logFileNameIsTooLong(normalFileName) {
t.Error("failed to check normal filename")
}
// check file with normal name which does exist.
_, err := os.Create(normalFileName)
if err != nil {
t.Error("failed to create test file")
}
defer os.Remove(normalFileName)
if logFileNameIsTooLong(normalFileName) {
t.Error("failed to check normal filename")
}
}