Merge branch '18696-rnaseq-training' refs #18696
[arvados.git] / services / arv-git-httpd / server.go
index 393b6c414494c4ea5b01e66e9d618e28222888d5..38a018ab3d5189a9b60a33368b92ae62247112e3 100644 (file)
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
 package main
 
 import (
-       "net"
        "net/http"
-       "net/http/cgi"
-       "sync"
-       "time"
+
+       "git.arvados.org/arvados.git/sdk/go/arvados"
+       "git.arvados.org/arvados.git/sdk/go/health"
+       "git.arvados.org/arvados.git/sdk/go/httpserver"
 )
 
 type server struct {
-       http.Server
-       Addr     string // host:port where the server is listening.
-       err      error
-       cond     *sync.Cond
-       done     bool
-       listener *net.TCPListener
-       wantDown bool
+       httpserver.Server
+       cluster *arvados.Cluster
 }
 
 func (srv *server) Start() error {
-       gitHandler := &cgi.Handler{
-               Path: theConfig.GitCommand,
-               Dir:  theConfig.Root,
-               Env: []string{
-                       "GIT_PROJECT_ROOT=" + theConfig.Root,
-                       "GIT_HTTP_EXPORT_ALL=",
-               },
-               InheritEnv: []string{"PATH"},
-               Args:       []string{"http-backend"},
-       }
-
-       // The rest of the work here is essentially
-       // http.ListenAndServe() with two more features: (1) whoever
-       // called Start() can discover which address:port we end up
-       // listening to -- which makes listening on ":0" useful in
-       // test suites -- and (2) the server can be shut down without
-       // killing the process -- which is useful in test cases, and
-       // makes it possible to shut down gracefully on SIGTERM
-       // without killing active connections.
-
-       addr, err := net.ResolveTCPAddr("tcp", theConfig.Addr)
-       if err != nil {
-               return err
-       }
-       srv.listener, err = net.ListenTCP("tcp", addr)
-       if err != nil {
-               return err
-       }
-       srv.Addr = srv.listener.Addr().String()
        mux := http.NewServeMux()
-       mux.Handle("/", &authHandler{gitHandler})
-       srv.Handler = mux
-
-       mutex := &sync.RWMutex{}
-       srv.cond = sync.NewCond(mutex.RLocker())
-       go func() {
-               err = srv.Serve(tcpKeepAliveListener{srv.listener})
-               if !srv.wantDown {
-                       srv.err = err
-               }
-               mutex.Lock()
-               srv.done = true
-               srv.cond.Broadcast()
-               mutex.Unlock()
-       }()
-       return nil
-}
-
-// Wait returns when the server has shut down.
-func (srv *server) Wait() error {
-       srv.cond.L.Lock()
-       defer srv.cond.L.Unlock()
-       for !srv.done {
-               srv.cond.Wait()
+       mux.Handle("/", &authHandler{handler: newGitHandler(srv.cluster), cluster: srv.cluster})
+       mux.Handle("/_health/", &health.Handler{
+               Token:  srv.cluster.ManagementToken,
+               Prefix: "/_health/",
+       })
+
+       var listen arvados.URL
+       for listen = range srv.cluster.Services.GitHTTP.InternalURLs {
+               break
        }
-       return srv.err
-}
-
-// Close shuts down the server and returns when it has stopped.
-func (srv *server) Close() error {
-       srv.wantDown = true
-       srv.listener.Close()
-       return srv.Wait()
-}
 
-// tcpKeepAliveListener is copied from net/http because not exported.
-//
-type tcpKeepAliveListener struct {
-       *net.TCPListener
-}
-
-func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
-       tc, err := ln.AcceptTCP()
-       if err != nil {
-               return
-       }
-       tc.SetKeepAlive(true)
-       tc.SetKeepAlivePeriod(3 * time.Minute)
-       return tc, nil
+       srv.Handler = mux
+       srv.Addr = listen.Host
+       return srv.Server.Start()
 }