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 "git.arvados.org/arvados.git/sdk/go/httpserver"
15 "github.com/sirupsen/logrus"
18 func (cresp ConnectionResponse) ServeHTTP(w http.ResponseWriter, req *http.Request) {
19 defer cresp.Conn.Close()
20 conn, bufrw, err := http.NewResponseController(w).Hijack()
22 http.Error(w, "connection upgrade failed: "+err.Error(), http.StatusInternalServerError)
26 conn.Write([]byte("HTTP/1.1 101 Switching Protocols\r\n"))
27 w.Header().Set("Connection", "upgrade")
28 for k, v := range cresp.Header {
31 w.Header().Write(conn)
32 conn.Write([]byte("\r\n"))
33 httpserver.ExemptFromDeadline(req)
35 var bytesIn, bytesOut int64
36 ctx, cancel := context.WithCancel(req.Context())
42 n, err := io.CopyN(conn, cresp.Bufrw, int64(cresp.Bufrw.Reader.Buffered()))
45 n, err = io.Copy(conn, cresp.Conn)
49 ctxlog.FromContext(ctx).WithError(err).Error("error copying downstream")
56 n, err := io.CopyN(cresp.Conn, bufrw, int64(bufrw.Reader.Buffered()))
59 n, err = io.Copy(cresp.Conn, conn)
63 ctxlog.FromContext(ctx).WithError(err).Error("error copying upstream")
68 // Wait for both io.Copy goroutines to finish and increment
69 // their byte counters.
71 if cresp.Logger != nil {
72 cresp.Logger.WithFields(logrus.Fields{
75 }).Info("closed connection")