Skip to content

Commit

Permalink
Allow to pass url as X-Sendfile header value
Browse files Browse the repository at this point in the history
  • Loading branch information
rmikalkenas committed Feb 8, 2024
1 parent 6d38e0a commit ed3f73c
Showing 1 changed file with 46 additions and 26 deletions.
72 changes: 46 additions & 26 deletions plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,45 +111,66 @@ func (p *Plugin) Middleware(next http.Handler) http.Handler {
}
}

// do not allow paths like ../../resource, security
// only specified folder and resources in it
// see: https://lgtm.com/rules/1510366186013/
if strings.Contains(path, "..") {
w.WriteHeader(http.StatusForbidden)
return
}
var f io.ReadCloser
var size int64

// check if the file exists
fs, err := os.Stat(path)
if err != nil {
http.Error(w, "not found", http.StatusNotFound)
return
}
if strings.HasPrefix(path, "http") {
resp, err := http.Get(path)

Check failure on line 118 in plugin.go

View workflow job for this annotation

GitHub Actions / Golang-CI (lint)

G107: Potential HTTP request made with variable url (gosec)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

f, err := os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()

defer func() {
_ = f.Close()
}()
if resp.StatusCode != http.StatusOK {
http.Error(w, http.StatusText(resp.StatusCode), resp.StatusCode)
return
}

f = resp.Body
size = resp.ContentLength
} else {
// do not allow paths like ../../resource, security
// only specified folder and resources in it
// see: https://lgtm.com/rules/1510366186013/
if strings.Contains(path, "..") {
w.WriteHeader(http.StatusForbidden)
return
}

// check if the file exists
fs, err := os.Stat(path)
if err != nil {
http.Error(w, "not found", http.StatusNotFound)
return
}

f, err = os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

defer func() {
_ = f.Close()
}()

size = fs.Size()
}

size := fs.Size()
var buf []byte
// do not allocate large buffer for the small files
if size < int64(bufSize) {
if size > 0 && size < int64(bufSize) {
// allocate exact size
buf = make([]byte, size)
} else {
// allocate default 10mb buf
buf = make([]byte, bufSize)
}

off := 0
for {
n, err := f.ReadAt(buf, int64(off))
n, err := f.Read(buf)
if err != nil {
if errors.Is(err, io.EOF) {
if n > 0 {
Expand All @@ -176,7 +197,6 @@ func (p *Plugin) Middleware(next http.Handler) http.Handler {
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
off += n
}

w.Header().Set(ContentTypeKey, ContentTypeVal)
Expand Down

0 comments on commit ed3f73c

Please sign in to comment.