mirror of https://github.com/k3s-io/k3s
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
998 B
54 lines
998 B
5 years ago
|
package dqlite
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"net"
|
||
|
"net/http"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
"github.com/rancher/k3s/pkg/dqlite/pipe"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
upgradeResponse = []byte("HTTP/1.1 101 Switching Protocols\r\nUpgrade: dqlite\r\n\r\n")
|
||
|
)
|
||
|
|
||
|
type proxy struct {
|
||
|
conns chan net.Conn
|
||
|
}
|
||
|
|
||
|
func newProxy(ctx context.Context, bindAddress string) http.Handler {
|
||
|
p := &proxy{
|
||
|
conns: make(chan net.Conn, 100),
|
||
|
}
|
||
|
go func() {
|
||
|
<-ctx.Done()
|
||
|
close(p.conns)
|
||
|
}()
|
||
|
go pipe.UnixPiper(p.conns, bindAddress)
|
||
|
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func (h *proxy) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||
|
hijacker, ok := rw.(http.Hijacker)
|
||
|
if !ok {
|
||
|
http.Error(rw, "failed to hijack", http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
conn, _, err := hijacker.Hijack()
|
||
|
if err != nil {
|
||
|
err := errors.Wrap(err, "Hijack connection")
|
||
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if n, err := conn.Write(upgradeResponse); err != nil || n != len(upgradeResponse) {
|
||
|
conn.Close()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
h.conns <- conn
|
||
|
}
|