fix return code when request /logs with long file name
This commit is contained in:
		@@ -18,7 +18,9 @@ package routes
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/emicklei/go-restful"
 | 
						"github.com/emicklei/go-restful"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -42,6 +44,12 @@ func (l Logs) Install(c *restful.Container) {
 | 
				
			|||||||
func logFileHandler(req *restful.Request, resp *restful.Response) {
 | 
					func logFileHandler(req *restful.Request, resp *restful.Response) {
 | 
				
			||||||
	logdir := "/var/log"
 | 
						logdir := "/var/log"
 | 
				
			||||||
	actual := path.Join(logdir, req.PathParameter("logpath"))
 | 
						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)
 | 
						http.ServeFile(resp.ResponseWriter, req.Request, actual)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,3 +57,15 @@ func logFileListHandler(req *restful.Request, resp *restful.Response) {
 | 
				
			|||||||
	logdir := "/var/log"
 | 
						logdir := "/var/log"
 | 
				
			||||||
	http.ServeFile(resp.ResponseWriter, req.Request, logdir)
 | 
						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
									
								
							
							
						
						
									
										48
									
								
								pkg/routes/logs_test.go
									
									
									
									
									
										Normal 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")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user