From b9fb3a62f56f910292c566609bf1453628798662 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 11:59:48 +0800 Subject: [PATCH 01/10] static file name default lower case --- config.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/config.go b/config.go index 6f87fed1..4751b7e4 100644 --- a/config.go +++ b/config.go @@ -523,18 +523,16 @@ func ParseConfig() (err error) { if sgz := AppConfig.String("StaticExtensionsToGzip"); sgz != "" { extensions := strings.Split(sgz, ",") - if len(extensions) > 0 { - StaticExtensionsToGzip = []string{} - for _, ext := range extensions { - if len(ext) == 0 { - continue - } - extWithDot := ext - if extWithDot[:1] != "." { - extWithDot = "." + extWithDot - } - StaticExtensionsToGzip = append(StaticExtensionsToGzip, extWithDot) + for _, ext := range extensions { + ext = strings.TrimSpace(ext) + if ext == "" { + continue } + ext = strings.ToLower(ext) + if !strings.HasPrefix(ext, ".") { + ext = "." + ext + } + StaticExtensionsToGzip = append(StaticExtensionsToGzip, ext) } } From dc38b324e0522b9053b25eb37bb02e9a1fcb3841 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 12:19:31 +0800 Subject: [PATCH 02/10] code bug fixed --- staticfile.go | 112 ++++++++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/staticfile.go b/staticfile.go index fa8a56d4..18b44234 100644 --- a/staticfile.go +++ b/staticfile.go @@ -31,98 +31,110 @@ func serverStaticRouter(ctx *context.Context) { return } requestPath := filepath.Clean(ctx.Input.Request.URL.Path) - i := 0 - for prefix, staticDir := range StaticDir { - if len(prefix) == 0 { - continue + + // special processing : favicon.ico/robots.txt can be in any static dir + if requestPath == "/favicon.ico" || requestPath == "/robots.txt" { + + if utils.FileExists("./" + requestPath) { + http.ServeFile(ctx.ResponseWriter, ctx.Request, "./"+requestPath) + return } - if requestPath == "/favicon.ico" || requestPath == "/robots.txt" { + + for _, staticDir := range StaticDir { file := path.Join(staticDir, requestPath) if utils.FileExists(file) { http.ServeFile(ctx.ResponseWriter, ctx.Request, file) return } - i++ - if i == len(StaticDir) { - http.NotFound(ctx.ResponseWriter, ctx.Request) - return - } + } + + http.NotFound(ctx.ResponseWriter, ctx.Request) + return + } + + for prefix, staticDir := range StaticDir { + if len(prefix) == 0 { continue } if strings.HasPrefix(requestPath, prefix) { if len(requestPath) > len(prefix) && requestPath[len(prefix)] != '/' { continue } - file := path.Join(staticDir, requestPath[len(prefix):]) - finfo, err := os.Stat(file) + filePath := path.Join(staticDir, requestPath[len(prefix):]) + fileInfo, err := os.Stat(filePath) if err != nil { if RunMode == "dev" { - Warn("Can't find the file:", file, err) + Warn("Can't find the file:", filePath, err) } http.NotFound(ctx.ResponseWriter, ctx.Request) return } //if the request is dir and DirectoryIndex is false then - if finfo.IsDir() { + if fileInfo.IsDir() { if !DirectoryIndex { exception("403", ctx) return - } else if ctx.Input.Request.URL.Path[len(ctx.Input.Request.URL.Path)-1] != '/' { + } + if ctx.Input.Request.URL.Path[len(ctx.Input.Request.URL.Path)-1] != '/' { http.Redirect(ctx.ResponseWriter, ctx.Request, ctx.Input.Request.URL.Path+"/", 302) return } - } else if strings.HasSuffix(requestPath, "/index.html") { - file := path.Join(staticDir, requestPath) - if utils.FileExists(file) { - oFile, err := os.Open(file) + } + + if strings.HasSuffix(requestPath, "/index.html") { + if utils.FileExists(filePath) { + fileReader, err := os.Open(filePath) if err != nil { if RunMode == "dev" { - Warn("Can't open the file:", file, err) + Warn("Can't open the file:", filePath, err) } http.NotFound(ctx.ResponseWriter, ctx.Request) + return } - defer oFile.Close() - http.ServeContent(ctx.ResponseWriter, ctx.Request, file, finfo.ModTime(), oFile) + defer fileReader.Close() + http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, fileInfo.ModTime(), fileReader) return } } - //This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request isStaticFileToCompress := false - if StaticExtensionsToGzip != nil && len(StaticExtensionsToGzip) > 0 { - for _, statExtension := range StaticExtensionsToGzip { - if strings.HasSuffix(strings.ToLower(file), strings.ToLower(statExtension)) { - isStaticFileToCompress = true - break - } + lowerFileName := strings.ToLower(filePath) + for _, statExtension := range StaticExtensionsToGzip { + if strings.HasSuffix(lowerFileName, statExtension) { + isStaticFileToCompress = true + break } } - if isStaticFileToCompress { - var contentEncoding string - if EnableGzip { - contentEncoding = getAcceptEncodingZip(ctx.Request) + if !isStaticFileToCompress { + http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath) + return + } + + //to compress file + var contentEncoding string + if EnableGzip { + contentEncoding = getAcceptEncodingZip(ctx.Request) + } + + memZipFile, err := openMemZipFile(filePath, contentEncoding) + if err != nil { + if RunMode == "dev" { + Warn("Can't compress the file:", filePath, err) } + http.NotFound(ctx.ResponseWriter, ctx.Request) + return + } - memzipfile, err := openMemZipFile(file, contentEncoding) - if err != nil { - return - } - - if contentEncoding == "gzip" { - ctx.Output.Header("Content-Encoding", "gzip") - } else if contentEncoding == "deflate" { - ctx.Output.Header("Content-Encoding", "deflate") - } else { - ctx.Output.Header("Content-Length", strconv.FormatInt(finfo.Size(), 10)) - } - - http.ServeContent(ctx.ResponseWriter, ctx.Request, file, finfo.ModTime(), memzipfile) - + if contentEncoding == "gzip" { + ctx.Output.Header("Content-Encoding", "gzip") + } else if contentEncoding == "deflate" { + ctx.Output.Header("Content-Encoding", "deflate") } else { - http.ServeFile(ctx.ResponseWriter, ctx.Request, file) + ctx.Output.Header("Content-Length", strconv.FormatInt(fileInfo.Size(), 10)) } - return + + http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, fileInfo.ModTime(), memZipFile) } } } From f708ce0299f0082faf8a8f275d122321f7cf4f25 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 12:24:52 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E5=BD=93=E6=9C=89=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=9A=84=E5=8E=8B=E7=BC=A9=E7=B1=BB=E5=9E=8B=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E4=B8=A2=E5=BC=83=E9=BB=98=E8=AE=A4=E7=B1=BB=E5=9E=8B(css,js)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/config.go b/config.go index 4751b7e4..c79437b1 100644 --- a/config.go +++ b/config.go @@ -523,6 +523,7 @@ func ParseConfig() (err error) { if sgz := AppConfig.String("StaticExtensionsToGzip"); sgz != "" { extensions := strings.Split(sgz, ",") + StaticExtensionsToGzip = []string{} for _, ext := range extensions { ext = strings.TrimSpace(ext) if ext == "" { From 936cb735e18e42428d86ad0fdaf36d62cfe527d4 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 13:27:35 +0800 Subject: [PATCH 04/10] file extensions bug fixed --- config.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config.go b/config.go index c79437b1..c2f23f67 100644 --- a/config.go +++ b/config.go @@ -523,7 +523,7 @@ func ParseConfig() (err error) { if sgz := AppConfig.String("StaticExtensionsToGzip"); sgz != "" { extensions := strings.Split(sgz, ",") - StaticExtensionsToGzip = []string{} + fileExts := []string{} for _, ext := range extensions { ext = strings.TrimSpace(ext) if ext == "" { @@ -533,7 +533,10 @@ func ParseConfig() (err error) { if !strings.HasPrefix(ext, ".") { ext = "." + ext } - StaticExtensionsToGzip = append(StaticExtensionsToGzip, ext) + fileExts = append(fileExts, ext) + } + if len(fileExts) > 0 { + StaticExtensionsToGzip = fileExts } } From 4995f9154780cf2690838658f4c84fa93934af35 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 13:46:20 +0800 Subject: [PATCH 05/10] code refactor --- staticfile.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/staticfile.go b/staticfile.go index 18b44234..5822882d 100644 --- a/staticfile.go +++ b/staticfile.go @@ -34,9 +34,9 @@ func serverStaticRouter(ctx *context.Context) { // special processing : favicon.ico/robots.txt can be in any static dir if requestPath == "/favicon.ico" || requestPath == "/robots.txt" { - - if utils.FileExists("./" + requestPath) { - http.ServeFile(ctx.ResponseWriter, ctx.Request, "./"+requestPath) + file := path.Join(".", requestPath) + if utils.FileExists(file) { + http.ServeFile(ctx.ResponseWriter, ctx.Request, file) return } From 9c17f73489316dde49f037206273d63f6ff0b916 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 13:48:34 +0800 Subject: [PATCH 06/10] code refactor --- staticfile.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/staticfile.go b/staticfile.go index 5822882d..1c9d775a 100644 --- a/staticfile.go +++ b/staticfile.go @@ -82,19 +82,17 @@ func serverStaticRouter(ctx *context.Context) { } if strings.HasSuffix(requestPath, "/index.html") { - if utils.FileExists(filePath) { - fileReader, err := os.Open(filePath) - if err != nil { - if RunMode == "dev" { - Warn("Can't open the file:", filePath, err) - } - http.NotFound(ctx.ResponseWriter, ctx.Request) - return + fileReader, err := os.Open(filePath) + if err != nil { + if RunMode == "dev" { + Warn("Can't open the file:", filePath, err) } - defer fileReader.Close() - http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, fileInfo.ModTime(), fileReader) + http.NotFound(ctx.ResponseWriter, ctx.Request) return } + defer fileReader.Close() + http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, fileInfo.ModTime(), fileReader) + return } isStaticFileToCompress := false From 6ad215a9bba3b95f8b2137d132d1e5a955937ef6 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 14:11:02 +0800 Subject: [PATCH 07/10] mem zip file var refactor --- memzipfile.go | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/memzipfile.go b/memzipfile.go index 0fff44b6..594f1060 100644 --- a/memzipfile.go +++ b/memzipfile.go @@ -29,72 +29,72 @@ import ( ) var ( - gmfim = make(map[string]*memFileInfo) - lock sync.RWMutex + menFileInfoMap = make(map[string]*memFileInfo) + lock sync.RWMutex ) -// OpenMemZipFile returns MemFile object with a compressed static file. +// openMemZipFile returns MemFile object with a compressed static file. // it's used for serve static file if gzip enable. func openMemZipFile(path string, zip string) (*memFile, error) { - osfile, e := os.Open(path) + osFile, e := os.Open(path) if e != nil { return nil, e } - defer osfile.Close() + defer osFile.Close() - osfileinfo, e := osfile.Stat() + osFileInfo, e := osFile.Stat() if e != nil { return nil, e } - modtime := osfileinfo.ModTime() - fileSize := osfileinfo.Size() + modTime := osFileInfo.ModTime() + fileSize := osFileInfo.Size() lock.RLock() - cfi, ok := gmfim[zip+":"+path] + cfi, ok := menFileInfoMap[zip+":"+path] lock.RUnlock() - if !(ok && cfi.ModTime() == modtime && cfi.fileSize == fileSize) { + if !(ok && cfi.ModTime() == modTime && cfi.fileSize == fileSize) { var content []byte if zip == "gzip" { - var zipbuf bytes.Buffer - gzipwriter, e := gzip.NewWriterLevel(&zipbuf, gzip.BestCompression) + var zipBuf bytes.Buffer + gzipWriter, e := gzip.NewWriterLevel(&zipBuf, gzip.BestCompression) if e != nil { return nil, e } - _, e = io.Copy(gzipwriter, osfile) - gzipwriter.Close() + _, e = io.Copy(gzipWriter, osFile) + gzipWriter.Close() if e != nil { return nil, e } - content, e = ioutil.ReadAll(&zipbuf) + content, e = ioutil.ReadAll(&zipBuf) if e != nil { return nil, e } } else if zip == "deflate" { - var zipbuf bytes.Buffer - deflatewriter, e := flate.NewWriter(&zipbuf, flate.BestCompression) + var zipBuf bytes.Buffer + deflateWriter, e := flate.NewWriter(&zipBuf, flate.BestCompression) if e != nil { return nil, e } - _, e = io.Copy(deflatewriter, osfile) - deflatewriter.Close() + _, e = io.Copy(deflateWriter, osFile) + deflateWriter.Close() if e != nil { return nil, e } - content, e = ioutil.ReadAll(&zipbuf) + content, e = ioutil.ReadAll(&zipBuf) if e != nil { return nil, e } } else { - content, e = ioutil.ReadAll(osfile) + content, e = ioutil.ReadAll(osFile) if e != nil { return nil, e } } - cfi = &memFileInfo{osfileinfo, modtime, content, int64(len(content)), fileSize} + cfi = &memFileInfo{osFileInfo, modTime, content, int64(len(content)), fileSize} lock.Lock() defer lock.Unlock() - gmfim[zip+":"+path] = cfi + menFileInfoMap[zip+":"+path] = cfi } return &memFile{fi: cfi, offset: 0}, nil } @@ -139,7 +139,7 @@ func (fi *memFileInfo) Sys() interface{} { return nil } -// MemFile contains MemFileInfo and bytes offset when reading. +// memFile contains MemFileInfo and bytes offset when reading. // it implements io.Reader,io.ReadCloser and io.Seeker. type memFile struct { fi *memFileInfo @@ -198,7 +198,7 @@ func (f *memFile) Seek(offset int64, whence int) (ret int64, err error) { return f.offset, nil } -// GetAcceptEncodingZip returns accept encoding format in http header. +// getAcceptEncodingZip returns accept encoding format in http header. // zip is first, then deflate if both accepted. // If no accepted, return empty string. func getAcceptEncodingZip(r *http.Request) string { @@ -206,9 +206,9 @@ func getAcceptEncodingZip(r *http.Request) string { ss = strings.ToLower(ss) if strings.Contains(ss, "gzip") { return "gzip" - } else if strings.Contains(ss, "deflate") { - return "deflate" - } else { - return "" } + if strings.Contains(ss, "deflate") { + return "deflate" + } + return "" } From d4f3dfd5274d1b5d57f76486ec48003b95f622df Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 14:15:41 +0800 Subject: [PATCH 08/10] return when find static path --- staticfile.go | 1 + 1 file changed, 1 insertion(+) diff --git a/staticfile.go b/staticfile.go index 1c9d775a..e1fc4f73 100644 --- a/staticfile.go +++ b/staticfile.go @@ -133,6 +133,7 @@ func serverStaticRouter(ctx *context.Context) { } http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, fileInfo.ModTime(), memZipFile) + return } } } From 1abf85ed2adb615f348ba2a11dfd7277df032f5c Mon Sep 17 00:00:00 2001 From: JessonChan Date: Tue, 22 Sep 2015 15:18:24 +0800 Subject: [PATCH 09/10] simplify the switch code --- context/output.go | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/context/output.go b/context/output.go index 743beb96..a4bb3d09 100644 --- a/context/output.go +++ b/context/output.go @@ -103,22 +103,10 @@ func (output *BeegoOutput) Cookie(name string, value string, others ...interface //fix cookie not work in IE if len(others) > 0 { switch v := others[0].(type) { - case int: + case int, int32, int64: if v > 0 { fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(v)*time.Second).UTC().Format(time.RFC1123), v) - } else if v < 0 { - fmt.Fprintf(&b, "; Max-Age=0") - } - case int64: - if v > 0 { - fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(v)*time.Second).UTC().Format(time.RFC1123), v) - } else if v < 0 { - fmt.Fprintf(&b, "; Max-Age=0") - } - case int32: - if v > 0 { - fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(v)*time.Second).UTC().Format(time.RFC1123), v) - } else if v < 0 { + } else if v <= 0 { fmt.Fprintf(&b, "; Max-Age=0") } } From 860568cb6c457a203157804569fcbb031313c75b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Fri, 6 Nov 2015 18:51:53 +0800 Subject: [PATCH 10/10] modified as astaxie reviews https://github.com/astaxie/beego/pull/1376 --- config.go | 1 - memzipfile.go | 6 +++--- staticfile.go | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/config.go b/config.go index c2f23f67..e8370f4f 100644 --- a/config.go +++ b/config.go @@ -529,7 +529,6 @@ func ParseConfig() (err error) { if ext == "" { continue } - ext = strings.ToLower(ext) if !strings.HasPrefix(ext, ".") { ext = "." + ext } diff --git a/memzipfile.go b/memzipfile.go index 594f1060..b61e87f2 100644 --- a/memzipfile.go +++ b/memzipfile.go @@ -206,9 +206,9 @@ func getAcceptEncodingZip(r *http.Request) string { ss = strings.ToLower(ss) if strings.Contains(ss, "gzip") { return "gzip" - } - if strings.Contains(ss, "deflate") { + } else if strings.Contains(ss, "deflate") { return "deflate" + } else { + return "" } - return "" } diff --git a/staticfile.go b/staticfile.go index e1fc4f73..de530b0c 100644 --- a/staticfile.go +++ b/staticfile.go @@ -96,9 +96,8 @@ func serverStaticRouter(ctx *context.Context) { } isStaticFileToCompress := false - lowerFileName := strings.ToLower(filePath) for _, statExtension := range StaticExtensionsToGzip { - if strings.HasSuffix(lowerFileName, statExtension) { + if strings.HasSuffix(strings.ToLower(filePath), strings.ToLower(statExtension)) { isStaticFileToCompress = true break }