write status then hijack (#126)
This commit is contained in:
parent
02be81e696
commit
822a51a0cf
1 changed files with 8 additions and 30 deletions
|
|
@ -585,45 +585,23 @@ func serveHiddenPage(w http.ResponseWriter, authErr error) error {
|
||||||
// Hijacks the connection from ResponseWriter, writes the response and proxies data between targetConn
|
// Hijacks the connection from ResponseWriter, writes the response and proxies data between targetConn
|
||||||
// and hijacked connection.
|
// and hijacked connection.
|
||||||
func serveHijack(w http.ResponseWriter, targetConn net.Conn) error {
|
func serveHijack(w http.ResponseWriter, targetConn net.Conn) error {
|
||||||
clientConn, bufReader, err := http.NewResponseController(w).Hijack()
|
w.WriteHeader(http.StatusOK)
|
||||||
|
clientConn, brw, err := http.NewResponseController(w).Hijack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return caddyhttp.Error(http.StatusInternalServerError,
|
return caddyhttp.Error(http.StatusInternalServerError,
|
||||||
fmt.Errorf("hijack failed: %v", err))
|
fmt.Errorf("hijack failed: %v", err))
|
||||||
}
|
}
|
||||||
defer clientConn.Close()
|
defer clientConn.Close()
|
||||||
// bufReader may contain unprocessed buffered data from the client.
|
// bufReader may contain unprocessed buffered data from the client.
|
||||||
if bufReader != nil {
|
// snippet borrowed from `proxy` plugin
|
||||||
// snippet borrowed from `proxy` plugin
|
if n := brw.Reader.Buffered(); n > 0 {
|
||||||
if n := bufReader.Reader.Buffered(); n > 0 {
|
rbuf, _ := brw.Peek(n)
|
||||||
rbuf, err := bufReader.Reader.Peek(n)
|
_, _ = targetConn.Write(rbuf)
|
||||||
if err != nil {
|
|
||||||
return caddyhttp.Error(http.StatusBadGateway, err)
|
|
||||||
}
|
|
||||||
_, _ = targetConn.Write(rbuf)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Since we hijacked the connection, we lost the ability to write and flush headers via w.
|
err = brw.Flush()
|
||||||
// Let's handcraft the response and send it manually.
|
|
||||||
res := &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Proto: "HTTP/1.1",
|
|
||||||
ProtoMajor: 1,
|
|
||||||
ProtoMinor: 1,
|
|
||||||
Header: make(http.Header),
|
|
||||||
}
|
|
||||||
res.Header.Set("Server", "Caddy")
|
|
||||||
|
|
||||||
buf := bufio.NewWriter(clientConn)
|
|
||||||
err = res.Write(buf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return caddyhttp.Error(http.StatusInternalServerError,
|
return caddyhttp.Error(http.StatusInternalServerError,
|
||||||
fmt.Errorf("failed to write response: %v", err))
|
fmt.Errorf("failed to flush to client: %v", err))
|
||||||
}
|
|
||||||
err = buf.Flush()
|
|
||||||
if err != nil {
|
|
||||||
return caddyhttp.Error(http.StatusInternalServerError,
|
|
||||||
fmt.Errorf("failed to send response to client: %v", err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dualStream(targetConn, clientConn, clientConn)
|
return dualStream(targetConn, clientConn, clientConn)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue