master
Raw Download raw file
  1package main
  2
  3import (
  4	"flag"
  5	"github.com/BurntSushi/toml"
  6	"io/ioutil"
  7	"log"
  8	"math/rand"
  9	"net/http"
 10	"os"
 11	"strconv"
 12	"time"
 13)
 14
 15// SERVER_CONFIG defines default for the server
 16type SERVER_CONFIG struct {
 17	// LISTEN_ADDRESS defines the local address on which to listen
 18	LISTEN_ADDRESS string
 19	//LISTEN_PORT defines the the port on which to listen
 20	LISTEN_PORT int
 21	// PERMIT_BLANK_PASSWORD determines if a password should be provided with the user names
 22	PERMIT_BLANK_PASSWORD bool
 23	// PRIVATE_KEY defines the path to the server's private key for signing https connections
 24	PRIVATE_KEY string
 25	// PRIVATE_CERT defines the path to the server certificate
 26	PRIVATE_CERT string
 27	// USE_HTTPS determines if the server should use HTTPS
 28	USE_HTTPS bool
 29	// QUESTIONS contains the path to the questions directory
 30	QUESTIONS string
 31	// USER_TESTS stores the test results of users
 32	USER_TESTS string
 33	// DB_ADDRESS contains the address of the database
 34	DB_ADDRESS string
 35	// DB_PORT contains the port on which to connect to the database
 36	DB_PORT int
 37}
 38
 39// defaultSERVER_CONFIG is used when no SERVER_CONFIGuration file is given
 40const defaultServerConfig = `
 41LISTEN_ADDRESS = "127.0.0.1"
 42LISTEN_PORT = 80
 43PERMIT_BLANK_PASSWORD = true
 44USE_HTTPS = false
 45PRIVATE_KEY = "~/.ssh/question.priv"
 46PRIVATE_CERT = "~/.ssh/server.crt"
 47QUESTIONS = "/path/to/questions"
 48USER_TESTS = "/path/to/tests"
 49`
 50
 51// the running configuration for the server
 52var serverConfig SERVER_CONFIG
 53
 54//loadServerConfiguration loads the configuration file
 55// cfgFile : the file that contains the configuration
 56func loadServerConfiguration(cfgFile string) SERVER_CONFIG {
 57	var contents string
 58	var config SERVER_CONFIG
 59	if cfgFile == "" {
 60		contents = defaultServerConfig
 61	} else {
 62		buffer, err := ioutil.ReadFile(cfgFile)
 63		if err != nil {
 64			log.Fatalf("Could not read configuration file: %+v\n", err.Error())
 65			os.Exit(EXIT_CODE.FILE_IO_ERROR)
 66		}
 67		contents = string(buffer)
 68	}
 69	if _, err := toml.Decode(contents, &config); err != nil {
 70		log.Fatalf("Could not parse configuration file: %+v\n", err.Error())
 71		os.Exit(EXIT_CODE.BAD_CONFIG)
 72	}
 73	return config
 74}
 75
 76// Listen binds the listening server and starts the listening loop
 77// serverConfig : contains the configuration to be used
 78func Listen(serverConfig SERVER_CONFIG) {
 79	// register the server handlers
 80	for _, handler := range handlers {
 81		http.HandleFunc(handler.Request, handler.HandleFunction)
 82	}
 83	if serverConfig.USE_HTTPS {
 84		// check
 85		// https://gist.github.com/denji/12b3a568f092ab951456
 86		log.Fatal(http.ListenAndServeTLS(
 87			serverConfig.LISTEN_ADDRESS+":"+
 88				strconv.Itoa(serverConfig.LISTEN_PORT),
 89			serverConfig.PRIVATE_CERT, serverConfig.PRIVATE_KEY,
 90			nil))
 91	} else {
 92		log.Fatal(http.ListenAndServe(
 93			serverConfig.LISTEN_ADDRESS+":"+
 94				strconv.Itoa(serverConfig.LISTEN_PORT),
 95			nil))
 96	}
 97}
 98
 99func ExecuteServer() {
100	var confFile string
101	flag.StringVar(&confFile, "file", "", "define a specific configuration file to read")
102	flag.StringVar(&confFile, "f", "", "define a specific configuration file to read")
103	flag.Parse()
104	serverConfig = loadServerConfiguration(confFile)
105	log.Printf("Configuration: %+v\n", serverConfig)
106	var err error
107	DBsession, err = InitDBSession()
108	if err != nil {
109		log.Printf("Fatal error connecting to DB: %+v", err)
110		return
111	}
112	log.Printf("Loaded %d categories from %s.", len(categories), serverConfig.QUESTIONS)
113	for _, cat := range categories {
114		log.Printf("Cat: %s", cat)
115	}
116	rand.Seed(time.Now().Unix())
117	Listen(serverConfig)
118}