1
0
mirror of https://github.com/astaxie/beego.git synced 2024-06-28 01:54:14 +00:00

Fix Unexpected EOF bug in staticfile

This commit is contained in:
Amit Yadav 2018-05-07 12:57:13 +05:30
parent bf5c5626ab
commit 98a3cda260
2 changed files with 19 additions and 13 deletions

View File

@ -74,7 +74,7 @@ func serverStaticRouter(ctx *context.Context) {
if enableCompress { if enableCompress {
acceptEncoding = context.ParseEncoding(ctx.Request) acceptEncoding = context.ParseEncoding(ctx.Request)
} }
b, n, sch, err := openFile(filePath, fileInfo, acceptEncoding) b, n, sch, reader, err := openFile(filePath, fileInfo, acceptEncoding)
if err != nil { if err != nil {
if BConfig.RunMode == DEV { if BConfig.RunMode == DEV {
logs.Warn("Can't compress the file:", filePath, err) logs.Warn("Can't compress the file:", filePath, err)
@ -89,47 +89,53 @@ func serverStaticRouter(ctx *context.Context) {
ctx.Output.Header("Content-Length", strconv.FormatInt(sch.size, 10)) ctx.Output.Header("Content-Length", strconv.FormatInt(sch.size, 10))
} }
http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, sch.modTime, sch) http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, sch.modTime, reader)
} }
type serveContentHolder struct { type serveContentHolder struct {
*bytes.Reader data []byte
modTime time.Time modTime time.Time
size int64 size int64
encoding string encoding string
} }
type serveContentReader struct {
*bytes.Reader
}
var ( var (
staticFileMap = make(map[string]*serveContentHolder) staticFileMap = make(map[string]*serveContentHolder)
mapLock sync.RWMutex mapLock sync.RWMutex
) )
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, error) { func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, *serveContentReader, error) {
mapKey := acceptEncoding + ":" + filePath mapKey := acceptEncoding + ":" + filePath
mapLock.RLock() mapLock.RLock()
mapFile := staticFileMap[mapKey] mapFile := staticFileMap[mapKey]
mapLock.RUnlock() mapLock.RUnlock()
if isOk(mapFile, fi) { if isOk(mapFile, fi) {
return mapFile.encoding != "", mapFile.encoding, mapFile, nil reader := &serveContentReader{Reader: bytes.NewReader(mapFile.data)}
return mapFile.encoding != "", mapFile.encoding, mapFile, reader, nil
} }
mapLock.Lock() mapLock.Lock()
defer mapLock.Unlock() defer mapLock.Unlock()
if mapFile = staticFileMap[mapKey]; !isOk(mapFile, fi) { if mapFile = staticFileMap[mapKey]; !isOk(mapFile, fi) {
file, err := os.Open(filePath) file, err := os.Open(filePath)
if err != nil { if err != nil {
return false, "", nil, err return false, "", nil, nil, err
} }
defer file.Close() defer file.Close()
var bufferWriter bytes.Buffer var bufferWriter bytes.Buffer
_, n, err := context.WriteFile(acceptEncoding, &bufferWriter, file) _, n, err := context.WriteFile(acceptEncoding, &bufferWriter, file)
if err != nil { if err != nil {
return false, "", nil, err return false, "", nil, nil, err
} }
mapFile = &serveContentHolder{Reader: bytes.NewReader(bufferWriter.Bytes()), modTime: fi.ModTime(), size: int64(bufferWriter.Len()), encoding: n} mapFile = &serveContentHolder{data: bufferWriter.Bytes(), modTime: fi.ModTime(), size: int64(bufferWriter.Len()), encoding: n}
staticFileMap[mapKey] = mapFile staticFileMap[mapKey] = mapFile
} }
return mapFile.encoding != "", mapFile.encoding, mapFile, nil reader := &serveContentReader{Reader: bytes.NewReader(mapFile.data)}
return mapFile.encoding != "", mapFile.encoding, mapFile, reader, nil
} }
func isOk(s *serveContentHolder, fi os.FileInfo) bool { func isOk(s *serveContentHolder, fi os.FileInfo) bool {

View File

@ -16,7 +16,7 @@ var licenseFile = filepath.Join(currentWorkDir, "LICENSE")
func testOpenFile(encoding string, content []byte, t *testing.T) { func testOpenFile(encoding string, content []byte, t *testing.T) {
fi, _ := os.Stat(licenseFile) fi, _ := os.Stat(licenseFile)
b, n, sch, err := openFile(licenseFile, fi, encoding) b, n, sch, reader, err := openFile(licenseFile, fi, encoding)
if err != nil { if err != nil {
t.Log(err) t.Log(err)
t.Fail() t.Fail()
@ -24,7 +24,7 @@ func testOpenFile(encoding string, content []byte, t *testing.T) {
t.Log("open static file encoding "+n, b) t.Log("open static file encoding "+n, b)
assetOpenFileAndContent(sch, content, t) assetOpenFileAndContent(sch, reader, content, t)
} }
func TestOpenStaticFile_1(t *testing.T) { func TestOpenStaticFile_1(t *testing.T) {
file, _ := os.Open(licenseFile) file, _ := os.Open(licenseFile)
@ -53,13 +53,13 @@ func TestOpenStaticFileDeflate_1(t *testing.T) {
testOpenFile("deflate", content, t) testOpenFile("deflate", content, t)
} }
func assetOpenFileAndContent(sch *serveContentHolder, content []byte, t *testing.T) { func assetOpenFileAndContent(sch *serveContentHolder, reader *serveContentReader, content []byte, t *testing.T) {
t.Log(sch.size, len(content)) t.Log(sch.size, len(content))
if sch.size != int64(len(content)) { if sch.size != int64(len(content)) {
t.Log("static content file size not same") t.Log("static content file size not same")
t.Fail() t.Fail()
} }
bs, _ := ioutil.ReadAll(sch) bs, _ := ioutil.ReadAll(reader)
for i, v := range content { for i, v := range content {
if v != bs[i] { if v != bs[i] {
t.Log("content not same") t.Log("content not same")