server.go 2.69 KB
/*
This is some stuff...

Authors:
Georg Hopp <georg@steffers.org>

Changes:
2018-09-30 [Georg Hopp] File created.

Copyright © 2018 Georg Hopp

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package test

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"

	"gitlab.weird-web-workers.org/golang/logger"
)

type ApiHandler struct {
	log *logger.Logger
}

type version struct {
	Version string `json:"Version"`
	BuildCommit string `json:"BuildCommint"`
	BuildTime string `json:"BuildTimestamp"`
}

type Server struct {
	server *http.Server
	log    *logger.Logger
	Stop   chan bool
}

func (handler *ApiHandler) ServeHTTP(
	response http.ResponseWriter,
	request *http.Request,
) {
	dirs := strings.Split(request.URL.Path, "/")
	switch dirs[0] {
	case "version":
		v, err := json.Marshal(
			version{
				VERSION,
				REVISION,
				BUILD_TIME,
			},
		)
		if err != nil {
			http.Error(response, "Unable to encode version information", 500)
			return
		}
		io.WriteString(response, string(v[:]))
	default:
		http.NotFound(response, request)
		return
	}
}

func NewServer(addr string, log *logger.Logger) (server *Server) {
	handler := ApiHandler{log: log}

	http.Handle("/api/0.0.1/", http.StripPrefix("/api/0.0.1/", &handler))

	server = &Server{
		server: &http.Server{Addr: addr},
		log: log,
		Stop: make(chan bool),
	}
	go func() {
		server.log.Info("Listening on %s", addr)
		if err := server.server.ListenAndServe();
			err != http.ErrServerClosed {
			logger.Default.LogError(err, "Stop listening")
		}
	}()

	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
	go func() {
		for run, ok := true, true; run && ok; {
			select {
			case <-interrupt:
				server.log.Info("API service Interrupted by signal")
				run = false
			case run, ok = <-server.Stop:
				server.log.Info("API service stopped")
			}
		}

		ctx := context.Background()
		if err := server.server.Shutdown(ctx); err != nil {
			server.log.LogError(err, "Unclean server shutdown")
		} else {
			server.log.Info("Server stopped")
		}
		server.Stop <- true
	}()

	return
}

// vim: ts=4 sts=4 sw=4 noet tw=72: