Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions drivers/quqi/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ func (d *Quqi) Put(ctx context.Context, dstDir model.Obj, stream model.FileStrea
// if the file already exists in Quqi server, there is no need to actually upload it
if uploadInitResp.Data.Exist {
// the file name returned by Quqi does not include the extension name
nodeName, nodeExt := uploadInitResp.Data.NodeName, rawExt(stream.GetName())
nodeName, nodeExt := uploadInitResp.Data.NodeName, utils.Ext(stream.GetName())
if nodeExt != "" {
nodeName = nodeName + "." + nodeExt
}
Expand Down Expand Up @@ -432,7 +432,7 @@ func (d *Quqi) Put(ctx context.Context, dstDir model.Obj, stream model.FileStrea
return nil, err
}
// the file name returned by Quqi does not include the extension name
nodeName, nodeExt := uploadFinishResp.Data.NodeName, rawExt(stream.GetName())
nodeName, nodeExt := uploadFinishResp.Data.NodeName, utils.Ext(stream.GetName())
if nodeExt != "" {
nodeName = nodeName + "." + nodeExt
}
Expand Down
11 changes: 0 additions & 11 deletions drivers/quqi/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"io"
"net/http"
"net/url"
stdpath "path"
"strings"
"time"

Expand Down Expand Up @@ -115,16 +114,6 @@ func (d *Quqi) checkLogin() bool {
return true
}

// rawExt 保留扩展名大小写
func rawExt(name string) string {
ext := stdpath.Ext(name)
if strings.HasPrefix(ext, ".") {
ext = ext[1:]
}

return ext
}

// decryptKey 获取密码
func decryptKey(encodeKey string) []byte {
// 移除非法字符
Expand Down
4 changes: 1 addition & 3 deletions drivers/vtencent/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import (
"fmt"
"io"
"net/http"
"path"
"strconv"
"strings"

"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
Expand Down Expand Up @@ -151,7 +149,7 @@ func (d *Vtencent) ApplyUploadUGC(signature string, stream model.FileStreamer) (
form := base.Json{
"signature": signature,
"videoName": stream.GetName(),
"videoType": strings.ReplaceAll(path.Ext(stream.GetName()), ".", ""),
"videoType": utils.Ext(stream.GetName()),
"videoSize": stream.GetSize(),
}
var resps RspApplyUploadUGC
Expand Down
5 changes: 2 additions & 3 deletions internal/net/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -619,10 +619,9 @@ type Buf struct {
// NewBuf is a buffer that can have 1 read & 1 write at the same time.
// when read is faster write, immediately feed data to read after written
func NewBuf(ctx context.Context, maxSize int) *Buf {
d := make([]byte, 0, maxSize)
return &Buf{
ctx: ctx,
buffer: bytes.NewBuffer(d),
buffer: bytes.NewBuffer(make([]byte, 0, maxSize)),
size: maxSize,
}
}
Expand Down Expand Up @@ -677,5 +676,5 @@ func (br *Buf) Write(p []byte) (n int, err error) {
}

func (br *Buf) Close() {
br.buffer.Reset()
br.buffer = nil
}
2 changes: 1 addition & 1 deletion pkg/utils/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func IsSubPath(path string, subPath string) bool {

func Ext(path string) string {
ext := stdpath.Ext(path)
if strings.HasPrefix(ext, ".") {
if len(ext) > 0 && ext[0] == '.' {
ext = ext[1:]
}
return strings.ToLower(ext)
Expand Down
80 changes: 3 additions & 77 deletions server/common/proxy.go
Original file line number Diff line number Diff line change
@@ -1,97 +1,25 @@
package common

import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strconv"
"strings"

"github.com/alist-org/alist/v3/internal/conf"
"maps"

"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/net"
"github.com/alist-org/alist/v3/internal/setting"
"github.com/alist-org/alist/v3/internal/stream"
"github.com/alist-org/alist/v3/pkg/http_range"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/microcosm-cc/bluemonday"
log "github.com/sirupsen/logrus"
"github.com/yuin/goldmark"
)

func processMarkdown(content []byte) ([]byte, error) {
var buf bytes.Buffer
if err := goldmark.New().Convert(content, &buf); err != nil {
return nil, fmt.Errorf("markdown conversion failed: %w", err)
}
return bluemonday.UGCPolicy().SanitizeBytes(buf.Bytes()), nil
}

func Proxy(w http.ResponseWriter, r *http.Request, link *model.Link, file model.Obj) error {

//优先处理md文件
if utils.Ext(file.GetName()) == "md" && setting.GetBool(conf.FilterReadMeScripts) {
var markdownContent []byte
var err error

if link.MFile != nil {
defer link.MFile.Close()
attachHeader(w, file)
markdownContent, err = io.ReadAll(link.MFile)
if err != nil {
return fmt.Errorf("failed to read markdown content: %w", err)
}
} else if link.RangeReadCloser != nil {
attachHeader(w, file)
rrc, err := link.RangeReadCloser.RangeRead(r.Context(), http_range.Range{Start: 0, Length: -1})
if err != nil {
return err
}
defer rrc.Close()
markdownContent, err = io.ReadAll(rrc)
if err != nil {
return fmt.Errorf("failed to read markdown content: %w", err)
}
} else {
header := net.ProcessHeader(r.Header, link.Header)
res, err := net.RequestHttp(r.Context(), r.Method, header, link.URL)
if err != nil {
return err
}
defer res.Body.Close()
for h, v := range res.Header {
w.Header()[h] = v
}
w.WriteHeader(res.StatusCode)
if r.Method == http.MethodHead {
return nil
}
markdownContent, err = io.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read markdown content: %w", err)
}

}

safeHTML, err := processMarkdown(markdownContent)
if err != nil {
return err
}

safeHTMLReader := bytes.NewReader(safeHTML)
w.Header().Set("Content-Length", strconv.FormatInt(int64(len(safeHTML)), 10))
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_, err = utils.CopyWithBuffer(w, safeHTMLReader)
if err != nil {
return err
}
return nil
}

if link.MFile != nil {
defer link.MFile.Close()
attachHeader(w, file)
Expand Down Expand Up @@ -152,9 +80,7 @@ func Proxy(w http.ResponseWriter, r *http.Request, link *model.Link, file model.
}
defer res.Body.Close()

for h, v := range res.Header {
w.Header()[h] = v
}
maps.Copy(w.Header(), res.Header)
w.WriteHeader(res.StatusCode)
if r.Method == http.MethodHead {
return nil
Expand Down
43 changes: 42 additions & 1 deletion server/handles/down.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package handles

import (
"bytes"
"fmt"
"io"
"net/http"
stdpath "path"
"strconv"
"strings"

"github.com/alist-org/alist/v3/internal/conf"
Expand All @@ -15,7 +18,9 @@ import (
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/alist-org/alist/v3/server/common"
"github.com/gin-gonic/gin"
"github.com/microcosm-cc/bluemonday"
log "github.com/sirupsen/logrus"
"github.com/yuin/goldmark"
)

func Down(c *gin.Context) {
Expand Down Expand Up @@ -124,7 +129,34 @@ func localProxy(c *gin.Context, link *model.Link, file model.Obj, proxyRange boo
if proxyRange {
common.ProxyRange(link, file.GetSize())
}
err = common.Proxy(c.Writer, c.Request, link, file)

//优先处理md文件
if utils.Ext(file.GetName()) == "md" && setting.GetBool(conf.FilterReadMeScripts) {
w := c.Writer
buf := bytes.NewBuffer(make([]byte, 0, file.GetSize()))
err = common.Proxy(&proxyResponseWriter{ResponseWriter: w, Writer: buf}, c.Request, link, file)
if err == nil && buf.Len() > 0 {
if w.Status() < 200 || w.Status() > 300 {
w.Write(buf.Bytes())
return
}

var html bytes.Buffer
if err = goldmark.Convert(buf.Bytes(), &html); err != nil {
err = fmt.Errorf("markdown conversion failed: %w", err)
} else {
buf.Reset()
err = bluemonday.UGCPolicy().SanitizeReaderToWriter(&html, buf)
if err == nil {
w.Header().Set("Content-Length", strconv.FormatInt(int64(buf.Len()), 10))
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_, err = utils.CopyWithBuffer(c.Writer, buf)
}
}
}
} else {
err = common.Proxy(c.Writer, c.Request, link, file)
}
if err != nil {
common.ErrorResp(c, err, 500, true)
return
Expand All @@ -150,3 +182,12 @@ func canProxy(storage driver.Driver, filename string) bool {
}
return false
}

type proxyResponseWriter struct {
http.ResponseWriter
io.Writer
}

func (pw *proxyResponseWriter) Write(p []byte) (int, error) {
return pw.Writer.Write(p)
}
Loading