1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
13 "git.arvados.org/arvados.git/sdk/go/ctxlog"
14 "github.com/sirupsen/logrus"
17 func (cresp ConnectionResponse) ServeHTTP(w http.ResponseWriter, req *http.Request) {
18 defer cresp.Conn.Close()
19 hj, ok := w.(http.Hijacker)
21 http.Error(w, "ResponseWriter does not support connection upgrade", http.StatusInternalServerError)
24 w.Header().Set("Connection", "upgrade")
25 for k, v := range cresp.Header {
28 w.WriteHeader(http.StatusSwitchingProtocols)
29 conn, bufrw, err := hj.Hijack()
31 ctxlog.FromContext(req.Context()).WithError(err).Error("error hijacking ResponseWriter")
36 var bytesIn, bytesOut int64
37 ctx, cancel := context.WithCancel(req.Context())
43 n, err := io.CopyN(conn, cresp.Bufrw, int64(cresp.Bufrw.Reader.Buffered()))
46 n, err = io.Copy(conn, cresp.Conn)
50 ctxlog.FromContext(ctx).WithError(err).Error("error copying downstream")
57 n, err := io.CopyN(cresp.Conn, bufrw, int64(bufrw.Reader.Buffered()))
60 n, err = io.Copy(cresp.Conn, conn)
64 ctxlog.FromContext(ctx).WithError(err).Error("error copying upstream")
69 // Wait for both io.Copy goroutines to finish and increment
70 // their byte counters.
72 if cresp.Logger != nil {
73 cresp.Logger.WithFields(logrus.Fields{
76 }).Info("closed connection")