Skip to content

Commit

Permalink
try to use sendfile when encode is enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
WeidiDeng committed Dec 19, 2024
1 parent 6790c0e commit 1e1daf9
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions modules/caddyhttp/encode/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,49 @@ func (rw *responseWriter) Write(p []byte) (int, error) {
}
}

type writerOnly struct {
io.Writer
}

// copied from stdlib
const sniffLen = 512

// ReadFrom will try to use sendfile to copy from the reader to the response writer.
// It's only used if the response writer implements io.ReaderFrom and the data can't be compressed.
// It's based on stdlin http1.1 response writer implementation.
// https://github.com/golang/go/blob/f4e3ec3dbe3b8e04a058d266adf8e048bab563f2/src/net/http/server.go#L586
func (rw *responseWriter) ReadFrom(r io.Reader) (int64, error) {
// WriteHeader wasn't called and is a CONNECT request, treat it as a success.
// otherwise, determine if the response should be compressed.
if rw.isConnect && !rw.wroteHeader && rw.statusCode == 0 {
rw.WriteHeader(http.StatusOK)
}

rr, ok := rw.ResponseWriter.(io.ReaderFrom)
// sendfile can't be used anyway
if !ok {
return io.Copy(writerOnly{rw}, r)
}

var ns int64
// try to sniff the content type and determine if the response should be compressed
if !rw.wroteHeader && rw.config.MinLength > 0 {
var err error
ns, err = io.Copy(writerOnly{rw}, io.LimitReader(r, sniffLen))
if err != nil || ns < sniffLen {
return ns, err
}
}

// the response will be compressed, no sendfile support
if rw.w != nil {
nr, err := io.Copy(rw.w, r)
return nr + ns, err
}
nr, err := rr.ReadFrom(r)
return nr + ns, err
}

// Close writes any remaining buffered response and
// deallocates any active resources.
func (rw *responseWriter) Close() error {
Expand Down

0 comments on commit 1e1daf9

Please sign in to comment.