<commit_before>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strings"

	"github.com/oal/timeplan-uia/utils"

	"github.com/flosch/pongo2"
	"github.com/gocraft/web"
)

var timetables = []string{}

var tplIndex = pongo2.Must(pongo2.FromFile("templates/index.html"))

type Context struct{}

func (c *Context) Index(w web.ResponseWriter, r *web.Request) {
	err := tplIndex.ExecuteWriter(pongo2.Context{
		"timetables": timetables,
	}, w)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func (c *Context) CSV(w web.ResponseWriter, r *web.Request) {
	file := r.PathParams["file"]
	lastSlash := strings.LastIndex(file, "/")
	if lastSlash != -1 {
		file = file[lastSlash:]
	}

	f, err := os.Open("timeplaner/v2015/" + file)
	if err != nil {
		return
	}

	defer f.Close()
	io.Copy(w, f)
}

func (c *Context) ICal(w web.ResponseWriter, r *web.Request) {
	file := r.PathParams["file"]
	lastSlash := strings.LastIndex(file, "/")
	if lastSlash != -1 {
		file = file[lastSlash:]
	}

	file = file[0 : len(file)-5]

	data, err := utils.ToICal(fmt.Sprintf("timeplaner/v2015/%v.csv", file))
	if err != nil {
		return
	}

	w.Write([]byte(data))
}

func startServer() {
	files, err := ioutil.ReadDir("timeplaner/v2015")
	if err != nil {
		panic(err)
	}

	for _, f := range files {
		name := f.Name()
		name = name[0:strings.LastIndex(name, ".")]
		timetables = append(timetables, name)
	}

	router := web.New(Context{}).
		Middleware(web.LoggerMiddleware).
		Get("/", (*Context).Index).
		Get("/csv/:file", (*Context).CSV).
		Get("/ical/:file", (*Context).ICal)
	http.ListenAndServe("localhost:15103", router) // Start the server!
}
<commit_msg>Fiks ip.<commit_after>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strings"

	"github.com/oal/timeplan-uia/utils"

	"github.com/flosch/pongo2"
	"github.com/gocraft/web"
)

var timetables = []string{}

var tplIndex = pongo2.Must(pongo2.FromFile("templates/index.html"))

type Context struct{}

func (c *Context) Index(w web.ResponseWriter, r *web.Request) {
	err := tplIndex.ExecuteWriter(pongo2.Context{
		"timetables": timetables,
	}, w)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func (c *Context) CSV(w web.ResponseWriter, r *web.Request) {
	file := r.PathParams["file"]
	lastSlash := strings.LastIndex(file, "/")
	if lastSlash != -1 {
		file = file[lastSlash:]
	}

	f, err := os.Open("timeplaner/v2015/" + file)
	if err != nil {
		return
	}

	defer f.Close()
	io.Copy(w, f)
}

func (c *Context) ICal(w web.ResponseWriter, r *web.Request) {
	file := r.PathParams["file"]
	lastSlash := strings.LastIndex(file, "/")
	if lastSlash != -1 {
		file = file[lastSlash:]
	}

	file = file[0 : len(file)-5]

	data, err := utils.ToICal(fmt.Sprintf("timeplaner/v2015/%v.csv", file))
	if err != nil {
		return
	}

	w.Write([]byte(data))
}

func startServer() {
	files, err := ioutil.ReadDir("timeplaner/v2015")
	if err != nil {
		panic(err)
	}

	for _, f := range files {
		name := f.Name()
		name = name[0:strings.LastIndex(name, ".")]
		timetables = append(timetables, name)
	}

	router := web.New(Context{}).
		Middleware(web.LoggerMiddleware).
		Get("/", (*Context).Index).
		Get("/csv/:file", (*Context).CSV).
		Get("/ical/:file", (*Context).ICal)
	http.ListenAndServe("0.0.0.0:15103", router) // Start the server!
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"

	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/golang/glog"
	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/gorilla/context"

	"github.com/prashanthrv/sangeeblog/controllers"
	"github.com/prashanthrv/sangeeblog/system"

	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/zenazn/goji"
	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/zenazn/goji/graceful"
	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/zenazn/goji/web"
	//"golang.org/x/net/http2"
)

func main() {
	// filename := flag.String("config", "config.toml", "Path to configuration file")
	//
	// flag.Parse()
	filename := "config.toml"
	defer glog.Flush()

	var application = &system.Application{}

	application.Init(filename)
	application.LoadTemplates()

	// Setup static files
	static := web.New()
	publicPath := application.Config.Get("general.public_path").(string)
	static.Get("/assets/*", http.StripPrefix("/assets/", http.FileServer(http.Dir(publicPath))))

	http.Handle("/assets/", static)

	// Apply middleware
	goji.Use(application.ApplyTemplates)
	goji.Use(application.ApplySessions)
	//goji.Use(application.ApplyDbMap)
	goji.Use(application.ApplyGormDB)
	//goji.Use(application.ApplyAuth)
	goji.Use(application.ApplyIsXhr)
	goji.Use(application.ApplyCsrfProtection)
	goji.Use(context.ClearHandler)

	controller := &controllers.MainController{}

	// Couple of files - in the real world you would use nginx to serve them.
	goji.Get("/robots.txt", http.FileServer(http.Dir(publicPath)))
	goji.Get("/favicon.ico", http.FileServer(http.Dir(publicPath+"/images")))

	// Home page
	goji.Get("/", application.Route(controller, "Blog"))

	// Sign In routes
	goji.Get("/signin", application.Route(controller, "SignIn"))
	goji.Post("/signin", application.Route(controller, "SignInPost"))

	// Sign Up routes
	goji.Get("/signup", application.Route(controller, "SignUp"))
	goji.Post("/signup", application.Route(controller, "SignUpPost"))

	// KTHXBYE
	goji.Get("/logout", application.Route(controller, "Logout"))

	goji.Get("/blog", application.Route(controller, "Blog"))
	goji.Get("/post/:postid", application.Route(controller, "Post"))
	goji.Get("/category/:categoryid", application.Route(controller, "Categories"))
	goji.Get("/page/:pageid", application.Route(controller, "Pages"))

	graceful.PostHook(func() {
		application.Close()
	})
	goji.Serve()
	//http2.ConfigureServer(http, &http2.Server{})
}
<commit_msg>String issue fixed.<commit_after>package main

import (
	"net/http"

	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/golang/glog"
	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/gorilla/context"

	"github.com/prashanthrv/sangeeblog/controllers"
	"github.com/prashanthrv/sangeeblog/system"

	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/zenazn/goji"
	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/zenazn/goji/graceful"
	"github.com/prashanthrv/sangeeblog/Godeps/_workspace/src/github.com/zenazn/goji/web"
	//"golang.org/x/net/http2"
)

func main() {
	// filename := flag.String("config", "config.toml", "Path to configuration file")
	//
	// flag.Parse()
	filename := "config.toml"
	defer glog.Flush()

	var application = &system.Application{}

	application.Init(&filename)
	application.LoadTemplates()

	// Setup static files
	static := web.New()
	publicPath := application.Config.Get("general.public_path").(string)
	static.Get("/assets/*", http.StripPrefix("/assets/", http.FileServer(http.Dir(publicPath))))

	http.Handle("/assets/", static)

	// Apply middleware
	goji.Use(application.ApplyTemplates)
	goji.Use(application.ApplySessions)
	//goji.Use(application.ApplyDbMap)
	goji.Use(application.ApplyGormDB)
	//goji.Use(application.ApplyAuth)
	goji.Use(application.ApplyIsXhr)
	goji.Use(application.ApplyCsrfProtection)
	goji.Use(context.ClearHandler)

	controller := &controllers.MainController{}

	// Couple of files - in the real world you would use nginx to serve them.
	goji.Get("/robots.txt", http.FileServer(http.Dir(publicPath)))
	goji.Get("/favicon.ico", http.FileServer(http.Dir(publicPath+"/images")))

	// Home page
	goji.Get("/", application.Route(controller, "Blog"))

	// Sign In routes
	goji.Get("/signin", application.Route(controller, "SignIn"))
	goji.Post("/signin", application.Route(controller, "SignInPost"))

	// Sign Up routes
	goji.Get("/signup", application.Route(controller, "SignUp"))
	goji.Post("/signup", application.Route(controller, "SignUpPost"))

	// KTHXBYE
	goji.Get("/logout", application.Route(controller, "Logout"))

	goji.Get("/blog", application.Route(controller, "Blog"))
	goji.Get("/post/:postid", application.Route(controller, "Post"))
	goji.Get("/category/:categoryid", application.Route(controller, "Categories"))
	goji.Get("/page/:pageid", application.Route(controller, "Pages"))

	graceful.PostHook(func() {
		application.Close()
	})
	goji.Serve()
	//http2.ConfigureServer(http, &http2.Server{})
}
<|endoftext|>


<commit_before>package bla

import (
	"crypto/tls"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/lucas-clemente/quic-go/h2quic"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"

	ini "gopkg.in/ini.v1"
)

var (
	logPool = sync.Pool{New: func() interface{} { return &LogWriter{nil, 200} }}

	tlsCert *tls.Certificate
	server  *http.Server
	cfg     *ServerConfig

	httpRequestCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "http",
			Subsystem: "requests",
			Name:      "total",
			Help:      "The total number of http request",
		},
		[]string{"handler"})

	httpRequestDurationSeconds = prometheus.NewSummary(
		prometheus.SummaryOpts{
			Namespace: "http",
			Subsystem: "request",
			Name:      "duration_seconds",
			Help:      "The request duration distribution",
		})
)

func listenMetric(addr string) {
	log.Printf("prometheus metric at %s/%s", addr, "metrics")
	prometheus.MustRegister(httpRequestCount)
	prometheus.MustRegister(httpRequestDurationSeconds)
	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(addr, nil)
}

// Config ---------------------

type ServerConfig struct {
	Certfile         string
	Keyfile          string
	Listen           string
	MetricListenAddr string
	AccessLogPath    string
}

func ListenAndServe(cfgPath string) {
	raw, err := ini.Load(cfgPath)
	if err != nil {
		log.Fatal(err)
	}

	cfg = &ServerConfig{
		"", "",
		":8080",
		"",
		"access.log",
	}

	raw.MapTo(cfg)

	log.Printf("pid:%d", os.Getpid())

	if cfg.MetricListenAddr != "" {
		go listenMetric(cfg.MetricListenAddr)
	}

	log.Printf("Server:%v", cfg)

	h := NewHandler(cfgPath)
	lh := logTimeAndStatus(cfg, h)
	server := &http.Server{Handler: lh, Addr: cfg.Listen}

	if cfg.Certfile != "" && cfg.Keyfile != "" {
		LoadCertificate()
		quic := &h2quic.Server{Server: server}
		quic.TLSConfig = &tls.Config{}
		quic.TLSConfig.GetCertificate = getCertificate

		pln, err := net.ListenPacket("udp", cfg.Listen)
		if err != nil {
			log.Fatal(err)
		}
		log.Print("listen quic on udp:%s", cfg.Listen)
		go quic.Serve(pln)

		// for higher score in ssllab
		log.Fatal(server.ListenAndServeTLS(cfg.Certfile, cfg.Keyfile))
	}
	server.ListenAndServe()
}

type LogWriter struct {
	http.ResponseWriter
	statusCode int
}

func (l *LogWriter) WriteHeader(i int) {
	l.statusCode = i
	l.ResponseWriter.WriteHeader(i)

}
func logTimeAndStatus(cfg *ServerConfig, handler http.Handler) http.Handler {

	var (
		writer io.Writer
		err    error
	)

	if cfg.AccessLogPath != "" {
		var file *os.File
		file, err = os.OpenFile(cfg.AccessLogPath,
			os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
		if err != nil {
			log.Fatal(err)
		}
		writer = file
		log.Printf("Access Log to file: %s", cfg.AccessLogPath)
		file.Seek(0, os.SEEK_END)
	} else {
		writer = os.Stdout
	}

	accessLogger := log.New(writer, "", log.LstdFlags)

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()

		writer := logPool.Get().(*LogWriter)
		writer.ResponseWriter = w
		writer.statusCode = 200

		if cfg.Certfile != "" {
			writer.ResponseWriter.Header().Add("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
		}
		handler.ServeHTTP(writer, r)

		delta := time.Since(start)

		accessLogger.Printf(`%s %s %s %s %d "%s"`,
			r.RemoteAddr, r.Method, r.URL.Path,
			delta, writer.statusCode, r.UserAgent())

		httpRequestDurationSeconds.Observe(delta.Seconds())

		logPool.Put(writer)
	})
}

func LoadCertificate() {

	log.Println("Loading new certs")
	cert, err := tls.LoadX509KeyPair(cfg.Certfile, cfg.Keyfile)
	if err != nil {
		log.Println("load cert failed keep old", err)
		return
	}
	tlsCert = &cert
}

func getCertificate(ch *tls.ClientHelloInfo) (cert *tls.Certificate, err error) {
	return tlsCert, nil
}
<commit_msg>quic header<commit_after>package bla

import (
	"crypto/tls"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/lucas-clemente/quic-go/h2quic"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"

	ini "gopkg.in/ini.v1"
)

