server.go 2.52 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"
	"io"
	"net/http"
	"os"
	"strings"

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

type ApiHandler struct {
	log *logger.Logger
}

type Server struct {
	server *http.Server
	mux    *http.ServeMux
	log    *logger.Logger
	ctx    context.Context
}

func (handler *ApiHandler) ServeHTTP(
	response http.ResponseWriter,
	request *http.Request,
) {
	dirs := strings.Split(request.URL.Path, "/")
	switch dirs[0] {
	case "version":
		response.Header().Set("Content-Type", "application/json")
		v, err := version.Versions.Json()
		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}
	mux := http.NewServeMux()

	server = &Server{
		server: &http.Server{
			Addr: addr,
			Handler: mux,
		},
		mux: mux,
		log: log,
		ctx: context.Background(),
	}

	server.mux.Handle(
		"/",
		http.FileServer(http.Dir(os.Getenv("DOCUMENT_ROOT"))),
	)
	server.mux.Handle(
		"/api/0.0.1/",
		http.StripPrefix("/api/0.0.1/", &handler),
	)

	return
}

func (server *Server) Start() <-chan struct{} {
	done := make(chan struct{})
	go func(done chan struct{}) {
		server.log.Info("Listening on %s", server.server.Addr)
		if err := server.server.ListenAndServe();
			err != http.ErrServerClosed {
			server.log.LogError(err, "Stop listening")
		}
		close(done)
	}(done)
	return done
}

func (server *Server) Finish() {
	if err := server.server.Shutdown(server.ctx); err != nil {
		server.log.LogError(err, "Unclean server shutdown")
	} else {
		server.log.Info("Server stopped")
	}
}

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