func onStopServer() {
	<-osSignal
	cache.ClosePool()
	os.Exit(0)
}
Listens for OS signals and executes the shutdown logic
package server
import (
	"encoding/csv"
	"encoding/json"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"github.com/RohitAwate/OAuth2Bin/oauth2/cache"
	"github.com/RohitAwate/OAuth2Bin/oauth2/config"
	"github.com/RohitAwate/OAuth2Bin/oauth2/middleware"
)
type OA2Server struct {
	Port    string
	Config  config.OA2Config
	Limiter middleware.RateLimiter
}
var serverConfig config.OA2Config
func NewOA2Server(port string, serverConfigPath string, ratePoliciesPath string) *OA2Server {
	serverConfig = *getServerConfig(serverConfigPath)
	return &OA2Server{
		Port:   port,
		Config: serverConfig,
		Limiter: middleware.RateLimiter{
			Policies: getRatePolicies(ratePoliciesPath),
		},
	}
}
func (s *OA2Server) SetRateLimiter(policies []middleware.RatePolicy) {
	s.Limiter = middleware.RateLimiter{Policies: policies}
}
func (s *OA2Server) Start() {
	s.setupRoutes()
	setupGracefulShutdown()
	log.Printf("OAuth 2.0 Server has started on port %s\n", s.Port)
	err := http.ListenAndServe(":"+s.Port, nil)
	if err != nil && err != http.ErrServerClosed {
		log.Fatalf("Could not start server on port %s\n", s.Port)
	}
}
func (s *OA2Server) chainCommonMiddleware(pattern string, handler http.HandlerFunc, extras ...middleware.Middleware) {
	middlewareSlice := []middleware.Middleware{s.Limiter, middleware.NewNotFoundMiddleware(pattern)}
	middlewareSlice = append(middlewareSlice, extras...)
	chain := middleware.Chain(handler, middlewareSlice...)
	http.HandleFunc(pattern, chain)
}
func (s *OA2Server) setupRoutes() {
	public := http.FileServer(http.Dir("public/"))
	http.Handle("/public/", http.StripPrefix("/public/", public))
	s.chainCommonMiddleware("/", s.handleHome)
	s.chainCommonMiddleware("/authorize", handleAuth)
	s.chainCommonMiddleware("/response", handleResponse, middleware.NewPostFormValidator(true))
	s.chainCommonMiddleware("/token", handleToken, middleware.NewPostFormValidator(false))
	s.chainCommonMiddleware("/echo", handleEcho)
}
func (s *OA2Server) handleHome(w http.ResponseWriter, r *http.Request) {
	tmpl, err := template.ParseFiles(
		"public/templates/index.html",
		"public/templates/nav.html",
		"public/templates/cards.html",
		"public/templates/footer.html",
	)
	if err != nil {
		log.Fatal(err)
	}
	err = tmpl.ExecuteTemplate(w, "home", s.Config)
	if err != nil {
		log.Fatal(err)
	}
}
var osSignal chan os.Signal
func setupGracefulShutdown() {
	osSignal = make(chan os.Signal)
	signal.Notify(osSignal, syscall.SIGTERM)
	signal.Notify(osSignal, syscall.SIGINT)
	go onStopServer()
}