var (
	logPool = sync.Pool{New: func() interface{} { return &LogWriter{nil, 200} }}

	tlsCert *tls.Certificate
	server  *http.Server
	cfg     *ServerConfig

	httpRequestCount = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "http",
			Subsystem: "requests",
			Name:      "total",
			Help:      "The total number of http request",
		},
		[]string{"handler"})

	httpRequestDurationSeconds = prometheus.NewSummary(
		prometheus.SummaryOpts{
			Namespace: "http",
			Subsystem: "request",
			Name:      "duration_seconds",
			Help:      "The request duration distribution",
		})
)

func listenMetric(addr string) {
	log.Printf("prometheus metric at %s/%s", addr, "metrics")
	prometheus.MustRegister(httpRequestCount)
	prometheus.MustRegister(httpRequestDurationSeconds)
	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(addr, nil)
}

// Config ---------------------

type ServerConfig struct {
	Certfile         string
	Keyfile          string
	Listen           string
	MetricListenAddr string
	AccessLogPath    string
}

func ListenAndServe(cfgPath string) {
	raw, err := ini.Load(cfgPath)
	if err != nil {
		log.Fatal(err)
	}

	cfg = &ServerConfig{
		"", "",
		":8080",
		"",
		"access.log",
	}

	raw.MapTo(cfg)

	log.Printf("pid:%d", os.Getpid())

	if cfg.MetricListenAddr != "" {
		go listenMetric(cfg.MetricListenAddr)
	}

	log.Printf("Server:%v", cfg)

	h := NewHandler(cfgPath)
	lh := logTimeAndStatus(cfg, h)
	server := &http.Server{Handler: lh, Addr: cfg.Listen}

	if cfg.Certfile != "" && cfg.Keyfile != "" {
		LoadCertificate()
		quic := &h2quic.Server{Server: server}
		quic.TLSConfig = &tls.Config{}
		quic.TLSConfig.GetCertificate = getCertificate

		pln, err := net.ListenPacket("udp", cfg.Listen)
		if err != nil {
			log.Fatal(err)
		}
		log.Print("listen quic on udp:%s", cfg.Listen)
		go quic.Serve(pln)

		// for higher score in ssllab
		log.Fatal(server.ListenAndServeTLS(cfg.Certfile, cfg.Keyfile))
	}
	server.ListenAndServe()
}

type LogWriter struct {
	http.ResponseWriter
	statusCode int
}

func (l *LogWriter) WriteHeader(i int) {
	l.statusCode = i
	l.ResponseWriter.WriteHeader(i)

}
func logTimeAndStatus(cfg *ServerConfig, handler http.Handler) http.Handler {

	var (
		writer io.Writer
		err    error
	)

	if cfg.AccessLogPath != "" {
		var file *os.File
		file, err = os.OpenFile(cfg.AccessLogPath,
			os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
		if err != nil {
			log.Fatal(err)
		}
		writer = file
		log.Printf("Access Log to file: %s", cfg.AccessLogPath)
		file.Seek(0, os.SEEK_END)
	} else {
		writer = os.Stdout
	}

	accessLogger := log.New(writer, "", log.LstdFlags)

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()

		writer := logPool.Get().(*LogWriter)
		writer.ResponseWriter = w
		writer.statusCode = 200

		if cfg.Certfile != "" {
			writer.ResponseWriter.Header().Add("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
			writer.ResponseWriter.Header().Add("alt-svc", `quic=":443"; ma=2592000; v="38,37,36"`)
			// alt-svc:quic=":443"; ma=2592000; v="39,38,37,35"
		}
		handler.ServeHTTP(writer, r)

		delta := time.Since(start)

		accessLogger.Printf(`%s %s %s %s %d "%s"`,
			r.RemoteAddr, r.Method, r.URL.Path,
			delta, writer.statusCode, r.UserAgent())

		httpRequestDurationSeconds.Observe(delta.Seconds())

		logPool.Put(writer)
	})
}

func LoadCertificate() {

	log.Println("Loading new certs")
	cert, err := tls.LoadX509KeyPair(cfg.Certfile, cfg.Keyfile)
	if err != nil {
		log.Println("load cert failed keep old", err)
		return
	}
	tlsCert = &cert
}

func getCertificate(ch *tls.ClientHelloInfo) (cert *tls.Certificate, err error) {
	return tlsCert, nil
}
<|endoftext|>


<commit_before>// Copyright 2017 Eduardo Pinheiro (edpin@edpin.com). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package https

import (
	"crypto/tls"
	"golang.org/x/crypto/acme/autocert"
	"log"
	"net/http"
	"time"
)

// StartSecureServer starts an HTTPS server with a Handler and an autocert
// manager. The HTTPS server started enables HTST by default to ensure maximum
// protection (see
// https://www.owasp.org/index.php/HTTP_Strict_Transport_Security_Cheat_Sheet).
// StartSecureServer also starts an HTTP server that redirects all requests to
// their HTTPS counterpart and immediately terminates all connections.
func StartSecureServer(h http.Handler, m *autocert.Manager) {
	s := NewSecureServer(m)
	s.Handler = NewHSTS(h)
	go func() {
		// Redirect regular HTTP requests to HTTPS.
		insecure := &http.Server{
			ReadTimeout:  5 * time.Second,
			WriteTimeout: 5 * time.Second,
			Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
				w.Header().Set("Connection", "close")
				url := "https://" + req.Host + req.URL.String()
				http.Redirect(w, req, url, http.StatusMovedPermanently)
			}),
		}
		log.Fatal(insecure.ListenAndServe())
	}()
	log.Fatal(s.ListenAndServeTLS("", ""))
}

type hstsHandler struct {
	h http.Handler
}

// NewSecureServer returns a new HTTP server with strict security settings.
func NewSecureServer(m *autocert.Manager) *http.Server {
	t := m.TLSConfig()
	t.ClientSessionCache = tls.NewLRUClientSessionCache(0)
	t.MinVersion = tls.VersionTLS12
	t.CurvePreferences = []tls.CurveID{
		tls.X25519, // requires go 1.8
		tls.CurveP521,
		tls.CurveP384,
		tls.CurveP256,
	}
	// Prefer this order of ciphers.
	t.CipherSuites = []uint16{
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
		// required by HTTP-2.
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
	}

	return &http.Server{
		Addr:              ":https",
		ReadTimeout:       5 * time.Second,
		ReadHeaderTimeout: 1 * time.Second,
		WriteTimeout:      10 * time.Second,
		IdleTimeout:       120 * time.Second,
		TLSConfig:         t,
	}
}

// NewHSTS returns an HTTP handler that sets HSTS headers on all requests.
func NewHSTS(h http.Handler) http.Handler {
	return hstsHandler{
		h: h,
	}
}

// ServeHTTP implements http.Handler.
func (h hstsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
	h.h.ServeHTTP(w, r)
}
<commit_msg>adds preload directive to HSTS<commit_after>// Copyright 2017 Eduardo Pinheiro (edpin@edpin.com). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package https

import (
	"crypto/tls"
	"golang.org/x/crypto/acme/autocert"
	"log"
	"net/http"
	"time"
)

// StartSecureServer starts an HTTPS server with a Handler and an autocert
// manager. The HTTPS server started enables HTST by default to ensure maximum
// protection (see
// https://www.owasp.org/index.php/HTTP_Strict_Transport_Security_Cheat_Sheet).
// StartSecureServer also starts an HTTP server that redirects all requests to
// their HTTPS counterpart and immediately terminates all connections.
func StartSecureServer(h http.Handler, m *autocert.Manager) {
	s := NewSecureServer(m)
	s.Handler = NewHSTS(h)
	go func() {
		// Redirect regular HTTP requests to HTTPS.
		insecure := &http.Server{
			ReadTimeout:  5 * time.Second,
			WriteTimeout: 5 * time.Second,
			Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
				w.Header().Set("Connection", "close")
				url := "https://" + req.Host + req.URL.String()
				http.Redirect(w, req, url, http.StatusMovedPermanently)
			}),
		}
		log.Fatal(insecure.ListenAndServe())
	}()
	log.Fatal(s.ListenAndServeTLS("", ""))
}

type hstsHandler struct {
	h http.Handler
}

// NewSecureServer returns a new HTTP server with strict security settings.
func NewSecureServer(m *autocert.Manager) *http.Server {
	t := m.TLSConfig()
	t.ClientSessionCache = tls.NewLRUClientSessionCache(0)
	t.MinVersion = tls.VersionTLS12
	t.CurvePreferences = []tls.CurveID{
		tls.X25519, // requires go 1.8
		tls.CurveP521,
		tls.CurveP384,
		tls.CurveP256,
	}
	// Prefer this order of ciphers.
	t.CipherSuites = []uint16{
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
		// required by HTTP-2.
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
	}

	return &http.Server{
		Addr:              ":https",
		ReadTimeout:       5 * time.Second,
		ReadHeaderTimeout: 1 * time.Second,
		WriteTimeout:      10 * time.Second,
		IdleTimeout:       120 * time.Second,
		TLSConfig:         t,
	}
}

// NewHSTS returns an HTTP handler that sets HSTS headers on all requests.
func NewHSTS(h http.Handler) http.Handler {
	return hstsHandler{
		h: h,
	}
}

// ServeHTTP implements http.Handler.
func (h hstsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
	h.h.ServeHTTP(w, r)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/Toorop/govh"
	"github.com/Toorop/govh/server"
	"strconv"
	"strings"
)

