mirror of
https://github.com/infinite-iroha/touka.git
synced 2026-02-03 17:01:11 +08:00
Compare commits
No commits in common. "e4aaaa1583d74310f42cad4ddf1d271f19fd58b9" and "76a89800a2df065e2dc37a1cf0b41fe4a0fb2545" have entirely different histories.
e4aaaa1583
...
76a89800a2
1 changed files with 3 additions and 110 deletions
113
context.go
113
context.go
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -280,113 +280,6 @@ func (c *Context) Text(code int, text string) {
|
||||||
c.Writer.Write([]byte(text))
|
c.Writer.Write([]byte(text))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileText
|
|
||||||
func (c *Context) FileText(code int, filePath string) {
|
|
||||||
// 清理path
|
|
||||||
cleanPath := filepath.Clean(filePath)
|
|
||||||
if !filepath.IsAbs(cleanPath) {
|
|
||||||
c.AddError(fmt.Errorf("relative path not allowed: %s", cleanPath))
|
|
||||||
c.ErrorUseHandle(http.StatusBadRequest, fmt.Errorf("relative path not allowed"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 检查文件是否存在
|
|
||||||
if _, err := os.Stat(cleanPath); os.IsNotExist(err) {
|
|
||||||
c.AddError(fmt.Errorf("file not found: %s", cleanPath))
|
|
||||||
c.ErrorUseHandle(http.StatusNotFound, fmt.Errorf("file not found"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开文件
|
|
||||||
file, err := os.Open(cleanPath)
|
|
||||||
if err != nil {
|
|
||||||
c.AddError(fmt.Errorf("failed to open file %s: %w", cleanPath, err))
|
|
||||||
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to open file: %w", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// 获取文件信息以获取文件大小
|
|
||||||
fileInfo, err := file.Stat()
|
|
||||||
if err != nil {
|
|
||||||
c.AddError(fmt.Errorf("failed to get file info for %s: %w", cleanPath, err))
|
|
||||||
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to get file info: %w", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 判断是否是dir
|
|
||||||
if fileInfo.IsDir() {
|
|
||||||
c.AddError(fmt.Errorf("path is a directory, not a file: %s", cleanPath))
|
|
||||||
c.ErrorUseHandle(http.StatusBadRequest, fmt.Errorf("path is a directory"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.SetHeader("Content-Type", "text/plain; charset=utf-8")
|
|
||||||
|
|
||||||
c.SetBodyStream(file, int(fileInfo.Size()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// not fot work
|
|
||||||
// FileTextSafeDir
|
|
||||||
func (c *Context) FileTextSafeDir(code int, filePath string, safeDir string) {
|
|
||||||
|
|
||||||
// 清理path
|
|
||||||
cleanPath := path.Clean(filePath)
|
|
||||||
if !filepath.IsAbs(cleanPath) {
|
|
||||||
c.AddError(fmt.Errorf("relative path not allowed: %s", cleanPath))
|
|
||||||
c.ErrorUseHandle(http.StatusBadRequest, fmt.Errorf("relative path not allowed"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if strings.Contains(cleanPath, "..") {
|
|
||||||
c.AddError(fmt.Errorf("path traversal attempt detected: %s", cleanPath))
|
|
||||||
c.ErrorUseHandle(http.StatusBadRequest, fmt.Errorf("path traversal attempt detected"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断filePath是否包含在safeDir内, 防止路径穿越
|
|
||||||
relPath, err := filepath.Rel(safeDir, cleanPath)
|
|
||||||
if err != nil {
|
|
||||||
c.AddError(fmt.Errorf("failed to get relative path: %w", err))
|
|
||||||
c.ErrorUseHandle(http.StatusBadRequest, fmt.Errorf("failed to get relative path: %w", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cleanPath = filepath.Join(safeDir, relPath)
|
|
||||||
|
|
||||||
// 检查文件是否存在
|
|
||||||
if _, err := os.Stat(cleanPath); os.IsNotExist(err) {
|
|
||||||
c.AddError(fmt.Errorf("file not found: %s", cleanPath))
|
|
||||||
c.ErrorUseHandle(http.StatusNotFound, fmt.Errorf("file not found"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开文件
|
|
||||||
file, err := os.Open(cleanPath)
|
|
||||||
if err != nil {
|
|
||||||
c.AddError(fmt.Errorf("failed to open file %s: %w", cleanPath, err))
|
|
||||||
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to open file: %w", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// 获取文件信息以获取文件大小
|
|
||||||
fileInfo, err := file.Stat()
|
|
||||||
if err != nil {
|
|
||||||
c.AddError(fmt.Errorf("failed to get file info for %s: %w", cleanPath, err))
|
|
||||||
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to get file info: %w", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 判断是否是dir
|
|
||||||
if fileInfo.IsDir() {
|
|
||||||
c.AddError(fmt.Errorf("path is a directory, not a file: %s", cleanPath))
|
|
||||||
c.ErrorUseHandle(http.StatusBadRequest, fmt.Errorf("path is a directory"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.SetHeader("Content-Type", "text/plain; charset=utf-8")
|
|
||||||
|
|
||||||
c.SetBodyStream(file, int(fileInfo.Size()))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// JSON 向响应写入 JSON 数据
|
// JSON 向响应写入 JSON 数据
|
||||||
// 设置 Content-Type 为 application/json
|
// 设置 Content-Type 为 application/json
|
||||||
func (c *Context) JSON(code int, obj any) {
|
func (c *Context) JSON(code int, obj any) {
|
||||||
|
|
@ -862,7 +755,7 @@ func (c *Context) GetRequestURIPath() string {
|
||||||
// 将文件内容作为响应body
|
// 将文件内容作为响应body
|
||||||
func (c *Context) SetRespBodyFile(code int, filePath string) {
|
func (c *Context) SetRespBodyFile(code int, filePath string) {
|
||||||
// 清理path
|
// 清理path
|
||||||
cleanPath := filepath.Clean(filePath)
|
cleanPath := path.Clean(filePath)
|
||||||
|
|
||||||
// 打开文件
|
// 打开文件
|
||||||
file, err := os.Open(cleanPath)
|
file, err := os.Open(cleanPath)
|
||||||
|
|
@ -882,7 +775,7 @@ func (c *Context) SetRespBodyFile(code int, filePath string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试根据文件扩展名猜测 Content-Type
|
// 尝试根据文件扩展名猜测 Content-Type
|
||||||
contentType := mime.TypeByExtension(filepath.Ext(cleanPath))
|
contentType := mime.TypeByExtension(path.Ext(cleanPath))
|
||||||
if contentType == "" {
|
if contentType == "" {
|
||||||
// 如果无法猜测,则使用默认的二进制流类型
|
// 如果无法猜测,则使用默认的二进制流类型
|
||||||
contentType = "application/octet-stream"
|
contentType = "application/octet-stream"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue