Golang中如何避免在HTTP响应中发送点文件或点文件夹内的文件

Golang中如何避免在HTTP响应中发送点文件或点文件夹内的文件 如何在HTTP响应中避免发送点文件或点文件夹中的文件

3 回复

检查文件名是否以点开头并返回错误?

更多关于Golang中如何避免在HTTP响应中发送点文件或点文件夹内的文件的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


http.FileServer 期望以 http.FileSystem 作为其参数。创建一个结构体并实现 Open(name string) (http.File, error) 方法,这是 http.FileSystem 接口唯一的行为,然后根据你的需求过滤文件。

type PublicDir struct{
    dir http.Dir
    AllowedExtensions []string
}
func (d PublicDir) Open(fileName string) (http.File, error) {
    // 检查文件的扩展名,并执行你需要的操作
}
public := http.FileServer(PublicDir{http.Dir("public/")})
http.Handle("/", http.StripPrefix("/", public))

在Golang的HTTP服务器中,可以通过中间件或文件服务器包装器来过滤点文件和点文件夹。以下是一个实现示例:

package main

import (
    "net/http"
    "strings"
)

// 检查路径是否包含点文件或点文件夹
func isDotFile(path string) bool {
    parts := strings.Split(path, "/")
    for _, part := range parts {
        if strings.HasPrefix(part, ".") {
            return true
        }
    }
    return false
}

// 包装文件服务器的处理器
func noDotFileHandler(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if isDotFile(r.URL.Path) {
            http.NotFound(w, r)
            return
        }
        h.ServeHTTP(w, r)
    })
}

func main() {
    fs := http.FileServer(http.Dir("./static"))
    http.Handle("/", noDotFileHandler(fs))
    http.ListenAndServe(":8080", nil)
}

对于更复杂的场景,可以自定义文件系统实现:

type filteredFileSystem struct {
    fs http.FileSystem
}

func (ffs filteredFileSystem) Open(name string) (http.File, error) {
    if isDotFile(name) {
        return nil, os.ErrNotExist
    }
    
    f, err := ffs.fs.Open(name)
    if err != nil {
        return nil, err
    }
    
    // 检查打开的文件是否是目录,如果是则检查目录内容
    stat, err := f.Stat()
    if err != nil {
        f.Close()
        return nil, err
    }
    
    if stat.IsDir() {
        // 重新实现目录读取逻辑,过滤点文件
        return &filteredDir{f, name}, nil
    }
    
    return f, nil
}

type filteredDir struct {
    http.File
    path string
}

func (fd *filteredDir) Readdir(count int) ([]os.FileInfo, error) {
    entries, err := fd.File.Readdir(count)
    if err != nil {
        return nil, err
    }
    
    filtered := make([]os.FileInfo, 0, len(entries))
    for _, entry := range entries {
        if !strings.HasPrefix(entry.Name(), ".") {
            filtered = append(filtered, entry)
        }
    }
    
    return filtered, nil
}

// 使用自定义文件系统
func main() {
    fs := &filteredFileSystem{http.Dir("./static")}
    http.Handle("/", http.FileServer(fs))
    http.ListenAndServe(":8080", nil)
}

这些实现确保了以点开头的文件和文件夹不会通过HTTP响应暴露。第一个示例通过中间件拦截请求路径,第二个示例通过自定义文件系统在文件系统层面进行过滤。

回到顶部