Skip to content

Commit 95f50f0

Browse files
author
CuteSocks
authored
Fix Caddy v2.7.x runtime error: ResponseWriter doesn't http.Flusher (#7)
1 parent ecaa8b9 commit 95f50f0

1 file changed

Lines changed: 10 additions & 15 deletions

File tree

forwardproxy.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"errors"
2727
"fmt"
2828
"io"
29-
"io/ioutil"
3029
"math/rand"
3130
"net"
3231
"net/http"
@@ -50,7 +49,7 @@ func init() {
5049

5150
// Used for generating padding lengths. Not needed to be cryptographically secure.
5251
// Does not care about double seeding.
53-
rand.Seed(time.Now().UnixNano())
52+
rand.New(rand.NewSource(time.Now().UnixNano()))
5453
}
5554

5655
// Handler implements a forward proxy.
@@ -292,11 +291,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
292291
}
293292

294293
// HTTP CONNECT Fast Open. We merely close the connection if Open fails.
295-
wFlusher, ok := w.(http.Flusher)
296-
if !ok {
297-
return caddyhttp.Error(http.StatusInternalServerError,
298-
fmt.Errorf("ResponseWriter doesn't implement http.Flusher"))
299-
}
294+
rc := http.NewResponseController(w)
300295
// Creates a padding of [30, 30+32)
301296
paddingLen := rand.Intn(32) + 30
302297
padding := make([]byte, paddingLen)
@@ -311,7 +306,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
311306
}
312307
w.Header().Set("Padding", string(padding))
313308
w.WriteHeader(http.StatusOK)
314-
wFlusher.Flush()
309+
err := rc.Flush()
310+
if err != nil {
311+
return caddyhttp.Error(http.StatusInternalServerError, fmt.Errorf(err.Error()))
312+
}
315313

316314
hostPort := r.URL.Host
317315
if hostPort == "" {
@@ -375,13 +373,13 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
375373
// make sure request is idempotent and could be retried by saving the Body
376374
// None of those methods are supposed to have body,
377375
// but we still need to copy the r.Body, even if it's empty
378-
rBodyBuf, err := ioutil.ReadAll(r.Body)
376+
rBodyBuf, err := io.ReadAll(r.Body)
379377
if err != nil {
380378
return caddyhttp.Error(http.StatusBadRequest,
381379
fmt.Errorf("failed to read request body: %v", err))
382380
}
383381
r.GetBody = func() (io.ReadCloser, error) {
384-
return ioutil.NopCloser(bytes.NewReader(rBodyBuf)), nil
382+
return io.NopCloser(bytes.NewReader(rBodyBuf)), nil
385383
}
386384
r.Body, _ = r.GetBody()
387385
}
@@ -578,11 +576,8 @@ func serveHiddenPage(w http.ResponseWriter, authErr error) error {
578576
// Hijacks the connection from ResponseWriter, writes the response and proxies data between targetConn
579577
// and hijacked connection.
580578
func serveHijack(w http.ResponseWriter, targetConn net.Conn) error {
581-
hijacker, ok := w.(http.Hijacker)
582-
if !ok {
583-
return caddyhttp.Error(http.StatusInternalServerError,
584-
fmt.Errorf("ResponseWriter does not implement http.Hijacker"))
585-
}
579+
hijacker := http.NewResponseController(w)
580+
586581
clientConn, bufReader, err := hijacker.Hijack()
587582
if err != nil {
588583
return caddyhttp.Error(http.StatusInternalServerError,

0 commit comments

Comments
 (0)