Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce FS.CompressRoot #1331

Merged
merged 5 commits into from Jul 10, 2022
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 42 additions & 5 deletions fs.go
Expand Up @@ -276,6 +276,10 @@ type FS struct {
// Brotli encoding is disabled by default.
CompressBrotli bool

// Path to the compressed root directory to serve files from. If this value
// is empty, Root is used.
CompressRoot string

// Enables byte range requests if set to true.
//
// Byte range requests are disabled by default.
Expand Down Expand Up @@ -388,9 +392,7 @@ func (fs *FS) NewRequestHandler() RequestHandler {
return fs.h
}

func (fs *FS) initRequestHandler() {
root := fs.Root

func (fs *FS) normalizeRoot(root string) string {
// Serve files from the current working directory if Root is empty or if Root is a relative path.
if (!fs.AllowEmptyRoot && len(root) == 0) || (len(root) > 0 && !filepath.IsAbs(root)) {
path, err := os.Getwd()
Expand All @@ -406,6 +408,18 @@ func (fs *FS) initRequestHandler() {
for len(root) > 0 && root[len(root)-1] == os.PathSeparator {
root = root[:len(root)-1]
}
return root
}

func (fs *FS) initRequestHandler() {
root := fs.normalizeRoot(fs.Root)

compressRoot := fs.CompressRoot
if len(compressRoot) == 0 {
compressRoot = root
} else {
compressRoot = fs.normalizeRoot(compressRoot)
}

cacheDuration := fs.CacheDuration
if cacheDuration <= 0 {
Expand All @@ -430,6 +444,7 @@ func (fs *FS) initRequestHandler() {
generateIndexPages: fs.GenerateIndexPages,
compress: fs.Compress,
compressBrotli: fs.CompressBrotli,
compressRoot: compressRoot,
pathNotFound: fs.PathNotFound,
acceptByteRange: fs.AcceptByteRange,
cacheDuration: cacheDuration,
Expand Down Expand Up @@ -478,6 +493,7 @@ type fsHandler struct {
generateIndexPages bool
compress bool
compressBrotli bool
compressRoot string
acceptByteRange bool
cacheDuration time.Duration
compressedFileSuffixes map[string]string
Expand Down Expand Up @@ -780,6 +796,20 @@ func cleanCacheNolock(cache map[string]*fsFile, pendingFiles, filesToRelease []*
return pendingFiles, filesToRelease
}

func (h *fsHandler) pathToFilePath(path string) string {
return h.root + filepath.FromSlash(path)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be filepath.FromSlash(h.root + path) like it was in the code where you call this function now?

And then strings.HasPrefix(filePath, h.root) should also use filepath.FromSlash( I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Join root and path, and then calls filepath.FromSlash 38b41a8

root and compressRoot are passed through filepath.FromSlash in normalizeRoot. (eg. C:\path\to\root)
The path is part of the URL, that is separated by slashes. (eg. /path/to/file)
The path needs filepath.FromSlash to join root. (eg. C:\path\to\root + \path\to\file)

I think the best way is to use "filepath.Join", but I used "+" and "filepath.FromSlash" to respect the original code.

func (h *fsHandler) pathToFilePath(path string) string {
	return filepath.Join(h.root, path)
}

func (h *fsHandler) filePathToCompressed(filePath string) string {
	if h.root == h.compressRoot {
		return filePath
	}
	if !strings.HasPrefix(filePath, h.root) {
		return filePath
	}
	return filepath.Join(h.compressRoot, filePath[len(h.root):])
}

}

func (h *fsHandler) filePathToCompressed(filePath string) string {
if h.root == h.compressRoot {
return filePath
}
if !strings.HasPrefix(filePath, h.root) {
return filePath
}
return h.compressRoot + filePath[len(h.root):]
}

func (h *fsHandler) handleRequest(ctx *RequestCtx) {
var path []byte
if h.pathRewrite != nil {
Expand Down Expand Up @@ -831,7 +861,7 @@ func (h *fsHandler) handleRequest(ctx *RequestCtx) {

if !ok {
pathStr := string(path)
filePath := filepath.FromSlash(h.root + pathStr)
filePath := h.pathToFilePath(pathStr)

var err error
ff, err = h.openFSFile(filePath, mustCompress, fileEncoding)
Expand Down Expand Up @@ -1153,7 +1183,14 @@ func (h *fsHandler) compressAndOpenFSFile(filePath string, fileEncoding string)
return h.newFSFile(f, fileInfo, false, "")
}

compressedFilePath := filePath + h.compressedFileSuffixes[fileEncoding]
compressedFilePath := h.filePathToCompressed(filePath)
if compressedFilePath != filePath {
if err := os.MkdirAll(filepath.Dir(compressedFilePath), os.ModePerm); err != nil {
return nil, err
}
}
compressedFilePath += h.compressedFileSuffixes[fileEncoding]

absPath, err := filepath.Abs(compressedFilePath)
if err != nil {
_ = f.Close()
Expand Down