X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6eb3d1fb8fe71623fa63da46c250184cf2e4fbb8..4da1edec9c50c7adef8ab9fa500d5f3c40fb296f:/services/arv-git-httpd/server.go diff --git a/services/arv-git-httpd/server.go b/services/arv-git-httpd/server.go index 716b2760f3..38a018ab3d 100644 --- a/services/arv-git-httpd/server.go +++ b/services/arv-git-httpd/server.go @@ -1,105 +1,36 @@ +// 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 - running 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()) - srv.running = true - go func() { - err = srv.Serve(tcpKeepAliveListener{srv.listener}) - if !srv.wantDown { - srv.err = err - } - mutex.Lock() - srv.running = false - srv.cond.Broadcast() - mutex.Unlock() - }() - return nil -} - -// Wait returns when the server has shut down. -func (srv *server) Wait() error { - if srv.cond == nil { - return nil - } - srv.cond.L.Lock() - defer srv.cond.L.Unlock() - for srv.running { - 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() }