func serverHandler(cmd *Cmd) (err error) {
	// New govh client
	client := govh.NewClient(OVH_APP_KEY, OVH_APP_SECRET, ck)
	// New server ressource
	serverR, err := server.New(client)
	if err != nil {
		return
	}
	// response (string)
	var resp string

	switch cmd.Action {
	// List
	case "list":
		servers, err := serverR.List()
		if err != nil {
			return err
		}
		for _, s := range servers {
			resp = fmt.Sprintf("%s%s\r\n", resp, s)
		}
		if len(resp) > 2 {
			resp = resp[0 : len(resp)-2]
		}
		dieOk(resp)
		break
	// get server properties
	// ./ovh server getTasks SERVER_NAME FUNCTION STATUS
	case "properties":
		if len(cmd.Args) != 3 {
			return errors.New("\"server properties\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		properties, err := serverR.GetProperties(strings.ToLower(cmd.Args[2]))
		if err != nil {
			return err
		}
		fmt.Printf("ID: %d%s", properties.Id, NL)
		fmt.Printf("Name: %s%s", properties.Name, NL)
		fmt.Printf("Ip: %s%s", properties.Ip, NL)
		fmt.Printf("Datacenter: %s%s", properties.Datacenter, NL)
		fmt.Printf("ProfessionalUse: %t%s", properties.ProfessionalUse, NL)
		fmt.Printf("CommercialRange: %s%s", properties.CommercialRange, NL)
		fmt.Printf("Os: %s%s", properties.Os, NL)
		fmt.Printf("State: %s%s", properties.State, NL)
		fmt.Printf("Reverse: %s%s", properties.Reverse, NL)
		fmt.Printf("Monitored: %t%s", properties.Monitored, NL)
		fmt.Printf("Rack: %s%s", properties.Rack, NL)
		fmt.Printf("RootDevice: %s%s", properties.RootDevice, NL)
		fmt.Printf("LinkSpeed: %d%s", properties.LinkSpeed, NL)
		fmt.Printf("Bootid: %d%s", properties.BootId, NL)
		dieOk("")
		break

	// Get server tasks
	case "getTasks":
		function := "all"
		status := "all"

		if len(cmd.Args) < 3 {
			return errors.New("\"server getTasks\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		if len(cmd.Args) > 5 {
			return errors.New("\"server getTasks\" too many arguments - see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		// serverName
		serverName := strings.ToLower(cmd.Args[2])

		// function
		if len(cmd.Args) > 3 {
			function = cmd.Args[3]
			if len(cmd.Args) > 4 {
				status = cmd.Args[4]
			}
		}

		tasks, err := serverR.GetTasks(serverName, function, status)
		if err != nil {
			return err
		}
		resp := ""
		for _, task := range tasks {
			resp = fmt.Sprintf("%s%d\r\n", resp, task)
		}
		if len(resp) > 2 {
			resp = resp[0 : len(resp)-2]
		}
		dieOk(resp)
		break

	// Get task properties
	// ./ovh server getTaskProperties SERVER_NAME TASK_ID
	case "getTaskProperties":
		if len(cmd.Args) != 4 {
			return errors.New("\"server getTaskProperties\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		serverName := strings.ToLower(cmd.Args[2])
		taskId, err := strconv.ParseUint(cmd.Args[3], 10, 64)
		if err != nil {
			return err
		}
		task, err := serverR.GetTaskProperties(serverName, taskId)
		if err != nil {
			return err
		}
		fmt.Printf("Task ID: %d%s", task.Id, NL)
		fmt.Printf("Function: %s%s", task.Function, NL)
		fmt.Printf("Status: %s%s", task.Status, NL)
		fmt.Printf("Comment: %s%s", task.Comment, NL)
		fmt.Printf("Last Upadte: %s%s", task.LastUpdate, NL)
		fmt.Printf("Start Date: %s%s", task.StartDate, NL)
		fmt.Printf("Done Date: %s%s", task.DoneDate, NL)
		dieOk("")
		break

	// Cancel task (if possible)
	// ./ovh server cancelTask SERVER_NAME TASK_ID
	case "cancelTask":
		if len(cmd.Args) != 4 {
			return errors.New("\"server cancel Task\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}
		serverName := strings.ToLower(cmd.Args[2])
		taskId, err := strconv.ParseUint(cmd.Args[3], 10, 64)
		if err != nil {
			return err
		}
		err = serverR.CancelTask(serverName, taskId)
		if err != nil {
			return err
		}
		dieOk("Success task " + cmd.Args[3] + "cancelled")
		break

	// Reboot
	case "reboot":
		if len(cmd.Args) != 3 {
			return errors.New("\"server reboot\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}
		task, err := serverR.Reboot(strings.ToLower(cmd.Args[2]))
		if err != nil {
			return err
		}
		fmt.Printf("Task ID: %d%s", task.Id, NL)
		fmt.Printf("Function: %s%s", task.Function, NL)
		fmt.Printf("Status: %s%s", task.Status, NL)
		fmt.Printf("Comment: %s%s", task.Comment, NL)
		fmt.Printf("Last Upadte: %s%s", task.LastUpdate, NL)
		fmt.Printf("Start Date: %s%s", task.StartDate, NL)
		fmt.Printf("Done Date: %s%s", task.DoneDate, NL)
		dieOk("")
		break

	default:
		return errors.New(fmt.Sprintf("This action : '%s' is not valid or not implemented yet !", strings.Join(cmd.Args, " ")))
	}
	return
}
<commit_msg>nil<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/Toorop/govh"
	"github.com/Toorop/govh/server"
	"strconv"
	"strings"
)

func serverHandler(cmd *Cmd) (err error) {
	// New govh client
	client := govh.NewClient(OVH_APP_KEY, OVH_APP_SECRET, ck)
	// New server ressource
	serverR, err := server.New(client)
	if err != nil {
		return
	}
	// response (string)
	var resp string

	switch cmd.Action {
	// List
	case "list":
		servers, err := serverR.List()
		if err != nil {
			return err
		}
		for _, s := range servers {
			resp = fmt.Sprintf("%s%s\r\n", resp, s)
		}
		if len(resp) > 2 {
			resp = resp[0 : len(resp)-2]
		}
		dieOk(resp)
		break
	// get server properties
	// ./ovh server getTasks SERVER_NAME FUNCTION STATUS
	case "properties":
		if len(cmd.Args) != 3 {
			return errors.New("\"server properties\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		properties, err := serverR.GetProperties(strings.ToLower(cmd.Args[2]))
		if err != nil {
			return err
		}
		fmt.Printf("ID: %d%s", properties.Id, NL)
		fmt.Printf("Name: %s%s", properties.Name, NL)
		fmt.Printf("Ip: %s%s", properties.Ip, NL)
		fmt.Printf("Datacenter: %s%s", properties.Datacenter, NL)
		fmt.Printf("ProfessionalUse: %t%s", properties.ProfessionalUse, NL)
		fmt.Printf("CommercialRange: %s%s", properties.CommercialRange, NL)
		fmt.Printf("Os: %s%s", properties.Os, NL)
		fmt.Printf("State: %s%s", properties.State, NL)
		fmt.Printf("Reverse: %s%s", properties.Reverse, NL)
		fmt.Printf("Monitored: %t%s", properties.Monitored, NL)
		fmt.Printf("Rack: %s%s", properties.Rack, NL)
		fmt.Printf("RootDevice: %s%s", properties.RootDevice, NL)
		fmt.Printf("LinkSpeed: %d%s", properties.LinkSpeed, NL)
		fmt.Printf("Bootid: %d%s", properties.BootId, NL)
		dieOk("")
		break

	// Get available netboots ID for this server
	case "availableNetboots":
		if len(cmd.Args) < 3 {
			return errors.New("\"server availableNetboots\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}
		var netbootIds []int
		if len(cmd.Args) == 3 {
			netbootIds, err = serverR.GetNetboots(strings.ToLower(cmd.Args[2]))
		} else {
			netbootIds, err = serverR.GetNetboots(strings.ToLower(cmd.Args[2]), cmd.Args[3])
		}
		if err != nil {
			return
		}
		for _, id := range netbootIds {
			fmt.Println(id)
		}
		break

	// Get server tasks
	case "getTasks":
		function := "all"
		status := "all"

		if len(cmd.Args) < 3 {
			return errors.New("\"server getTasks\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		if len(cmd.Args) > 5 {
			return errors.New("\"server getTasks\" too many arguments - see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		// serverName
		serverName := strings.ToLower(cmd.Args[2])

		// function
		if len(cmd.Args) > 3 {
			function = cmd.Args[3]
			if len(cmd.Args) > 4 {
				status = cmd.Args[4]
			}
		}

		tasks, err := serverR.GetTasks(serverName, function, status)
		if err != nil {
			return err
		}
		resp := ""
		for _, task := range tasks {
			resp = fmt.Sprintf("%s%d\r\n", resp, task)
		}
		if len(resp) > 2 {
			resp = resp[0 : len(resp)-2]
		}
		dieOk(resp)
		break

	// Get task properties
	// ./ovh server getTaskProperties SERVER_NAME TASK_ID
	case "getTaskProperties":
		if len(cmd.Args) != 4 {
			return errors.New("\"server getTaskProperties\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}

		serverName := strings.ToLower(cmd.Args[2])
		taskId, err := strconv.ParseUint(cmd.Args[3], 10, 64)
		if err != nil {
			return err
		}
		task, err := serverR.GetTaskProperties(serverName, taskId)
		if err != nil {
			return err
		}
		fmt.Printf("Task ID: %d%s", task.Id, NL)
		fmt.Printf("Function: %s%s", task.Function, NL)
		fmt.Printf("Status: %s%s", task.Status, NL)
		fmt.Printf("Comment: %s%s", task.Comment, NL)
		fmt.Printf("Last Upadte: %s%s", task.LastUpdate, NL)
		fmt.Printf("Start Date: %s%s", task.StartDate, NL)
		fmt.Printf("Done Date: %s%s", task.DoneDate, NL)
		dieOk("")
		break

	// Cancel task (if possible)
	// ./ovh server cancelTask SERVER_NAME TASK_ID
	case "cancelTask":
		if len(cmd.Args) != 4 {
			return errors.New("\"server cancel Task\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}
		serverName := strings.ToLower(cmd.Args[2])
		taskId, err := strconv.ParseUint(cmd.Args[3], 10, 64)
		if err != nil {
			return err
		}
		err = serverR.CancelTask(serverName, taskId)
		if err != nil {
			return err
		}
		dieOk("Success task " + cmd.Args[3] + "cancelled")
		break

	// Reboot
	case "reboot":
		if len(cmd.Args) != 3 {
			return errors.New("\"server reboot\" needs an argument see doc at https://github.com/Toorop/govh/blob/master/cli/README.md")
		}
		task, err := serverR.Reboot(strings.ToLower(cmd.Args[2]))
		if err != nil {
			return err
		}
		fmt.Printf("Task ID: %d%s", task.Id, NL)
		fmt.Printf("Function: %s%s", task.Function, NL)
		fmt.Printf("Status: %s%s", task.Status, NL)
		fmt.Printf("Comment: %s%s", task.Comment, NL)
		fmt.Printf("Last Upadte: %s%s", task.LastUpdate, NL)
		fmt.Printf("Start Date: %s%s", task.StartDate, NL)
		fmt.Printf("Done Date: %s%s", task.DoneDate, NL)
		dieOk("")
		break

	default:
		return errors.New(fmt.Sprintf("This action : '%s' is not valid or not implemented yet !", strings.Join(cmd.Args, " ")))
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
)

var (
	host = flag.String("host", "", "The hostname/ip to listen on.")
	port = flag.Int("port", 3000, "The port number to listen on.")
)

func main() {
	flag.Parse()

	addr := fmt.Sprintf("%s:%d", *host, *port)
	panic(http.ListenAndServe(addr, http.FileServer(http.Dir("./public"))))
}
<commit_msg>Added 2nd http.FileServer() for /gopath => $GOPATH<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
)

var (
	host = flag.String("host", "", "The hostname/ip to listen on.")
	port = flag.Int("port", 3000, "The port number to listen on.")
)

func main() {
	flag.Parse()

	addr := fmt.Sprintf("%s:%d", *host, *port)
	http.Handle("/gopath/", http.StripPrefix("/gopath", http.FileServer(http.Dir(os.Getenv("GOPATH")))))
	http.Handle("/", http.FileServer(http.Dir("./public")))

	fmt.Println("Listeing on", addr)
	panic(http.ListenAndServe(addr, nil))
}
<|endoftext|>


<commit_before>package main

import (
	"net"
	"net/url"
	"os"

	"github.com/BurntSushi/toml"
	"github.com/flynn/flynn-controller/client"
)

var cmdServerAdd = &Command{
	Run:      runServerAdd,
	Usage:    "server-add [-g <githost>] [-p <tlspin>] <server-name> <url> <key>",
	Short:    "add a server",
	Long:     `Command add-server adds a server to the ~/.flynnrc configuration file`,
	NoClient: true,
}

var serverGitHost string
var serverTLSPin string

func init() {
	cmdServerAdd.Flag.StringVarP(&serverGitHost, "git-host", "g", "", "git host (if host differs from api URL host)")
	cmdServerAdd.Flag.StringVarP(&serverTLSPin, "tls-pin", "p", "", "SHA256 of the server's TLS cert (useful if it is self-signed)")
}

func runServerAdd(cmd *Command, args []string, client *controller.Client) error {
	if len(args) != 3 {
		cmd.printUsage(true)
	}
	if err := readConfig(); err != nil {
		return err
	}

	s := &ServerConfig{
		Name:    args[0],
		URL:     args[1],
		Key:     args[2],
		GitHost: serverGitHost,
		TLSPin:  serverTLSPin,
	}
	if serverGitHost == "" {
		u, err := url.Parse(s.URL)
		if err != nil {
			return err
		}
		host, _, _ := net.SplitHostPort(u.Host)
		s.GitHost = host
	}
	config.Servers = append(config.Servers, s)

	f, err := os.Create(configPath())
	if err != nil {
		return err
	}
	defer f.Close()
	return toml.NewEncoder(f).Encode(config)
}
<commit_msg>Add output to server-add<commit_after>package main

import (
	"log"
	"net"
	"net/url"
	"os"

	"github.com/BurntSushi/toml"
	"github.com/flynn/flynn-controller/client"
)

var cmdServerAdd = &Command{
	Run:      runServerAdd,
	Usage:    "server-add [-g <githost>] [-p <tlspin>] <server-name> <url> <key>",
	Short:    "add a server",
	Long:     `Command add-server adds a server to the ~/.flynnrc configuration file`,
	NoClient: true,
}

var serverGitHost string
var serverTLSPin string

func init() {
	cmdServerAdd.Flag.StringVarP(&serverGitHost, "git-host", "g", "", "git host (if host differs from api URL host)")
	cmdServerAdd.Flag.StringVarP(&serverTLSPin, "tls-pin", "p", "", "SHA256 of the server's TLS cert (useful if it is self-signed)")
}

func runServerAdd(cmd *Command, args []string, client *controller.Client) error {
	if len(args) != 3 {
		cmd.printUsage(true)
	}
	if err := readConfig(); err != nil {
		return err
	}

	s := &ServerConfig{
		Name:    args[0],
		URL:     args[1],
		Key:     args[2],
		GitHost: serverGitHost,
		TLSPin:  serverTLSPin,
	}
	if serverGitHost == "" {
		u, err := url.Parse(s.URL)
		if err != nil {
			return err
		}
		host, _, _ := net.SplitHostPort(u.Host)
		s.GitHost = host
	}
	config.Servers = append(config.Servers, s)

	f, err := os.Create(configPath())
	if err != nil {
		return err
	}
	defer f.Close()

	if err := toml.NewEncoder(f).Encode(config); err != nil {
		return err
	}

	log.Printf("Server %s added.", s.Name)
	return nil
}
<|endoftext|>


<commit_before>// Package imageserver provides an Image server toolkit.
package imageserver

// Server represents an Image server
type Server interface {
	Get(Params) (*Image, error)
}

// ServerFunc is a Server func.
type ServerFunc func(params Params) (*Image, error)

// Get implements Server.
func (f ServerFunc) Get(params Params) (*Image, error) {
	return f(params)
}

// SourceParam is the source Param name.
const SourceParam = "source"

// SourceServer is a source Server.
//
// It forwards to the underlying Server with only the source param.
type SourceServer struct {
	Server
}

// Get implements Server.
func (s *SourceServer) Get(params Params) (*Image, error) {
	source, err := params.Get(SourceParam)
	if err != nil {
		return nil, err
	}
	params = Params{SourceParam: source}
	return s.Server.Get(params)
}

// NewLimitServer creates a new Server that limits the number of concurrent executions.
//
// It uses a buffered channel to limit the number of concurrent executions.
func NewLimitServer(s Server, limit int) Server {
	if limit <= 0 {
		return s
	}
	limitCh := make(chan struct{}, limit)
	return ServerFunc(func(params Params) (*Image, error) {
		limitCh <- struct{}{}
		defer func() {
			<-limitCh
		}()
		return s.Get(params)
	})
}

// StaticServer is an Image Server that always returns the same Image and error.
type StaticServer struct {
	Image *Image
	Error error
}

// Get implements Server.
func (s *StaticServer) Get(params Params) (*Image, error) {
	return s.Image, s.Error
}
<commit_msg>use a struct for NewLimitServer (it's faster)<commit_after>// Package imageserver provides an Image server toolkit.
package imageserver

// Server represents an Image server
type Server interface {
	Get(Params) (*Image, error)
}

// ServerFunc is a Server func.
type ServerFunc func(params Params) (*Image, error)

// Get implements Server.
func (f ServerFunc) Get(params Params) (*Image, error) {
	return f(params)
}

// SourceParam is the source Param name.
const SourceParam = "source"

// SourceServer is a source Server.
//
// It forwards to the underlying Server with only the source param.
type SourceServer struct {
	Server
}

// Get implements Server.
func (s *SourceServer) Get(params Params) (*Image, error) {
	source, err := params.Get(SourceParam)
	if err != nil {
		return nil, err
	}
	params = Params{SourceParam: source}
	return s.Server.Get(params)
}

// NewLimitServer creates a new Server that limits the number of concurrent executions.
//
// It uses a buffered channel to limit the number of concurrent executions.
func NewLimitServer(s Server, limit int) Server {
	return &limitServer{
		Server:  s,
		limitCh: make(chan struct{}, limit),
	}
}

type limitServer struct {
	Server
	limitCh chan struct{}
}

func (s *limitServer) Get(params Params) (*Image, error) {
	s.limitCh <- struct{}{}
	defer func() {
		<-s.limitCh
	}()
	return s.Server.Get(params)
}

// StaticServer is an Image Server that always returns the same Image and error.
type StaticServer struct {
	Image *Image
	Error error
}

// Get implements Server.
func (s *StaticServer) Get(params Params) (*Image, error) {
	return s.Image, s.Error
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"crypto/rand"
	"crypto/subtle"
	"encoding/binary"
	"io"
	"log"
	"net"
	"sync"
	"sync/atomic"
	"time"

	"golang.org/x/crypto/ed25519"
)

// ClientConnection - A client connection
type ClientConnection struct {
	conf          Conf
	conn          net.Conn
	reader        *bufio.Reader
	writer        *bufio.Writer
	clientVersion byte
}

// StoredContent - Paste buffer
type StoredContent struct {
	sync.RWMutex

	encryptSkID         []byte
	ts                  []byte
	signature           []byte
	ciphertextWithNonce []byte
}

var storedContent StoredContent
var trustedClients TrustedClients
var clientsCount = uint64(0)

func (cnx *ClientConnection) getOperation(h1 []byte, isMove bool) {
	conf, reader, writer := cnx.conf, cnx.reader, cnx.writer
	rbuf := make([]byte, 32)
	if _, err := io.ReadFull(reader, rbuf); err != nil {
		log.Print(err)
		return
	}
	h2 := rbuf
	opcode := byte('G')
	if isMove {
		opcode = byte('M')
	}
	wh2 := auth2get(conf, cnx.clientVersion, h1, opcode)
	if subtle.ConstantTimeCompare(wh2, h2) != 1 {
		return
	}

	var encryptSkID, ts, signature, ciphertextWithNonce []byte
	if isMove {
		storedContent.Lock()
		encryptSkID, ts, signature, ciphertextWithNonce =
			storedContent.encryptSkID, storedContent.ts,
			storedContent.signature, storedContent.ciphertextWithNonce
		storedContent.encryptSkID, storedContent.ts, storedContent.signature,
			storedContent.ciphertextWithNonce = nil, nil, nil, nil
		storedContent.Unlock()
	} else {
		storedContent.RLock()
		encryptSkID, ts, signature, ciphertextWithNonce =
			storedContent.encryptSkID, storedContent.ts, storedContent.signature,
			storedContent.ciphertextWithNonce
		storedContent.RUnlock()
	}

	cnx.conn.SetDeadline(time.Now().Add(conf.DataTimeout))
	h3 := auth3get(conf, cnx.clientVersion, h2, encryptSkID, ts, signature)
	writer.Write(h3)
	ciphertextWithNonceLen := uint64(len(ciphertextWithNonce))
	binary.Write(writer, binary.LittleEndian, ciphertextWithNonceLen)
	writer.Write(encryptSkID)
	if cnx.clientVersion >= 5 {
		writer.Write(ts)
	}
	writer.Write(signature)
	writer.Write(ciphertextWithNonce)
	if err := writer.Flush(); err != nil {
		log.Print(err)
		return
	}
}

func (cnx *ClientConnection) storeOperation(h1 []byte) {
	conf, reader, writer := cnx.conf, cnx.reader, cnx.writer
	var rbuf []byte
	if cnx.clientVersion < 5 {
		rbuf = make([]byte, 112)
	} else {
		rbuf = make([]byte, 120)
	}
	if _, err := io.ReadFull(reader, rbuf); err != nil {
		log.Print(err)
		return
	}
	h2 := rbuf[0:32]
	ciphertextWithNonceLen := binary.LittleEndian.Uint64(rbuf[32:40])
	if conf.MaxLen > 0 && ciphertextWithNonceLen > conf.MaxLen {
		log.Printf("%v bytes requested to be stored, but limit set to %v bytes (%v Mb)\n",
			ciphertextWithNonceLen, conf.MaxLen, conf.MaxLen/(1024*1024))
		return
	}
	encryptSkID := rbuf[40:48]
	var ts, signature []byte
	if cnx.clientVersion < 5 {
		ts = make([]byte, 8)
		binary.LittleEndian.PutUint64(ts, uint64(time.Now().Unix()))
		signature = rbuf[48:112]
	} else {
		ts = rbuf[48:56]
		signature = rbuf[56:120]
	}
	opcode := byte('S')

	wh2 := auth2store(conf, cnx.clientVersion, h1, opcode, encryptSkID, ts, signature)
	if subtle.ConstantTimeCompare(wh2, h2) != 1 {
		return
	}
	ciphertextWithNonce := make([]byte, ciphertextWithNonceLen)

	cnx.conn.SetDeadline(time.Now().Add(conf.DataTimeout))
	if _, err := io.ReadFull(reader, ciphertextWithNonce); err != nil {
		log.Print(err)
		return
	}
	if ed25519.Verify(conf.SignPk, ciphertextWithNonce, signature) != true {
		return
	}
	h3 := auth3store(conf, cnx.clientVersion, h2)

	storedContent.Lock()
	storedContent.encryptSkID = encryptSkID
	storedContent.ts = ts
	storedContent.signature = signature
	storedContent.ciphertextWithNonce = ciphertextWithNonce
	storedContent.Unlock()

	writer.Write(h3)
	if err := writer.Flush(); err != nil {
		log.Print(err)
		return
	}
}

func handleClientConnection(conf Conf, conn net.Conn) {
	defer conn.Close()
	reader, writer := bufio.NewReader(conn), bufio.NewWriter(conn)
	cnx := ClientConnection{
		conf:   conf,
		conn:   conn,
		reader: reader,
		writer: writer,
	}
	rbuf := make([]byte, 65)
	if _, err := io.ReadFull(reader, rbuf); err != nil {
		log.Print(err)
		return
	}
	cnx.clientVersion = rbuf[0]
	if cnx.clientVersion < 4 || cnx.clientVersion > 5 {
		log.Print("Unsupported client version - Please run the same version on the server and on the client")
		return
	}
	r := rbuf[1:33]
	h0 := rbuf[33:65]
	wh0 := auth0(conf, cnx.clientVersion, r)
	if subtle.ConstantTimeCompare(wh0, h0) != 1 {
		return
	}
	r2 := make([]byte, 32)
	if _, err := rand.Read(r); err != nil {
		log.Fatal(err)
	}
	h1 := auth1(conf, cnx.clientVersion, h0, r2)
	writer.Write([]byte{cnx.clientVersion})
	writer.Write(r2)
	writer.Write(h1)
	if err := writer.Flush(); err != nil {
		log.Print(err)
		return
	}
	remoteIP := cnx.conn.RemoteAddr().(*net.TCPAddr).IP
	addToTrustedIPs(conf, remoteIP)
	opcode, err := reader.ReadByte()
	if err != nil {
		return
	}
	switch opcode {
	case byte('G'):
		cnx.getOperation(h1, false)
	case byte('M'):
		cnx.getOperation(h1, true)
	case byte('S'):
		cnx.storeOperation(h1)
	}
}

type TrustedClients struct {
	sync.RWMutex

	ips []net.IP
}

func addToTrustedIPs(conf Conf, ip net.IP) {
	trustedClients.Lock()
	if uint64(len(trustedClients.ips)) >= conf.TrustedIPCount {
		trustedClients.ips = append(trustedClients.ips[1:], ip)
	} else {
		trustedClients.ips = append(trustedClients.ips, ip)
	}
	trustedClients.Unlock()
}

func isIPTrusted(conf Conf, ip net.IP) bool {
	trustedClients.RLock()
	defer trustedClients.RUnlock()
	if len(trustedClients.ips) == 0 {
		return true
	}
	for _, foundIP := range trustedClients.ips {
		if foundIP.Equal(ip) {
			return true
		}
	}
	return false
}

func acceptClient(conf Conf, conn net.Conn) {
	conn.SetDeadline(time.Now().Add(conf.Timeout))
	remoteIP := conn.RemoteAddr().(*net.TCPAddr).IP
	for {
		count := atomic.LoadUint64(&clientsCount)
		if count >= conf.MaxClients-conf.TrustedIPCount && isIPTrusted(conf, remoteIP) == false {
			conn.Close()
			return
		}
		if count >= conf.MaxClients {
			conn.Close()
			return
		} else if atomic.CompareAndSwapUint64(&clientsCount, count, count+1) {
			break
		}
	}
	handleClientConnection(conf, conn)
	atomic.AddUint64(&clientsCount, ^uint64(0))
}

// RunServer - run a server
func RunServer(conf Conf) {
	listen, err := net.Listen("tcp", conf.Listen)
	if err != nil {
		log.Fatal(err)
	}
	defer listen.Close()
	for {
		conn, err := listen.Accept()
		if err != nil {
			log.Fatal(err)
		}
		go acceptClient(conf, conn)
	}
}
<commit_msg>Check the connections count before spawning a new goroutine<commit_after>package main

import (
	"bufio"
	"crypto/rand"
	"crypto/subtle"
	"encoding/binary"
	"io"
	"log"
	"net"
	"sync"
	"sync/atomic"
	"time"

	"golang.org/x/crypto/ed25519"
)

// ClientConnection - A client connection
type ClientConnection struct {
	conf          Conf
	conn          net.Conn
	reader        *bufio.Reader
	writer        *bufio.Writer
	clientVersion byte
}

// StoredContent - Paste buffer
type StoredContent struct {
	sync.RWMutex

	encryptSkID         []byte
	ts                  []byte
	signature           []byte
	ciphertextWithNonce []byte
}

var storedContent StoredContent
var trustedClients TrustedClients
var clientsCount = uint64(0)

func (cnx *ClientConnection) getOperation(h1 []byte, isMove bool) {
	conf, reader, writer := cnx.conf, cnx.reader, cnx.writer
	rbuf := make([]byte, 32)
	if _, err := io.ReadFull(reader, rbuf); err != nil {
		log.Print(err)
		return
	}
	h2 := rbuf
	opcode := byte('G')
	if isMove {
		opcode = byte('M')
	}
	wh2 := auth2get(conf, cnx.clientVersion, h1, opcode)
	if subtle.ConstantTimeCompare(wh2, h2) != 1 {
		return
	}

	var encryptSkID, ts, signature, ciphertextWithNonce []byte
	if isMove {
		storedContent.Lock()
		encryptSkID, ts, signature, ciphertextWithNonce =
			storedContent.encryptSkID, storedContent.ts,
			storedContent.signature, storedContent.ciphertextWithNonce
		storedContent.encryptSkID, storedContent.ts, storedContent.signature,
			storedContent.ciphertextWithNonce = nil, nil, nil, nil
		storedContent.Unlock()
	} else {
		storedContent.RLock()
		encryptSkID, ts, signature, ciphertextWithNonce =
			storedContent.encryptSkID, storedContent.ts, storedContent.signature,
			storedContent.ciphertextWithNonce
		storedContent.RUnlock()
	}

	cnx.conn.SetDeadline(time.Now().Add(conf.DataTimeout))
	h3 := auth3get(conf, cnx.clientVersion, h2, encryptSkID, ts, signature)
	writer.Write(h3)
	ciphertextWithNonceLen := uint64(len(ciphertextWithNonce))
	binary.Write(writer, binary.LittleEndian, ciphertextWithNonceLen)
	writer.Write(encryptSkID)
	if cnx.clientVersion >= 5 {
		writer.Write(ts)
	}
	writer.Write(signature)
	writer.Write(ciphertextWithNonce)
	if err := writer.Flush(); err != nil {
		log.Print(err)
		return
	}
}

func (cnx *ClientConnection) storeOperation(h1 []byte) {
	conf, reader, writer := cnx.conf, cnx.reader, cnx.writer
	var rbuf []byte
	if cnx.clientVersion < 5 {
		rbuf = make([]byte, 112)
	} else {
		rbuf = make([]byte, 120)
	}
	if _, err := io.ReadFull(reader, rbuf); err != nil {
		log.Print(err)
		return
	}
	h2 := rbuf[0:32]
	ciphertextWithNonceLen := binary.LittleEndian.Uint64(rbuf[32:40])
	if conf.MaxLen > 0 && ciphertextWithNonceLen > conf.MaxLen {
		log.Printf("%v bytes requested to be stored, but limit set to %v bytes (%v Mb)\n",
			ciphertextWithNonceLen, conf.MaxLen, conf.MaxLen/(1024*1024))
		return
	}
	encryptSkID := rbuf[40:48]
	var ts, signature []byte
	if cnx.clientVersion < 5 {
		ts = make([]byte, 8)
		binary.LittleEndian.PutUint64(ts, uint64(time.Now().Unix()))
		signature = rbuf[48:112]
	} else {
		ts = rbuf[48:56]
		signature = rbuf[56:120]
	}
	opcode := byte('S')

	wh2 := auth2store(conf, cnx.clientVersion, h1, opcode, encryptSkID, ts, signature)
	if subtle.ConstantTimeCompare(wh2, h2) != 1 {
		return
	}
	ciphertextWithNonce := make([]byte, ciphertextWithNonceLen)

	cnx.conn.SetDeadline(time.Now().Add(conf.DataTimeout))
	if _, err := io.ReadFull(reader, ciphertextWithNonce); err != nil {
		log.Print(err)
		return
	}
	if ed25519.Verify(conf.SignPk, ciphertextWithNonce, signature) != true {
		return
	}
	h3 := auth3store(conf, cnx.clientVersion, h2)

	storedContent.Lock()
	storedContent.encryptSkID = encryptSkID
	storedContent.ts = ts
	storedContent.signature = signature
	storedContent.ciphertextWithNonce = ciphertextWithNonce
	storedContent.Unlock()

	writer.Write(h3)
	if err := writer.Flush(); err != nil {
		log.Print(err)
		return
	}
}

func handleClientConnection(conf Conf, conn net.Conn) {
	defer conn.Close()
	reader, writer := bufio.NewReader(conn), bufio.NewWriter(conn)
	cnx := ClientConnection{
		conf:   conf,
		conn:   conn,
		reader: reader,
		writer: writer,
	}
	rbuf := make([]byte, 65)
	if _, err := io.ReadFull(reader, rbuf); err != nil {
		return
	}
	cnx.clientVersion = rbuf[0]
	if cnx.clientVersion < 4 || cnx.clientVersion > 5 {
		log.Print("Unsupported client version - Please run the same version on the server and on the client")
		return
	}
	r := rbuf[1:33]
	h0 := rbuf[33:65]
	wh0 := auth0(conf, cnx.clientVersion, r)
	if subtle.ConstantTimeCompare(wh0, h0) != 1 {
		return
	}
	r2 := make([]byte, 32)
	if _, err := rand.Read(r); err != nil {
		log.Fatal(err)
	}
	h1 := auth1(conf, cnx.clientVersion, h0, r2)
	writer.Write([]byte{cnx.clientVersion})
	writer.Write(r2)
	writer.Write(h1)
	if err := writer.Flush(); err != nil {
		log.Print(err)
		return
	}
	remoteIP := cnx.conn.RemoteAddr().(*net.TCPAddr).IP
	addToTrustedIPs(conf, remoteIP)
	opcode, err := reader.ReadByte()
	if err != nil {
		return
	}
	switch opcode {
	case byte('G'):
		cnx.getOperation(h1, false)
	case byte('M'):
		cnx.getOperation(h1, true)
	case byte('S'):
		cnx.storeOperation(h1)
	}
}

type TrustedClients struct {
	sync.RWMutex

	ips []net.IP
}

func addToTrustedIPs(conf Conf, ip net.IP) {
	trustedClients.Lock()
	if uint64(len(trustedClients.ips)) >= conf.TrustedIPCount {
		trustedClients.ips = append(trustedClients.ips[1:], ip)
	} else {
		trustedClients.ips = append(trustedClients.ips, ip)
	}
	trustedClients.Unlock()
}

func isIPTrusted(conf Conf, ip net.IP) bool {
	trustedClients.RLock()
	defer trustedClients.RUnlock()
	if len(trustedClients.ips) == 0 {
		return true
	}
	for _, foundIP := range trustedClients.ips {
		if foundIP.Equal(ip) {
			return true
		}
	}
	return false
}

func acceptClient(conf Conf, conn net.Conn) {
	handleClientConnection(conf, conn)
	atomic.AddUint64(&clientsCount, ^uint64(0))
}

func maybeAcceptClient(conf Conf, conn net.Conn) {
	conn.SetDeadline(time.Now().Add(conf.Timeout))
	remoteIP := conn.RemoteAddr().(*net.TCPAddr).IP
	for {
		count := atomic.LoadUint64(&clientsCount)
		if count >= conf.MaxClients-conf.TrustedIPCount && isIPTrusted(conf, remoteIP) == false {
			conn.Close()
			return
		}
		if count >= conf.MaxClients {
			conn.Close()
			return
		} else if atomic.CompareAndSwapUint64(&clientsCount, count, count+1) {
			break
		}
	}
	go acceptClient(conf, conn)
}

// RunServer - run a server
func RunServer(conf Conf) {
	listen, err := net.Listen("tcp", conf.Listen)
	if err != nil {
		log.Fatal(err)
	}
	defer listen.Close()
	for {
		conn, err := listen.Accept()
		if err != nil {
			log.Fatal(err)
		}
		maybeAcceptClient(conf, conn)
	}
}
<|endoftext|>


<commit_before>package main

import (
    "os"
    "log"
    "net/http"
    "html/template"
    "github.com/gorilla/mux"
    "github.com/mitchellh/go-homedir"

)

type FList struct {
    Files []FullPath
}

type FullPath struct {
    Name string
    Path string
}

func Run(){

    r := mux.NewRouter()

    r.HandleFunc("/", DefaultHandler).Methods("GET")
    r.HandleFunc("/", PathHandler).Methods("POST")
    r.HandleFunc("/sort", SortHandler).Methods("POST")

    http.Handle("/", r)
    http.ListenAndServe(":8080", nil)
}

func DefaultHandler(res http.ResponseWriter, req *http.Request){
    path, err := homedir.Dir()
    log.Println(path)
    checkErr(err)

    fobj := CreateFList(path)

    t, err := template.ParseFiles("index.html")
    checkErr(err)

    err = t.Execute(res, fobj)
    checkErr(err)
}

func PathHandler(res http.ResponseWriter, req *http.Request){
    path := req.FormValue("path")
    log.Println(path)
    fobj := CreateFList(path)

    t, err := template.ParseFiles("index.html")
    checkErr(err)

    err = t.Execute(res, fobj)
    checkErr(err)
}

func SortHandler(res http.ResponseWriter, req *http.Request){
    path := req.FormValue("path")
    log.Println(path)
    Sort(path)
}

func checkErr(err error){
    if err != nil {
        log.Fatal(err)
    }
}

func CreateFList(path string) *FList {
    fobj := &FList{Files: make([]FullPath, 0, 100)}

    dir, err := os.Open(path)
    checkErr(err)

    fi, err := dir.Readdir(100)
    checkErr(err)

    for _, file := range fi {
        fobj.Files = append(fobj.Files, FullPath{Name:file.Name(), Path: path+"/"+file.Name()})
        log.Println(file.Name())
    }

    //fobj := &FList{Files: fi}

    return fobj
}

    <commit_msg>Updated server.go such that it renders only directories<commit_after>package main

import (
    "os"
    "log"
    "net/http"
    "html/template"
    "github.com/gorilla/mux"
    "github.com/mitchellh/go-homedir"

)

type FList struct {
    Files []FullPath
}

type FullPath struct {
    Name string
    Path string
}

func Run(){

    r := mux.NewRouter()

    r.HandleFunc("/", DefaultHandler).Methods("GET")
    r.HandleFunc("/", PathHandler).Methods("POST")
    r.HandleFunc("/sort", SortHandler).Methods("POST")

    http.Handle("/", r)
    http.ListenAndServe(":8080", nil)
}

func DefaultHandler(res http.ResponseWriter, req *http.Request){
    path, err := homedir.Dir()
    log.Println(path)
    checkErr(err)

    fobj := CreateFList(path)

    t, err := template.ParseFiles("index.html")
    checkErr(err)

    err = t.Execute(res, fobj)
    checkErr(err)
}

func PathHandler(res http.ResponseWriter, req *http.Request){
    path := req.FormValue("path")
    log.Println(path)
    fobj := CreateFList(path)

    t, err := template.ParseFiles("index.html")
    checkErr(err)

    err = t.Execute(res, fobj)
    checkErr(err)
}

func SortHandler(res http.ResponseWriter, req *http.Request){
    path := req.FormValue("path")
    log.Println(path)
    Sort(path)
}

func checkErr(err error){
    if err != nil {
        log.Fatal(err)
    }
}

func CreateFList(path string) *FList {
    fobj := &FList{Files: make([]FullPath, 0, 100)}

    dir, err := os.Open(path)
    checkErr(err)

    fi, err := dir.Readdir(100)
    checkErr(err)

    for _, file := range fi {
        if file.IsDir() {
            fobj.Files = append(fobj.Files,
                                FullPath{Name:file.Name(), Path: path+"/"+file.Name()})
            log.Println(file.Name())
        }
    }

    //fobj := &FList{Files: fi}

    return fobj
}

    <|endoftext|>


<commit_before>package servo

import "net/http"

// The Server is responsible for running the server process.
// It can be injected via the goldi type "kernel.server"
type Server interface {
	// Run starts the server and blocks until it has finished
	Run() error
}

// DefaultServer is the standard implementation of the Server interface.
// It accepts a listen address and an HTTP handler and uses the http package of
// the standard library.
type HTTPServer struct {
	ListenAddress string
	Handler       http.Handler
	Log           Logger
}

// NewHTTPServer creates a new HTTPServer
func NewHTTPServer(listenAddress string, handler http.Handler, log Logger) *HTTPServer {
	return &HTTPServer{listenAddress, handler, log}
}

// Run will make this server listen on the given ListenAddress and use the handler to
// handle all incoming HTTP requests. The method blocks.
func (s *HTTPServer) Run() error {
	s.Log.Info("Server started", "address", s.ListenAddress)
	return http.ListenAndServe(s.ListenAddress, s.Handler)
}
<commit_msg>Work with http handler func<commit_after>package servo

import "net/http"

// The Server is responsible for running the server process.
// It can be injected via the goldi type "kernel.server"
type Server interface {
	// Run starts the server and blocks until it has finished
	Run() error
}

// DefaultServer is the standard implementation of the Server interface.
// It accepts a listen address and an HTTP handler and uses the http package of
// the standard library.
type HTTPServer struct {
	ListenAddress string
	Handler       http.HandlerFunc
	Log           Logger
}

// NewHTTPServer creates a new HTTPServer
func NewHTTPServer(listenAddress string, handler http.HandlerFunc, log Logger) *HTTPServer {
	return &HTTPServer{listenAddress, handler, log}
}

// Run will make this server listen on the given ListenAddress and use the handler to
// handle all incoming HTTP requests. The method blocks.
func (s *HTTPServer) Run() error {
	s.Log.Info("Server started", "address", s.ListenAddress)
	http.HandleFunc("/", s.Handler)
	return http.ListenAndServe(s.ListenAddress, s.Handler)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	//"log"
	"encoding/json"
	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
	"github.com/sdboyer/mock_druplatform_api/acquia"
	"net/http"
	"net"
	"time"
)

var fml = fmt.Println

// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
// connections. It's used by ListenAndServe and ListenAndServeTLS so
// dead TCP connections (e.g. closing laptop mid-download) eventually
// go away.
//
// Copied from net/http, b/c they did not deign to export
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
}

type ServerInstance struct {
	Listener tcpKeepAliveListener
	HttpServer *http.Server
}

var servers = make([]ServerInstance, 0)

func main() {
	router := mux.NewRouter()
	router.Headers("Content-Type", "application/json")

	router.HandleFunc("/", hhListServers).Methods("GET")
	router.HandleFunc("/", hhCreateServer).Methods("POST")

	n := negroni.New()
	n.UseHandler(router)
	n.Run(":10233")
}

type createServerRequest struct {
	Server_type string  `json:"server_type"`
	Version string `json:"version"`
}

func hhCreateServer(w http.ResponseWriter, r *http.Request) {
	j := &createServerRequest{}

	decoder := json.NewDecoder(r.Body)
	if err := decoder.Decode(j); err != nil {
		panic(err)
	}

	an := negroni.New()
	an.UseHandler(acquia.NewRouter(acquia.NewServerInstance("default")))

	laddr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:0") // listen to all the things
	if err != nil {
		panic(err)
	}

	l, err := net.ListenTCP("tcp", laddr)
	if err != nil {
		panic(err)
	}
	kal := tcpKeepAliveListener{l}

	// The Addr prop shouldn't actually be used, but set it to avoid triggering defaults
	srv := &http.Server{Addr: laddr.String(), Handler: an}

	si := ServerInstance{Listener: kal, HttpServer: srv}
	resp, err := json.Marshal(struct{
		Port int `json:"port"`
		ServerType string  `json:"server_type"`
		Version string `json:"version"`
	}{
		Port: kal.Addr().(*net.TCPAddr).Port,
		ServerType: "acquia",
		Version: "1.0",
	})

	if err != nil {
		panic(err)
	}

	w.Write(resp) // auto-sends 200 response
	servers = append(servers, si)
	go srv.Serve(kal)
}

func hhListServers(w http.ResponseWriter, r *http.Request) {

}
<commit_msg>Split main() logic into separate callable func<commit_after>package main

import (
	"fmt"
	//"log"
	"encoding/json"
	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
	"github.com/sdboyer/mock_druplatform_api/acquia"
	"net/http"
	"net"
	"time"
)

var fml = fmt.Println

// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
// connections. It's used by ListenAndServe and ListenAndServeTLS so
// dead TCP connections (e.g. closing laptop mid-download) eventually
// go away.
//
// Copied from net/http, b/c they did not deign to export
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
}

type ServerInstance struct {
	Listener tcpKeepAliveListener
	HttpServer *http.Server
}

var servers = make([]ServerInstance, 0)

func main() {
	setUpMainHttpd()
}

func setUpMainHttpd() {
	router := mux.NewRouter()
	router.HandleFunc("/", hhListServers).Methods("GET")
	router.HandleFunc("/", hhCreateServer).Methods("POST")

	n := negroni.New()
	n.UseHandler(router)
	n.Run(":10233")
}

type createServerRequest struct {
	Server_type string  `json:"server_type"`
	Version string `json:"version"`
}

func hhCreateServer(w http.ResponseWriter, r *http.Request) {
	j := &createServerRequest{}

	decoder := json.NewDecoder(r.Body)
	if err := decoder.Decode(j); err != nil {
		panic(err)
	}

	an := negroni.New()
	an.UseHandler(acquia.NewRouter(acquia.NewServerInstance("default")))

	laddr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:0") // listen to all the things
	if err != nil {
		panic(err)
	}

	l, err := net.ListenTCP("tcp", laddr)
	if err != nil {
		panic(err)
	}
	kal := tcpKeepAliveListener{l}

	// The Addr prop shouldn't actually be used, but set it to avoid triggering defaults
	srv := &http.Server{Addr: laddr.String(), Handler: an}

	si := ServerInstance{Listener: kal, HttpServer: srv}
	resp, err := json.Marshal(struct{
		Port int `json:"port"`
		ServerType string  `json:"server_type"`
		Version string `json:"version"`
	}{
		Port: kal.Addr().(*net.TCPAddr).Port,
		ServerType: "acquia",
		Version: "1.0",
	})

	if err != nil {
		panic(err)
	}

	w.Write(resp) // auto-sends 200 response
	servers = append(servers, si)
	go srv.Serve(kal)
}

func hhListServers(w http.ResponseWriter, r *http.Request) {

}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"os"
	"os/signal"
)

// interruptChannel is used to receive SIGINT (Ctrl+C) signals.
var interruptChannel chan os.Signal

// addHandlerChannel is used to add an interrupt handler to the list of handlers
// to be invoked on SIGINT (Ctrl+C) signals.
var addHandlerChannel = make(chan func())

// mainInterruptHandler listens for SIGINT (Ctrl+C) signals on the
// interruptChannel and invokes the registered interruptCallbacks accordingly.
// It also listens for callback registration.  It must be run as a goroutine.
func mainInterruptHandler() {
	// interruptCallbacks is a list of callbacks to invoke when a
	// SIGINT (Ctrl+C) is received.
	var interruptCallbacks []func()

	for {
		select {
		case <-interruptChannel:
			btcdLog.Infof("Received SIGINT (Ctrl+C).  Shutting down...")
			// run handlers in LIFO order.
			for i  := range interruptCallbacks {
				idx := len(interruptCallbacks) -1 -i
				callback := interruptCallbacks[idx]
				callback()
			}

			// Signal the main goroutine to shutdown.
			shutdownChannel <- true

		case handler := <-addHandlerChannel:
			interruptCallbacks = append(interruptCallbacks, handler)
		}
	}
}

// addInterruptHandler adds a handler to call when a SIGINT (Ctrl+C) is
// received.
func addInterruptHandler(handler func()) {
	// Create the channel and start the main interrupt handler which invokes
	// all other callbacks and exits if not already done.
	if interruptChannel == nil {
		interruptChannel = make(chan os.Signal, 1)
		signal.Notify(interruptChannel, os.Interrupt)
		go mainInterruptHandler()
	}

	addHandlerChannel <- handler
}
<commit_msg>go fmt.<commit_after>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
	"os"
	"os/signal"
)

// interruptChannel is used to receive SIGINT (Ctrl+C) signals.
var interruptChannel chan os.Signal

// addHandlerChannel is used to add an interrupt handler to the list of handlers
// to be invoked on SIGINT (Ctrl+C) signals.
var addHandlerChannel = make(chan func())

// mainInterruptHandler listens for SIGINT (Ctrl+C) signals on the
// interruptChannel and invokes the registered interruptCallbacks accordingly.
// It also listens for callback registration.  It must be run as a goroutine.
func mainInterruptHandler() {
	// interruptCallbacks is a list of callbacks to invoke when a
	// SIGINT (Ctrl+C) is received.
	var interruptCallbacks []func()

	for {
		select {
		case <-interruptChannel:
			btcdLog.Infof("Received SIGINT (Ctrl+C).  Shutting down...")
			// run handlers in LIFO order.
			for i := range interruptCallbacks {
				idx := len(interruptCallbacks) - 1 - i
				callback := interruptCallbacks[idx]
				callback()
			}

			// Signal the main goroutine to shutdown.
			shutdownChannel <- true

		case handler := <-addHandlerChannel:
			interruptCallbacks = append(interruptCallbacks, handler)
		}
	}
}

// addInterruptHandler adds a handler to call when a SIGINT (Ctrl+C) is
// received.
func addInterruptHandler(handler func()) {
	// Create the channel and start the main interrupt handler which invokes
	// all other callbacks and exits if not already done.
	if interruptChannel == nil {
		interruptChannel = make(chan os.Signal, 1)
		signal.Notify(interruptChannel, os.Interrupt)
		go mainInterruptHandler()
	}

	addHandlerChannel <- handler
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package interfacer

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"strings"
	"testing"

	"github.com/kisielk/gotool"
)

const testdata = "testdata"

var (
	warnsRe  = regexp.MustCompile(`^WARN (.*)\n?$`)
	singleRe = regexp.MustCompile(`([^ ]*) can be ([^ ]*)(,|$)`)
)

func goFiles(t *testing.T, p string) []string {
	if strings.HasSuffix(p, ".go") {
		return []string{p}
	}
	dirs := gotool.ImportPaths([]string{p})
	var paths []string
	for _, dir := range dirs {
		files, err := ioutil.ReadDir(dir)
		if err != nil {
			t.Fatal(err)
		}
		for _, file := range files {
			if file.IsDir() {
				continue
			}
			paths = append(paths, filepath.Join(dir, file.Name()))
		}
	}
	return paths
}

type identVisitor struct {
	fset   *token.FileSet
	idents map[string]token.Position
}

func identKey(pos token.Position, name string) string {
	return fmt.Sprintf("%d %s", pos.Line, name)
}

func (v *identVisitor) Visit(n ast.Node) ast.Visitor {
	switch x := n.(type) {
	case *ast.Ident:
		pos := v.fset.Position(x.Pos())
		v.idents[identKey(pos, x.Name)] = pos
	}
	return v
}

func identPositions(fset *token.FileSet, f *ast.File) map[string]token.Position {
	v := &identVisitor{
		fset:   fset,
		idents: make(map[string]token.Position),
	}
	ast.Walk(v, f)
	return v.idents
}

func wantedWarnings(t *testing.T, p string) []Warn {
	fset := token.NewFileSet()
	var warns []Warn
	for _, path := range goFiles(t, p) {
		src, err := os.Open(path)
		if err != nil {
			t.Fatal(err)
		}
		f, err := parser.ParseFile(fset, path, src, parser.ParseComments)
		src.Close()
		if err != nil {
			t.Fatal(err)
		}
		identPos := identPositions(fset, f)
		for _, group := range f.Comments {
			cm := warnsRe.FindStringSubmatch(group.Text())
			if cm == nil {
				continue
			}
			for _, m := range singleRe.FindAllStringSubmatch(cm[1], -1) {
				vname, tname := m[1], m[2]
				comPos := fset.Position(group.Pos())
				warns = append(warns, Warn{
					Pos:     identPos[identKey(comPos, vname)],
					Name:    vname,
					NewType: tname,
				})
			}
		}
	}
	return warns
}

func doTest(t *testing.T, p string) {
	t.Run(p, func(t *testing.T) {
		warns := wantedWarnings(t, p)
		doTestWarns(t, p, warns, p)
	})
}

func warnsJoin(warns []Warn) string {
	var b bytes.Buffer
	for _, warn := range warns {
		fmt.Fprintln(&b, warn.String())
	}
	return b.String()
}

func doTestWarns(t *testing.T, name string, exp []Warn, args ...string) {
	got, err := CheckArgsList(args)
	if err != nil {
		t.Fatalf("Did not want error in %s:\n%v", name, err)
	}
	if !reflect.DeepEqual(exp, got) {
		t.Fatalf("Output mismatch in %s:\nwant:\n%sgot:\n%s",
			name, warnsJoin(exp), warnsJoin(got))
	}
}

func endNewline(s string) string {
	if strings.HasSuffix(s, "\n") {
		return s
	}
	return s + "\n"
}

func doTestString(t *testing.T, name, exp string, args ...string) {
	var b bytes.Buffer
	switch len(args) {
	case 0:
		args = []string{name}
	case 1:
		if args[0] == "" {
			args = nil
		}
	}
	err := CheckArgsOutput(args, &b, true)
	if err != nil {
		t.Fatalf("Did not want error in %s:\n%v", name, err)
	}
	exp = endNewline(exp)
	got := b.String()
	if exp != got {
		t.Fatalf("Output mismatch in %s:\nExpected:\n%s\nGot:\n%s",
			name, exp, got)
	}
}

func inputPaths(t *testing.T, glob string) []string {
	all, err := filepath.Glob(glob)
	if err != nil {
		t.Fatal(err)
	}
	return all
}

func chdirUndo(t *testing.T, d string) func() {
	wd, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}
	if err := os.Chdir(d); err != nil {
		t.Fatal(err)
	}
	return func() {
		if err := os.Chdir(wd); err != nil {
			t.Fatal(err)
		}
	}
}

func runFileTests(t *testing.T, paths ...string) {
	defer chdirUndo(t, "files")()
	if len(paths) == 0 {
		paths = inputPaths(t, "*")
	}
	for _, p := range paths {
		doTest(t, p)
	}
}

func runLocalTests(t *testing.T, paths ...string) {
	defer chdirUndo(t, "local")()
	if len(paths) > 0 {
		for _, p := range paths {
			doTest(t, p)
		}
		return
	}
	for _, p := range inputPaths(t, "*") {
		paths = append(paths, "./"+p+"/...")
	}
	for _, p := range paths {
		doTest(t, p)
	}
	// non-recursive
	doTest(t, "./single")
	doTestString(t, "no-args", ".", "")
}

func runNonlocalTests(t *testing.T, paths ...string) {
	// std
	doTestString(t, "std-pkg", "sync/atomic\n", "sync/atomic")
	defer chdirUndo(t, "src")()
	if len(paths) > 0 {
		for _, p := range paths {
			doTest(t, p)
		}
		return
	}
	paths = inputPaths(t, "*")
	for _, p := range paths {
		doTest(t, p+"/...")
	}
	// local recursive
	doTest(t, "./nested/...")
	// non-recursive
	doTest(t, "single")
	// make sure we don't miss a package's imports
	doTestString(t, "grab-import", "grab-import\ngrab-import/use.go:27:15: s can be def2.Fooer")
	defer chdirUndo(t, "nested/pkg")()
	// relative paths
	doTestString(t, "rel-path", "nested/pkg\nsimple.go:12:17: rc can be Closer", "./...")
}

func TestMain(m *testing.M) {
	if err := os.Chdir(testdata); err != nil {
		panic(err)
	}
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	build.Default.GOPATH = wd
	gotool.DefaultContext.BuildContext.GOPATH = wd
	os.Exit(m.Run())
}

func TestWarns(t *testing.T) {
	runFileTests(t)
	runLocalTests(t)
	runNonlocalTests(t)
}

func doTestError(t *testing.T, name, exp string, args ...string) {
	switch len(args) {
	case 0:
		args = []string{name}
	case 1:
		if args[0] == "" {
			args = nil
		}
	}
	err := CheckArgsOutput(args, ioutil.Discard, false)
	if err == nil {
		t.Fatalf("Wanted error in %s, but none found.", name)
	}
	got := err.Error()
	if exp != got {
		t.Fatalf("Error mismatch in %s:\nExpected:\n%s\nGot:\n%s",
			name, exp, got)
	}
}

func TestErrors(t *testing.T) {
	// non-existent Go file
	doTestError(t, "missing.go", "open missing.go: no such file or directory")
	// local non-existent non-recursive
	doTestError(t, "./missing", "no initial packages were loaded")
	// non-local non-existent non-recursive
	doTestError(t, "missing", "no initial packages were loaded")
	// Mixing Go files and dirs
	doTestError(t, "wrong-args", "named files must be .go files: bar", "foo.go", "bar")
}

func TestExtraArg(t *testing.T) {
	err := CheckArgsOutput([]string{"single", "--", "foo", "bar"}, ioutil.Discard, false)
	got := err.Error()
	want := "unwanted extra args: [foo bar]"
	if got != want {
		t.Fatalf("Error mismatch:\nExpected:\n%s\nGot:\n%s", want, got)
	}
}
<commit_msg>test: adapt to new go/loader errors<commit_after>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package interfacer

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"strings"
	"testing"

	"github.com/kisielk/gotool"
)

const testdata = "testdata"

var (
	warnsRe  = regexp.MustCompile(`^WARN (.*)\n?$`)
	singleRe = regexp.MustCompile(`([^ ]*) can be ([^ ]*)(,|$)`)
)

func goFiles(t *testing.T, p string) []string {
	if strings.HasSuffix(p, ".go") {
		return []string{p}
	}
	dirs := gotool.ImportPaths([]string{p})
	var paths []string
	for _, dir := range dirs {
		files, err := ioutil.ReadDir(dir)
		if err != nil {
			t.Fatal(err)
		}
		for _, file := range files {
			if file.IsDir() {
				continue
			}
			paths = append(paths, filepath.Join(dir, file.Name()))
		}
	}
	return paths
}

type identVisitor struct {
	fset   *token.FileSet
	idents map[string]token.Position
}

func identKey(pos token.Position, name string) string {
	return fmt.Sprintf("%d %s", pos.Line, name)
}

func (v *identVisitor) Visit(n ast.Node) ast.Visitor {
	switch x := n.(type) {
	case *ast.Ident:
		pos := v.fset.Position(x.Pos())
		v.idents[identKey(pos, x.Name)] = pos
	}
	return v
}

func identPositions(fset *token.FileSet, f *ast.File) map[string]token.Position {
	v := &identVisitor{
		fset:   fset,
		idents: make(map[string]token.Position),
	}
	ast.Walk(v, f)
	return v.idents
}

func wantedWarnings(t *testing.T, p string) []Warn {
	fset := token.NewFileSet()
	var warns []Warn
	for _, path := range goFiles(t, p) {
		src, err := os.Open(path)
		if err != nil {
			t.Fatal(err)
		}
		f, err := parser.ParseFile(fset, path, src, parser.ParseComments)
		src.Close()
		if err != nil {
			t.Fatal(err)
		}
		identPos := identPositions(fset, f)
		for _, group := range f.Comments {
			cm := warnsRe.FindStringSubmatch(group.Text())
			if cm == nil {
				continue
			}
			for _, m := range singleRe.FindAllStringSubmatch(cm[1], -1) {
				vname, tname := m[1], m[2]
				comPos := fset.Position(group.Pos())
				warns = append(warns, Warn{
					Pos:     identPos[identKey(comPos, vname)],
					Name:    vname,
					NewType: tname,
				})
			}
		}
	}
	return warns
}

func doTest(t *testing.T, p string) {
	t.Run(p, func(t *testing.T) {
		warns := wantedWarnings(t, p)
		doTestWarns(t, p, warns, p)
	})
}

func warnsJoin(warns []Warn) string {
	var b bytes.Buffer
	for _, warn := range warns {
		fmt.Fprintln(&b, warn.String())
	}
	return b.String()
}

func doTestWarns(t *testing.T, name string, exp []Warn, args ...string) {
	got, err := CheckArgsList(args)
	if err != nil {
		t.Fatalf("Did not want error in %s:\n%v", name, err)
	}
	if !reflect.DeepEqual(exp, got) {
		t.Fatalf("Output mismatch in %s:\nwant:\n%sgot:\n%s",
			name, warnsJoin(exp), warnsJoin(got))
	}
}

func endNewline(s string) string {
	if strings.HasSuffix(s, "\n") {
		return s
	}
	return s + "\n"
}

func doTestString(t *testing.T, name, exp string, args ...string) {
	var b bytes.Buffer
	switch len(args) {
	case 0:
		args = []string{name}
	case 1:
		if args[0] == "" {
			args = nil
		}
	}
	err := CheckArgsOutput(args, &b, true)
	if err != nil {
		t.Fatalf("Did not want error in %s:\n%v", name, err)
	}
	exp = endNewline(exp)
	got := b.String()
	if exp != got {
		t.Fatalf("Output mismatch in %s:\nExpected:\n%s\nGot:\n%s",
			name, exp, got)
	}
}

func inputPaths(t *testing.T, glob string) []string {
	all, err := filepath.Glob(glob)
	if err != nil {
		t.Fatal(err)
	}
	return all
}

func chdirUndo(t *testing.T, d string) func() {
	wd, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}
	if err := os.Chdir(d); err != nil {
		t.Fatal(err)
	}
	return func() {
		if err := os.Chdir(wd); err != nil {
			t.Fatal(err)
		}
	}
}

func runFileTests(t *testing.T, paths ...string) {
	defer chdirUndo(t, "files")()
	if len(paths) == 0 {
		paths = inputPaths(t, "*")
	}
	for _, p := range paths {
		doTest(t, p)
	}
}

func runLocalTests(t *testing.T, paths ...string) {
	defer chdirUndo(t, "local")()
	if len(paths) > 0 {
		for _, p := range paths {
			doTest(t, p)
		}
		return
	}
	for _, p := range inputPaths(t, "*") {
		paths = append(paths, "./"+p+"/...")
	}
	for _, p := range paths {
		doTest(t, p)
	}
	// non-recursive
	doTest(t, "./single")
	doTestString(t, "no-args", ".", "")
}

func runNonlocalTests(t *testing.T, paths ...string) {
	// std
	doTestString(t, "std-pkg", "sync/atomic\n", "sync/atomic")
	defer chdirUndo(t, "src")()
	if len(paths) > 0 {
		for _, p := range paths {
			doTest(t, p)
		}
		return
	}
	paths = inputPaths(t, "*")
	for _, p := range paths {
		doTest(t, p+"/...")
	}
	// local recursive
	doTest(t, "./nested/...")
	// non-recursive
	doTest(t, "single")
	// make sure we don't miss a package's imports
	doTestString(t, "grab-import", "grab-import\ngrab-import/use.go:27:15: s can be def2.Fooer")
	defer chdirUndo(t, "nested/pkg")()
	// relative paths
	doTestString(t, "rel-path", "nested/pkg\nsimple.go:12:17: rc can be Closer", "./...")
}

func TestMain(m *testing.M) {
	if err := os.Chdir(testdata); err != nil {
		panic(err)
	}
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	build.Default.GOPATH = wd
	gotool.DefaultContext.BuildContext.GOPATH = wd
	os.Exit(m.Run())
}

func TestWarns(t *testing.T) {
	runFileTests(t)
	runLocalTests(t)
	runNonlocalTests(t)
}

func doTestError(t *testing.T, name, cont string, args ...string) {
	switch len(args) {
	case 0:
		args = []string{name}
	case 1:
		if args[0] == "" {
			args = nil
		}
	}
	err := CheckArgsOutput(args, ioutil.Discard, false)
	if err == nil {
		t.Fatalf("Wanted error in %s, but none found.", name)
	}
	got := err.Error()
	if !strings.Contains(got, cont) {
		t.Fatalf("Error mismatch in %s:\nExpected:\n%s\nGot:\n%s",
			name, cont, got)
	}
}

func TestErrors(t *testing.T) {
	// non-existent Go file
	doTestError(t, "missing.go", "missing.go: no such file or directory")
	// local non-existent non-recursive
	doTestError(t, "./missing", "no initial packages were loaded")
	// non-local non-existent non-recursive
	doTestError(t, "missing", "no initial packages were loaded")
	// Mixing Go files and dirs
	doTestError(t, "wrong-args", "named files must be .go files: bar", "foo.go", "bar")
}

func TestExtraArg(t *testing.T) {
	err := CheckArgsOutput([]string{"single", "--", "foo", "bar"}, ioutil.Discard, false)
	got := err.Error()
	want := "unwanted extra args: [foo bar]"
	if got != want {
		t.Fatalf("Error mismatch:\nExpected:\n%s\nGot:\n%s", want, got)
	}
}
<|endoftext|>


<commit_before>package internal

import (
	"log"
	"os"

	"github.com/hugelgupf/p9/internal/linux"
)

// ExtractErrno extracts a linux.Errno from a error, best effort.
//
// If the system-specific or Go-specific error cannot be mapped to anything, it
// will be logged an EIO will be returned.
func ExtractErrno(err error) linux.Errno {
	switch err {
	case os.ErrNotExist:
		return linux.ENOENT
	case os.ErrExist:
		return linux.EEXIST
	case os.ErrPermission:
		return linux.EACCES
	case os.ErrInvalid:
		return linux.EINVAL
	}

	// Attempt to unwrap.
	switch e := err.(type) {
	case linux.Errno:
		return e
	case *os.PathError:
		return ExtractErrno(e.Err)
	case *os.SyscallError:
		return ExtractErrno(e.Err)
	}

	if e := sysErrno(err); e != 0 {
		return e
	}

	// Default case.
	//
	// TODO: give the ability to turn this off.
	log.Printf("unknown error: %v", err)
	return linux.EIO
}
<commit_msg>internal: also unwrap LinkError<commit_after>package internal

import (
	"log"
	"os"

	"github.com/hugelgupf/p9/internal/linux"
)

// ExtractErrno extracts a linux.Errno from a error, best effort.
//
// If the system-specific or Go-specific error cannot be mapped to anything, it
// will be logged an EIO will be returned.
func ExtractErrno(err error) linux.Errno {
	switch err {
	case os.ErrNotExist:
		return linux.ENOENT
	case os.ErrExist:
		return linux.EEXIST
	case os.ErrPermission:
		return linux.EACCES
	case os.ErrInvalid:
		return linux.EINVAL
	}

	// Attempt to unwrap.
	switch e := err.(type) {
	case linux.Errno:
		return e
	case *os.PathError:
		return ExtractErrno(e.Err)
	case *os.SyscallError:
		return ExtractErrno(e.Err)
	case *os.LinkError:
		return ExtractErrno(e.Err)
	}

	if e := sysErrno(err); e != 0 {
		return e
	}

	// Default case.
	//
	// TODO: give the ability to turn this off.
	log.Printf("unknown error: %v", err)
	return linux.EIO
}
<|endoftext|>


<commit_before>package dbServices

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"path"
	"time"

	"sync"

	"github.com/DanielRenne/GoCore/core/serverSettings"
	"github.com/asdine/storm"
	_ "github.com/denisenkom/go-mssqldb"
	"github.com/fatih/color"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	_ "github.com/go-sql-driver/mysql"
)

var DBMutex *sync.RWMutex
var DB *sql.DB
var BoltDB *storm.DB
var MongoSession *mgo.Session
var MongoSessionAuth *mgo.Session
var MongoDB *mgo.Database
var MongoDBAuth *mgo.Database

var mongoDBOverride string
var mongoDBNameOverride string

const (

	//Driver Types
	DATABASE_DRIVER_MYSQL   = "mysql"
	DATABASE_DRIVER_MSSQL   = "mssql"
	DATABASE_DRIVER_BOLTDB  = "boltDB"
	DATABASE_DRIVER_MONGODB = "mongoDB"
)

func init() {
	DBMutex = &sync.RWMutex{}
}

func OverrideMongoDBConnection(connectionString string, dbName string) {
	mongoDBOverride = connectionString
	mongoDBNameOverride = dbName
}

func ReadMongoDB() (mdb *mgo.Database) {
	DBMutex.RLock()
	mdb = MongoDB
	DBMutex.RUnlock()
	return mdb
}

func ReadMongoDBAuth() (mdb *mgo.Database) {
	DBMutex.RLock()
	mdb = MongoDBAuth
	DBMutex.RUnlock()
	return mdb
}

func Initialize() error {

	fmt.Println("core dbServices initialized.")

	switch serverSettings.WebConfig.DbConnection.Driver {
	case DATABASE_DRIVER_MYSQL:
		return openSQLDriver()
	case DATABASE_DRIVER_MSSQL:
		return openSQLDriver()
	case DATABASE_DRIVER_BOLTDB:
		return openBolt()
	case DATABASE_DRIVER_MONGODB:
		return openMongo()
	}
	return nil
}

func openSQLDriver() error {
	var err error
	DBMutex.Lock()
	DB, err = sql.Open(serverSettings.WebConfig.DbConnection.Driver, serverSettings.WebConfig.DbConnection.ConnectionString)
	DBMutex.Unlock()

	if err != nil {
		color.Red("Open connection failed:" + err.Error())
		return err
	}

	DBMutex.RLock()
	color.Cyan("Open Database Connections: " + string(DB.Stats().OpenConnections))
	DBMutex.RUnlock()
	return nil
}

func openBolt() error {

	myDBDir := serverSettings.APP_LOCATION + "/db/" + serverSettings.WebConfig.DbConnection.ConnectionString

	os.Mkdir(path.Dir(myDBDir), 0777)

	// (Create if not exist) open a database
	var err error
	DBMutex.Lock()
	BoltDB, err = storm.Open(myDBDir, storm.AutoIncrement())
	DBMutex.Unlock()

	if err != nil {
		color.Red("Failed to create or open boltDB Database at " + myDBDir + ":\n\t" + err.Error())
		return err
	}

	color.Cyan("Successfully opened new bolt DB at " + myDBDir)
	return nil
}

func openMongo() error {

	if serverSettings.WebConfig.DbConnection.Replication.Enabled {
		info := new(mgo.DialInfo)
		info.Direct = true
		info.Timeout = time.Millisecond * 3000

		var addresses []string
		addresses = append(addresses, serverSettings.WebConfig.DbConnection.Replication.Master)
		// for i, _ := range serverSettings.WebConfig.DbConnection.Replication.Slaves {
		// 	slave := serverSettings.WebConfig.DbConnection.Replication.Slaves[i]
		// 	addresses = append(addresses, slave)
		// }
		info.Addrs = addresses

		session, err := mgo.DialWithInfo(info)
		// session, err := mgo.Dial(serverSettings.WebConfig.DbConnection.Replication.SessionConnection)
		if err != nil { //  if you have a
			color.Red("Failed to create or open mongo Database to initialize replicaSet at " + serverSettings.WebConfig.DbConnection.Replication.Master + "\n\t" + err.Error())
		} else {
			time.Sleep(time.Millisecond * 500)
			result := Mongo_Result_Repl_Conf{}
			err = session.DB("admin").Run("replSetGetConfig", &result)
			if err != nil {
				color.Red("Failed to get buildInfo:  " + err.Error())
			} else {

				result.Config.Version = result.Config.Version + 1
				result.Config.Members[0].Host = serverSettings.WebConfig.DbConnection.Replication.Master
				result.Config.Members[0].Priority = 1
				result.Config.Members[0].Votes = 1

				for i, _ := range serverSettings.WebConfig.DbConnection.Replication.Slaves {
					slaveAddress := serverSettings.WebConfig.DbConnection.Replication.Slaves[i]
					if len(result.Config.Members) < i+2 {
						var slave Mongo_Replica_Member
						slave.Id = i + 1
						slave.Priority = i + 1
						slave.Votes = 1
						slave.Host = slaveAddress
						result.Config.Members = append(result.Config.Members, slave)
					} else {
						result.Config.Members[i+1].Host = slaveAddress
						result.Config.Members[i+1].Priority = i + 1
						result.Config.Members[i+1].Votes = 1
					}
				}

				result.Config.Settings.HeartbeatTimeoutSecs = 5

				err = session.DB("admin").Run(bson.D{{"replSetReconfig", result.Config}, {"force", true}}, nil)
				if err != nil {
					color.Red("Failed to replSetReconfig:  " + err.Error())
				}
				log.Println("Successfully initialized replica sets.")
			}
		}
	}

	var err error
	connectionString := serverSettings.WebConfig.DbConnection.ConnectionString
	if mongoDBOverride != "" {
		connectionString = mongoDBOverride
	}

	DBMutex.Lock()
	MongoSession, err = mgo.Dial(connectionString) // open an connection -> Dial function
	DBMutex.Unlock()

	if err != nil { //  if you have a
		color.Red("Failed to create or open mongo Database at " + connectionString + "\n\t" + err.Error())
		return err
	}

	if serverSettings.WebConfig.HasDbAuth && serverSettings.WebConfig.DbAuthConnection.AuthServer {

		DBMutex.Lock()
		MongoSessionAuth, err = mgo.Dial(connectionString) // open an connection -> Dial function
		DBMutex.Unlock()

		if err != nil { //  if you have a
			color.Red("Failed to create or open mongo Database at " + connectionString + "\n\t" + err.Error())
			return err
		}
	}

	return connectMongoDB()
}

func connectMongoDB() error {
	DBMutex.Lock()
	MongoSession.SetMode(mgo.Monotonic, true) // Optional. Switch the session to a monotonic behavior.
	MongoSession.SetSyncTimeout(2000 * time.Millisecond)

	dbName := serverSettings.WebConfig.DbConnection.Database
	if mongoDBNameOverride != "" {
		dbName = mongoDBNameOverride
	}

	MongoDB = MongoSession.DB(dbName)
	color.Green("Mongo Database Connected Successfully.")
	if serverSettings.WebConfig.HasDbAuth {
		MongoSessionAuth.SetMode(mgo.Monotonic, true) // Optional. Switch the session to a monotonic behavior.
		MongoSessionAuth.SetSyncTimeout(2000 * time.Millisecond)
		MongoDBAuth = MongoSession.DB(serverSettings.WebConfig.DbAuthConnection.Database)
		color.Green("Mongo Authentication Database Connected Successfully.")
	}
	DBMutex.Unlock()
	return nil
}
<commit_msg>Removed Autoincrement boltDB.<commit_after>package dbServices

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"path"
	"time"

	"sync"

	"github.com/DanielRenne/GoCore/core/serverSettings"
	"github.com/asdine/storm"
	_ "github.com/denisenkom/go-mssqldb"
	"github.com/fatih/color"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	_ "github.com/go-sql-driver/mysql"
)

var DBMutex *sync.RWMutex
var DB *sql.DB
var BoltDB *storm.DB
var MongoSession *mgo.Session
var MongoSessionAuth *mgo.Session
var MongoDB *mgo.Database
var MongoDBAuth *mgo.Database

var mongoDBOverride string
var mongoDBNameOverride string

const (

	//Driver Types
	DATABASE_DRIVER_MYSQL   = "mysql"
	DATABASE_DRIVER_MSSQL   = "mssql"
	DATABASE_DRIVER_BOLTDB  = "boltDB"
	DATABASE_DRIVER_MONGODB = "mongoDB"
)

func init() {
	DBMutex = &sync.RWMutex{}
}

func OverrideMongoDBConnection(connectionString string, dbName string) {
	mongoDBOverride = connectionString
	mongoDBNameOverride = dbName
}

func ReadMongoDB() (mdb *mgo.Database) {
	DBMutex.RLock()
	mdb = MongoDB
	DBMutex.RUnlock()
	return mdb
}

func ReadMongoDBAuth() (mdb *mgo.Database) {
	DBMutex.RLock()
	mdb = MongoDBAuth
	DBMutex.RUnlock()
	return mdb
}

func Initialize() error {

	fmt.Println("core dbServices initialized.")

	switch serverSettings.WebConfig.DbConnection.Driver {
	case DATABASE_DRIVER_MYSQL:
		return openSQLDriver()
	case DATABASE_DRIVER_MSSQL:
		return openSQLDriver()
	case DATABASE_DRIVER_BOLTDB:
		return openBolt()
	case DATABASE_DRIVER_MONGODB:
		return openMongo()
	}
	return nil
}

func openSQLDriver() error {
	var err error
	DBMutex.Lock()
	DB, err = sql.Open(serverSettings.WebConfig.DbConnection.Driver, serverSettings.WebConfig.DbConnection.ConnectionString)
	DBMutex.Unlock()

	if err != nil {
		color.Red("Open connection failed:" + err.Error())
		return err
	}

	DBMutex.RLock()
	color.Cyan("Open Database Connections: " + string(DB.Stats().OpenConnections))
	DBMutex.RUnlock()
	return nil
}

func openBolt() error {

	myDBDir := serverSettings.APP_LOCATION + "/db/" + serverSettings.WebConfig.DbConnection.ConnectionString

	os.Mkdir(path.Dir(myDBDir), 0777)

	// (Create if not exist) open a database
	var err error
	DBMutex.Lock()
	BoltDB, err = storm.Open(myDBDir)
	DBMutex.Unlock()

	if err != nil {
		color.Red("Failed to create or open boltDB Database at " + myDBDir + ":\n\t" + err.Error())
		return err
	}

	color.Cyan("Successfully opened new bolt DB at " + myDBDir)
	return nil
}

func openMongo() error {

	if serverSettings.WebConfig.DbConnection.Replication.Enabled {
		info := new(mgo.DialInfo)
		info.Direct = true
		info.Timeout = time.Millisecond * 3000

		var addresses []string
		addresses = append(addresses, serverSettings.WebConfig.DbConnection.Replication.Master)
		// for i, _ := range serverSettings.WebConfig.DbConnection.Replication.Slaves {
		// 	slave := serverSettings.WebConfig.DbConnection.Replication.Slaves[i]
		// 	addresses = append(addresses, slave)
		// }
		info.Addrs = addresses

		session, err := mgo.DialWithInfo(info)
		// session, err := mgo.Dial(serverSettings.WebConfig.DbConnection.Replication.SessionConnection)
		if err != nil { //  if you have a
			color.Red("Failed to create or open mongo Database to initialize replicaSet at " + serverSettings.WebConfig.DbConnection.Replication.Master + "\n\t" + err.Error())
		} else {
			time.Sleep(time.Millisecond * 500)
			result := Mongo_Result_Repl_Conf{}
			err = session.DB("admin").Run("replSetGetConfig", &result)
			if err != nil {
				color.Red("Failed to get buildInfo:  " + err.Error())
			} else {

				result.Config.Version = result.Config.Version + 1
				result.Config.Members[0].Host = serverSettings.WebConfig.DbConnection.Replication.Master
				result.Config.Members[0].Priority = 1
				result.Config.Members[0].Votes = 1

				for i, _ := range serverSettings.WebConfig.DbConnection.Replication.Slaves {
					slaveAddress := serverSettings.WebConfig.DbConnection.Replication.Slaves[i]
					if len(result.Config.Members) < i+2 {
						var slave Mongo_Replica_Member
						slave.Id = i + 1
						slave.Priority = i + 1
						slave.Votes = 1
						slave.Host = slaveAddress
						result.Config.Members = append(result.Config.Members, slave)
					} else {
						result.Config.Members[i+1].Host = slaveAddress
						result.Config.Members[i+1].Priority = i + 1
						result.Config.Members[i+1].Votes = 1
					}
				}

				result.Config.Settings.HeartbeatTimeoutSecs = 5

				err = session.DB("admin").Run(bson.D{{"replSetReconfig", result.Config}, {"force", true}}, nil)
				if err != nil {
					color.Red("Failed to replSetReconfig:  " + err.Error())
				}
				log.Println("Successfully initialized replica sets.")
			}
		}
	}

	var err error
	connectionString := serverSettings.WebConfig.DbConnection.ConnectionString
	if mongoDBOverride != "" {
		connectionString = mongoDBOverride
	}

	DBMutex.Lock()
	MongoSession, err = mgo.Dial(connectionString) // open an connection -> Dial function
	DBMutex.Unlock()

	if err != nil { //  if you have a
		color.Red("Failed to create or open mongo Database at " + connectionString + "\n\t" + err.Error())
		return err
	}

	if serverSettings.WebConfig.HasDbAuth && serverSettings.WebConfig.DbAuthConnection.AuthServer {

		DBMutex.Lock()
		MongoSessionAuth, err = mgo.Dial(connectionString) // open an connection -> Dial function
		DBMutex.Unlock()

		if err != nil { //  if you have a
			color.Red("Failed to create or open mongo Database at " + connectionString + "\n\t" + err.Error())
			return err
		}
	}

	return connectMongoDB()
}

func connectMongoDB() error {
	DBMutex.Lock()
	MongoSession.SetMode(mgo.Monotonic, true) // Optional. Switch the session to a monotonic behavior.
	MongoSession.SetSyncTimeout(2000 * time.Millisecond)

	dbName := serverSettings.WebConfig.DbConnection.Database
	if mongoDBNameOverride != "" {
		dbName = mongoDBNameOverride
	}

	MongoDB = MongoSession.DB(dbName)
	color.Green("Mongo Database Connected Successfully.")
	if serverSettings.WebConfig.HasDbAuth {
		MongoSessionAuth.SetMode(mgo.Monotonic, true) // Optional. Switch the session to a monotonic behavior.
		MongoSessionAuth.SetSyncTimeout(2000 * time.Millisecond)
		MongoDBAuth = MongoSession.DB(serverSettings.WebConfig.DbAuthConnection.Database)
		color.Green("Mongo Authentication Database Connected Successfully.")
	}
	DBMutex.Unlock()
	return nil
}
<|endoftext|>