<commit_before>/*
	This is the server package.
	The purpouse of this package is to map a connection to each player(who is online) so we have a comunication chanel.

*/
package server

import (
	"runtime/debug"
	"fmt"
	"github.com/fzzy/sockjs-go/sockjs"
	"log"
	"net"
	"net/http"
	"path"
	"runtime"
	"warcluster/db_manager"
	"warcluster/entities"
)

var listener net.Listener

var sessions *sockjs.SessionPool = sockjs.NewSessionPool() //This is the SockJs sessions pull (a list of all the currently active client's sessions).

/*This function goes trough all the procedurs needed for the werver to be initialized.
Create an empty connections pool and start the listening foe messages loop.*/
func Start(host string, port int) error {
	log.Print("Server is starting...")
	log.Println("Server is up and running!")

	mux := sockjs.NewServeMux(http.DefaultServeMux)
	conf := sockjs.NewConfig()

	http.HandleFunc("/console", staticHandler)
	http.Handle("/static", http.FileServer(http.Dir(getStaticDir())))
	mux.Handle("/universe", handler, conf)

	if err := ListenAndServe(fmt.Sprintf("%v:%v", host, port), mux); err != nil {
		log.Println(err)
		return err
	}

	return Stop()
}

// ListenAndServe listens on the TCP network address srv.Addr and then
// calls Serve to handle requests on incoming connections.  If
// srv.Addr is blank, ":http" is used.
func ListenAndServe(address string, mux *sockjs.ServeMux) error {
	var err error

	server := &http.Server{Addr: address, Handler: mux}
	addr := server.Addr
	if addr == "" {
		addr = ":http"
	}
	listener, err = net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	return server.Serve(listener)
}

//Die biatch and get the fuck out.
func Stop() error {
	log.Println("Server is shutting down...")
	listener.Close()
	log.Println("Server has stopped.")
	return nil
}

//Returns the HTML page needed to display the debug page (server "chat" window).
func staticHandler(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, path.Join(getStaticDir(), "/index.html"))
}

/*This function is called from the message handler to parse the first message for every new connection.
It check for existing user in the DB and logs him if the password is correct.
If the user is new he is initiated and a new home planet nad solar system are generated.*/
func login(session sockjs.Session) (*Client, error) {
	nickname, player := authenticate(session)

	client := &Client{
		Session:  session,
		Nickname: nickname,
		Player:   player,
	}

	home_planet_entity, _ := db_manager.GetEntity(client.Player.HomePlanet)
	home_planet := home_planet_entity.(*entities.Planet)
	session.Send([]byte(fmt.Sprintf("{\"Command\": \"login_success\", \"Username\": \"%s\", \"Position\": [%d, %d] }",
		client.Nickname, home_planet.GetCoords()[0], home_planet.GetCoords()[1])))
	return client, nil
}

/*On the first received message from each connection the server will call the handler.
Add new session to the session pool, call the login func to validate the connection and
if the connection is valid enters "while true" state and uses ParseRequest to parse the requests.

Shocking right?!?!*/
func handler(session sockjs.Session) {
	sessions.Add(session)
	defer sessions.Remove(session)
	defer func() {
		if panicked := recover(); panicked != nil {
			log.Println(string(debug.Stack()))
			return
		}
	}()

	if client, err := login(session); err == nil {
		for {
			message := session.Receive()
			if message == nil {
				break
			}

			if request, err := UnmarshalRequest(message, client); err == nil {
				if action, err := ParseRequest(request); err == nil {
					if err := action(request); err != nil {
						log.Println(err)
					}
				} else {
					log.Println("Error in server.main.handler:", err.Error())
				}
			} else {
				log.Println("Error in server.main.handler:", err.Error())
			}
		}
	} else {
		session.End()
	}
}

func getStaticDir() string {
	_, filename, _, _ := runtime.Caller(1)
	return path.Join(path.Dir(filename), "../static")
}
<commit_msg>Pretify error handling in user requests<commit_after>/*
	This is the server package.
	The purpouse of this package is to map a connection to each player(who is online) so we have a comunication chanel.

*/
package server

import (
	"runtime/debug"
	"fmt"
	"github.com/fzzy/sockjs-go/sockjs"
	"log"
	"net"
	"net/http"
	"path"
	"runtime"
	"warcluster/db_manager"
	"warcluster/entities"
)

var listener net.Listener

var sessions *sockjs.SessionPool = sockjs.NewSessionPool() //This is the SockJs sessions pull (a list of all the currently active client's sessions).

/*This function goes trough all the procedurs needed for the werver to be initialized.
Create an empty connections pool and start the listening foe messages loop.*/
func Start(host string, port int) error {
	log.Print("Server is starting...")
	log.Println("Server is up and running!")

	mux := sockjs.NewServeMux(http.DefaultServeMux)
	conf := sockjs.NewConfig()

	http.HandleFunc("/console", staticHandler)
	http.Handle("/static", http.FileServer(http.Dir(getStaticDir())))
	mux.Handle("/universe", handler, conf)

	if err := ListenAndServe(fmt.Sprintf("%v:%v", host, port), mux); err != nil {
		log.Println(err)
		return err
	}

	return Stop()
}

// ListenAndServe listens on the TCP network address srv.Addr and then
// calls Serve to handle requests on incoming connections.  If
// srv.Addr is blank, ":http" is used.
func ListenAndServe(address string, mux *sockjs.ServeMux) error {
	var err error

	server := &http.Server{Addr: address, Handler: mux}
	addr := server.Addr
	if addr == "" {
		addr = ":http"
	}
	listener, err = net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	return server.Serve(listener)
}

//Die biatch and get the fuck out.
func Stop() error {
	log.Println("Server is shutting down...")
	listener.Close()
	log.Println("Server has stopped.")
	return nil
}

//Returns the HTML page needed to display the debug page (server "chat" window).
func staticHandler(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, path.Join(getStaticDir(), "/index.html"))
}

/*This function is called from the message handler to parse the first message for every new connection.
It check for existing user in the DB and logs him if the password is correct.
If the user is new he is initiated and a new home planet nad solar system are generated.*/
func login(session sockjs.Session) (*Client, error) {
	nickname, player := authenticate(session)

	client := &Client{
		Session:  session,
		Nickname: nickname,
		Player:   player,
	}

	home_planet_entity, _ := db_manager.GetEntity(client.Player.HomePlanet)
	home_planet := home_planet_entity.(*entities.Planet)
	session.Send([]byte(fmt.Sprintf("{\"Command\": \"login_success\", \"Username\": \"%s\", \"Position\": [%d, %d] }",
		client.Nickname, home_planet.GetCoords()[0], home_planet.GetCoords()[1])))
	return client, nil
}

/*On the first received message from each connection the server will call the handler.
Add new session to the session pool, call the login func to validate the connection and
if the connection is valid enters "while true" state and uses ParseRequest to parse the requests.

Shocking right?!?!*/
func handler(session sockjs.Session) {
	sessions.Add(session)
	defer sessions.Remove(session)
	defer func() {
		if panicked := recover(); panicked != nil {
			log.Println(string(debug.Stack()))
			return
		}
	}()

	if client, err := login(session); err == nil {
		for {
			message := session.Receive()
			if message == nil {
				break
			}

			if request, err := UnmarshalRequest(message, client); err == nil {
				if action, err := ParseRequest(request); err == nil {
					if err := action(request); err != nil {
						log.Println(err)
					}
				} else {
					log.Println("Error in server.main.handler.ParseRequest:", err.Error())
				}
			} else {
				log.Println("Error in server.main.handler.UnmarshalRequest:", err.Error())
			}
		}
	} else {
		session.End()
	}
}

func getStaticDir() string {
	_, filename, _, _ := runtime.Caller(1)
	return path.Join(path.Dir(filename), "../static")
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/jbrodriguez/mlog"
	"github.com/jbrodriguez/pubsub"
	"jbrodriguez/mediagui/server/lib"
	"jbrodriguez/mediagui/server/services"
	"log"
	"os"
	"os/signal"
	"path/filepath"
)

var Version string

func main() {
	// look for mediagui.conf at the following places
	// $HOME/.mediagui/mediagui.conf
	// /usr/local/etc/mediagui.conf
	// <current dir>/mediagui.conf
	home := os.Getenv("HOME")

	cwd, err := os.Getwd()
	if err != nil {
		log.Printf("Unable to get current directory: %s", err.Error())
		os.Exit(1)
	}

	locations := []string{
		filepath.Join(home, ".mediagui/mediagui.conf"),
		"/usr/local/etc/mediagui.conf",
		filepath.Join(cwd, "mediagui.conf"),
	}

	settings, err := lib.NewSettings(Version, home, locations)
	if err != nil {
		log.Printf("Unable to start the app: %s", err.Error())
		os.Exit(2)
	}

	if settings.LogDir != "" {
		mlog.Start(mlog.LevelInfo, filepath.Join(settings.LogDir, "mediagui.log"))
	} else {
		mlog.Start(mlog.LevelInfo, "")
	}

	mlog.Info("mediagui v%s starting ...", Version)

	bus := pubsub.New(623)

	socket := services.NewSocket(bus, settings)
	server := services.NewServer(bus, settings)
	core := services.NewCore(bus, settings)
	dal := services.NewDal(bus, settings)
	scanner := services.NewScanner(bus, settings)

	socket.Start()
	scanner.Start()
	dal.Start()
	server.Start()
	core.Start()

	mlog.Info("Press Ctrl+C to stop ...")

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	for _ = range c {
		mlog.Info("Received an interrupt, shutting the app down ...")

		core.Stop()
		server.Stop()
		dal.Stop()
		scanner.Stop()
		socket.Stop()

		break
	}

	mlog.Stop()
}
<commit_msg>- Start scraper service - Fix services starting order<commit_after>package main

import (
	"github.com/jbrodriguez/mlog"
	"github.com/jbrodriguez/pubsub"
	"jbrodriguez/mediagui/server/lib"
	"jbrodriguez/mediagui/server/services"
	"log"
	"os"
	"os/signal"
	"path/filepath"
)

var Version string

func main() {
	// look for mediagui.conf at the following places
	// $HOME/.mediagui/mediagui.conf
	// /usr/local/etc/mediagui.conf
	// <current dir>/mediagui.conf
	home := os.Getenv("HOME")

	cwd, err := os.Getwd()
	if err != nil {
		log.Printf("Unable to get current directory: %s", err.Error())
		os.Exit(1)
	}

	locations := []string{
		filepath.Join(home, ".mediagui/mediagui.conf"),
		"/usr/local/etc/mediagui.conf",
		filepath.Join(cwd, "mediagui.conf"),
	}

	settings, err := lib.NewSettings(Version, home, locations)
	if err != nil {
		log.Printf("Unable to start the app: %s", err.Error())
		os.Exit(2)
	}

	if settings.LogDir != "" {
		mlog.Start(mlog.LevelInfo, filepath.Join(settings.LogDir, "mediagui.log"))
	} else {
		mlog.Start(mlog.LevelInfo, "")
	}

	mlog.Info("mediagui v%s starting ...", Version)

	bus := pubsub.New(623)

	dal := services.NewDal(bus, settings)
	socket := services.NewSocket(bus, settings)
	server := services.NewServer(bus, settings)
	scanner := services.NewScanner(bus, settings)
	scraper := services.NewScraper(bus, settings)
	core := services.NewCore(bus, settings)

	dal.Start()
	socket.Start()
	server.Start()
	scanner.Start()
	scraper.Start()
	core.Start()

	mlog.Info("Press Ctrl+C to stop ...")

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	for _ = range c {
		mlog.Info("Received an interrupt, shutting the app down ...")

		core.Stop()
		scraper.Stop()
		scanner.Stop()
		server.Stop()
		socket.Stop()
		dal.Stop()

		break
	}

	mlog.Stop()
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"os"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/blacktop/vm-proxy/server/vbox"
	"github.com/blacktop/vm-proxy/server/vmware"
	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"github.com/urfave/cli"
)

var (
	// Version stores the server's version
	Version string
	// BuildTime stores the server's build time
	BuildTime string
	// GitCommit stores server's gitcommit
	GitCommit string
	// Token stores the server api token
	Token string
	// Host server host
	Host string
	// Port server port
	Port string
)

var appHelpTemplate = `Usage: {{.Name}} {{if .Flags}}[OPTIONS] {{end}}COMMAND [arg...]

{{.Usage}}

Version: {{.Version}}{{if or .Author .Email}}

Author:{{if .Author}}
  {{.Author}}{{if .Email}} - <{{.Email}}>{{end}}{{else}}
  {{.Email}}{{end}}{{end}}
{{if .Flags}}
Options:
  {{range .Flags}}{{.}}
  {{end}}{{end}}
Commands:
  {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
  {{end}}
Run '{{.Name}} COMMAND --help' for more information on a command.
`

func main() {

	cli.AppHelpTemplate = appHelpTemplate
	app := cli.NewApp()

	app.Name = "vm-proxy"
	app.Author = "blacktop"
	app.Email = "https://github.com/blacktop"
	app.Version = Version + ", BuildTime: " + BuildTime
	app.Compiled, _ = time.Parse("20060102", BuildTime)
	app.Usage = "VM Proxy Server - Allows hypervisors to be controlled from docker containers"
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "verbose, V",
			Usage: "verbose output",
		},
		cli.StringFlag{
			Name:        "host",
			Value:       "127.0.0.1",
			Usage:       "vm-proxy server host",
			EnvVar:      "VMPROXY_HOST",
			Destination: &Host,
		},
		cli.StringFlag{
			Name:        "port",
			Value:       "3993",
			Usage:       "vm-proxy server port",
			EnvVar:      "VMPROXY_PORT",
			Destination: &Port,
		},
		cli.StringFlag{
			Name:        "token",
			Value:       "",
			Usage:       "webhook token",
			EnvVar:      "VMPROXY_TOKEN",
			Destination: &Token,
		},
	}
	app.Commands = []cli.Command{
		{
			Name:    "update",
			Aliases: []string{"u"},
			Usage:   "Update images",
			Action: func(c *cli.Context) error {
				return nil
			},
		},
		{
			Name:    "export",
			Aliases: []string{"u"},
			Usage:   "Export Database",
			Action: func(c *cli.Context) error {
				return nil
			},
		},
	}
	app.Action = func(c *cli.Context) error {

		if c.Bool("verbose") {
			log.SetLevel(log.DebugLevel)
		}

		if len(c.String("token")) == 0 {
			log.Warn("no webhook token set: --token")
		}

		// create http routes
		router := mux.NewRouter().StrictSlash(true)
		// virtualbox routes
		router.HandleFunc("/vbox/list", vbox.List).Methods("GET")
		// router.HandleFunc("/vbox/{source:(?:giphy|xkcd|dilbert|default|contrib)}/{file}", updateImageKeywords).Methods("PATCH")
		// vmware routes
		router.HandleFunc("/vmware/list", vmware.List).Methods("GET")
		// router.HandleFunc("/vmware/{source:(?:giphy|xkcd|dilbert|default|contrib)}/{file}", updateImageKeywords).Methods("PATCH")

		err := GenerateCerts(Host + ":" + Port)
		if err != nil {
			log.Fatal(err)
		}

		// start microservice
		log.WithFields(log.Fields{
			"host":  Host,
			"port":  Port,
			"token": Token,
		}).Info("vm-proxy service listening")

		loggedRouter := handlers.LoggingHandler(os.Stdout, router)
		log.Fatal(http.ListenAndServeTLS(":"+Port, "cert.pem", "key.pem", loggedRouter))

		return nil
	}

	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>actually use the certs you generate<commit_after>package main

import (
	"net/http"
	"os"
	"path/filepath"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/blacktop/vm-proxy/server/vbox"
	"github.com/blacktop/vm-proxy/server/vmware"
	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	homedir "github.com/mitchellh/go-homedir"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
)

var (
	// Version stores the server's version
	Version string
	// BuildTime stores the server's build time
	BuildTime string
	// GitCommit stores server's gitcommit
	GitCommit string
	// Token stores the server api token
	Token string
	// Host server host
	Host string
	// Port server port
	Port string
)

var appHelpTemplate = `Usage: {{.Name}} {{if .Flags}}[OPTIONS] {{end}}COMMAND [arg...]

{{.Usage}}

Version: {{.Version}}{{if or .Author .Email}}

Author:{{if .Author}}
  {{.Author}}{{if .Email}} - <{{.Email}}>{{end}}{{else}}
  {{.Email}}{{end}}{{end}}
{{if .Flags}}
Options:
  {{range .Flags}}{{.}}
  {{end}}{{end}}
Commands:
  {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
  {{end}}
Run '{{.Name}} COMMAND --help' for more information on a command.
`

func main() {

	cli.AppHelpTemplate = appHelpTemplate
	app := cli.NewApp()

	app.Name = "vm-proxy"
	app.Author = "blacktop"
	app.Email = "https://github.com/blacktop"
	app.Version = Version + ", BuildTime: " + BuildTime
	app.Compiled, _ = time.Parse("20060102", BuildTime)
	app.Usage = "VM Proxy Server - Allows hypervisors to be controlled from docker containers"
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "verbose, V",
			Usage: "verbose output",
		},
		cli.StringFlag{
			Name:        "host",
			Value:       "127.0.0.1",
			Usage:       "vm-proxy server host",
			EnvVar:      "VMPROXY_HOST",
			Destination: &Host,
		},
		cli.StringFlag{
			Name:        "port",
			Value:       "3993",
			Usage:       "vm-proxy server port",
			EnvVar:      "VMPROXY_PORT",
			Destination: &Port,
		},
		cli.StringFlag{
			Name:        "token",
			Value:       "",
			Usage:       "webhook token",
			EnvVar:      "VMPROXY_TOKEN",
			Destination: &Token,
		},
	}
	app.Commands = []cli.Command{
		{
			Name:    "update",
			Aliases: []string{"u"},
			Usage:   "Update images",
			Action: func(c *cli.Context) error {
				return nil
			},
		},
		{
			Name:    "export",
			Aliases: []string{"u"},
			Usage:   "Export Database",
			Action: func(c *cli.Context) error {
				return nil
			},
		},
	}
	app.Action = func(c *cli.Context) error {

		if c.Bool("verbose") {
			log.SetLevel(log.DebugLevel)
		}

		if len(c.String("token")) == 0 {
			log.Warn("no webhook token set: --token")
		}

		// create http routes
		router := mux.NewRouter().StrictSlash(true)
		// virtualbox routes
		router.HandleFunc("/vbox/list", vbox.List).Methods("GET")
		// router.HandleFunc("/vbox/{source:(?:giphy|xkcd|dilbert|default|contrib)}/{file}", updateImageKeywords).Methods("PATCH")
		// vmware routes
		router.HandleFunc("/vmware/list", vmware.List).Methods("GET")
		// router.HandleFunc("/vmware/{source:(?:giphy|xkcd|dilbert|default|contrib)}/{file}", updateImageKeywords).Methods("PATCH")

		err := GenerateCerts(Host + ":" + Port)
		if err != nil {
			log.Fatal(err)
		}

		// start microservice
		log.WithFields(log.Fields{
			"host":  Host,
			"port":  Port,
			"token": Token,
		}).Info("vm-proxy service listening")

		home, err := homedir.Dir()
		if err != nil {
			return errors.Wrap(err, "could not detect users home directory")
		}
		certPath := filepath.Join(home, ".vmproxy", "cert.pem")
		keyPath := filepath.Join(home, ".vmproxy", "key.pem")

		loggedRouter := handlers.LoggingHandler(os.Stdout, router)
		log.Fatal(http.ListenAndServeTLS(":"+Port, certPath, keyPath, loggedRouter))

		return nil
	}

	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"time"
)

type Packet struct {
	source  string
	arrived time.Time
	content []byte
}

func main() {
	packets := make(chan Packet, 200) // share until we start assembling multi-sentcence messages
	send := make(chan string)
	logger := time.NewTicker(10 * time.Second).C
	go Log(logger)
	readAIS(send)
	ecc := NewPacketHandler("ECC", packets)
	go ReadHTTP("http://aishub.ais.ecc.no/raw", 5*time.Second, &ecc)
	kystverket := NewPacketHandler("Kystverket", packets)
	go ReadTCP("153.44.253.27:5631", 5*time.Second, &kystverket)
	//test := NewPacketHandler("test", packets)
	//http.SourceName += "_timeout"
	//go ReadHTTP("http://127.0.0.1:12345", 8*time.Second, &test)
	//tcp.SourceName += "_timeout"
	//go ReadTCP("test_timeout", "127.0.0.1:12345", 2*time.Second, &test)
	//http.SourceName += " test_redirect"
	//go ReadHTTP("test_redirect", "http://localhost:12346", 0*time.Second, &test)
	//loop := NewPacketHandler("test_redirect_loop", make(chan<- Packet))
	//go ReadHTTP("http://localhost:12347", 0*time.Second, &loop)
	//test.SourceName = "file"
	//go ReadFile("minute_ecc.log", &test)
	for packet := range packets {
		splitPacket(packet.content, send)
	}

	log.Println("Packets left: ", len(packets))
	log.Println(ecc.Log())
	log.Println(kystverket.Log())
	//log.Println(test.Log())
}

func Log(ticker <-chan time.Time) {
	for _ = range ticker {
		fmt.Println("source connections: ", listener_connections)
	}
}

func CheckErr(err error, msg string) {
	if err != nil {
		log.Fatalf("Failed to %s: %s\n", msg, err.Error())
	}
}
func ErrIf(cond bool, msg string) {
	if cond {
		log.Fatalln(msg)
	}
}
<commit_msg>Print statistics on Ctrl-C and `timeout`s<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

type Packet struct {
	source  string
	arrived time.Time
	content []byte
}

func main() {
	signalChan := make(chan os.Signal, 1)
	// Intercept ^C and `timeout`s
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

	packets := make(chan Packet, 200) // share until we start assembling multi-sentcence messages
	send := make(chan string)
	logger := time.NewTicker(10 * time.Second).C
	go Log(logger)
	readAIS(send)
	ecc := NewPacketHandler("ECC", packets)
	go ReadHTTP("http://aishub.ais.ecc.no/raw", 5*time.Second, &ecc)
	kystverket := NewPacketHandler("Kystverket", packets)
	go ReadTCP("153.44.253.27:5631", 5*time.Second, &kystverket)
	//test := NewPacketHandler("test", packets)
	//http.SourceName += "_timeout"
	//go ReadHTTP("http://127.0.0.1:12345", 8*time.Second, &test)
	//tcp.SourceName += "_timeout"
	//go ReadTCP("test_timeout", "127.0.0.1:12345", 2*time.Second, &test)
	//http.SourceName += " test_redirect"
	//go ReadHTTP("test_redirect", "http://localhost:12346", 0*time.Second, &test)
	//loop := NewPacketHandler("test_redirect_loop", make(chan<- Packet))
	//go ReadHTTP("http://localhost:12347", 0*time.Second, &loop)
	//test.SourceName = "file"
	//go ReadFile("minute_ecc.log", &test)
	go func() {
		for packet := range packets {
			splitPacket(packet.content, send)
		}
	}()

	// Here we wait for CTRL-C or some other kill signal
	_ = <-signalChan
	log.Println("Packets left: ", len(packets))
	log.Println(ecc.Log())
	log.Println(kystverket.Log())
	//log.Println(test.Log())
}

func Log(ticker <-chan time.Time) {
	for _ = range ticker {
		fmt.Println("source connections: ", listener_connections)
	}
}

func CheckErr(err error, msg string) {
	if err != nil {
		log.Fatalf("Failed to %s: %s\n", msg, err.Error())
	}
}
func ErrIf(cond bool, msg string) {
	if cond {
		log.Fatalln(msg)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/gorilla/mux"
	. "github.com/mickael-kerjean/filestash/server/common"
	. "github.com/mickael-kerjean/filestash/server/ctrl"
	. "github.com/mickael-kerjean/filestash/server/middleware"
	_ "github.com/mickael-kerjean/filestash/server/plugin"
	"net/http"
    "net/http/pprof"
	"os"
	"runtime"
	"runtime/debug"
	"strconv"
	"time"
)

func main() {
	app := App{}
	Init(&app)
}

func Init(a *App) {
	var middlewares []Middleware
	r := mux.NewRouter()

	if os.Getenv("DEBUG") == "true" {
		initDebugRoutes(r)
	}

	// API for Session
	session := r.PathPrefix("/api/session").Subrouter()
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart }
	session.HandleFunc("",                NewMiddlewareChain(SessionGet,          middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser }
	session.HandleFunc("",                NewMiddlewareChain(SessionAuthenticate, middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionTry }
	session.HandleFunc("",                NewMiddlewareChain(SessionLogout,       middlewares, *a)).Methods("DELETE")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax }
	session.HandleFunc("/auth/{service}", NewMiddlewareChain(SessionOAuthBackend, middlewares, *a)).Methods("GET")

	// API for admin
	middlewares = []Middleware{ ApiHeaders, SecureAjax }
	admin := r.PathPrefix("/admin/api").Subrouter()
	admin.HandleFunc("/session", NewMiddlewareChain(AdminSessionGet,            middlewares, *a)).Methods("GET")
	admin.HandleFunc("/session", NewMiddlewareChain(AdminSessionAuthenticate,   middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ ApiHeaders, AdminOnly, SecureAjax }
	admin.HandleFunc("/config",  NewMiddlewareChain(PrivateConfigHandler,       middlewares, *a)).Methods("GET")
	admin.HandleFunc("/config",  NewMiddlewareChain(PrivateConfigUpdateHandler, middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ IndexHeaders }
	admin.HandleFunc("/log",                        NewMiddlewareChain(FetchLogHandler,          middlewares, *a)).Methods("GET")
	r.PathPrefix("/admin").Handler(http.HandlerFunc(NewMiddlewareChain(IndexHandler(FILE_INDEX), middlewares, *a))).Methods("GET")

	// API for File management
	files := r.PathPrefix("/api/files").Subrouter()
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly }
	files.HandleFunc("/cat",    NewMiddlewareChain(FileCat,    middlewares, *a)).Methods("GET", "HEAD")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart, LoggedInOnly }
	files.HandleFunc("/cat",    NewMiddlewareChain(FileAccess, middlewares, *a)).Methods("OPTIONS")
	files.HandleFunc("/cat",    NewMiddlewareChain(FileSave,   middlewares, *a)).Methods("POST")
	files.HandleFunc("/ls",     NewMiddlewareChain(FileLs,     middlewares, *a)).Methods("GET")
	files.HandleFunc("/mv",     NewMiddlewareChain(FileMv,     middlewares, *a)).Methods("GET")
	files.HandleFunc("/rm",     NewMiddlewareChain(FileRm,     middlewares, *a)).Methods("GET")
	files.HandleFunc("/mkdir",  NewMiddlewareChain(FileMkdir,  middlewares, *a)).Methods("GET")
	files.HandleFunc("/touch",  NewMiddlewareChain(FileTouch,  middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ ApiHeaders, SessionStart, LoggedInOnly }
	files.HandleFunc("/search",  NewMiddlewareChain(FileSearch,  middlewares, *a)).Methods("GET")

	// API for exporter
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, RedirectSharedLoginIfNeeded, SessionStart, LoggedInOnly }
	r.PathPrefix("/api/export/{share}/{mtype0}/{mtype1}").Handler(NewMiddlewareChain(FileExport,  middlewares, *a))

	// API for Shared link
	share := r.PathPrefix("/api/share").Subrouter()
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart, LoggedInOnly }
	share.HandleFunc("",               NewMiddlewareChain(ShareList,        middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser }
	share.HandleFunc("/{share}/proof", NewMiddlewareChain(ShareVerifyProof, middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, CanManageShare }
	share.HandleFunc("/{share}",       NewMiddlewareChain(ShareDelete,      middlewares, *a)).Methods("DELETE")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser, CanManageShare }
	share.HandleFunc("/{share}",       NewMiddlewareChain(ShareUpsert,      middlewares, *a)).Methods("POST")

	// Webdav server / Shared Link
	middlewares = []Middleware{ IndexHeaders, SecureHeaders }
	r.HandleFunc("/s/{share}",         NewMiddlewareChain(IndexHandler(FILE_INDEX), middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ WebdavBlacklist, SessionStart }
	r.PathPrefix("/s/{share}").Handler(NewMiddlewareChain(WebdavHandler,            middlewares, *a))

	// Application Resources
	middlewares = []Middleware{ ApiHeaders }
	r.HandleFunc("/api/config",  NewMiddlewareChain(PublicConfigHandler,                             middlewares, *a)).Methods("GET")
	r.HandleFunc("/api/backend", NewMiddlewareChain(AdminBackend,                                    middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ StaticHeaders }
	r.PathPrefix("/assets").Handler(http.HandlerFunc(NewMiddlewareChain(StaticHandler(FILE_ASSETS),  middlewares, *a))).Methods("GET")
	r.HandleFunc("/favicon.ico", func(res http.ResponseWriter, req *http.Request) {
		http.Redirect(res, req, "/assets/logo/favicon.ico", http.StatusMovedPermanently)
	})
	middlewares = []Middleware{ IndexHeaders }
	r.HandleFunc("/about",                     NewMiddlewareChain(AboutHandler,                      middlewares, *a)).Methods("GET")
	for _, obj := range Hooks.Get.HttpEndpoint() {
		obj(r)
	}
	r.HandleFunc("/robots.txt", func(res http.ResponseWriter, req *http.Request) {
		res.Write([]byte(""))
	})
	r.PathPrefix("/").Handler(http.HandlerFunc(NewMiddlewareChain(IndexHandler(FILE_INDEX),          middlewares, *a))).Methods("GET")

	port := Config.Get("general.port").Int()
	srv := &http.Server{
		Addr:    ":" + strconv.Itoa(port),
		Handler: r,
	}
	Log.Stdout("Filestash %s: starting", APP_VERSION)
	go ensureAppHasBooted(fmt.Sprintf("http://localhost:%d/about", port), fmt.Sprintf("listening on :%d", port))
	if err := srv.ListenAndServe(); err != nil {
		Log.Stdout("error: %v", err)
		return
	}
}

func initDebugRoutes(r *mux.Router) {
	r.HandleFunc("/debug/pprof/", pprof.Index)
	r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
	r.HandleFunc("/debug/pprof/profile", pprof.Profile)
	r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
	r.HandleFunc("/debug/pprof/trace", pprof.Trace)
	r.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine"))
	r.Handle("/debug/pprof/heap", pprof.Handler("heap"))
	r.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate"))
	r.Handle("/debug/pprof/block", pprof.Handler("block"))
	r.Handle("/debug/pprof/allocs", pprof.Handler("allocs"))
	r.Handle("/debug/pprof/mutex", pprof.Handler("mutex"))
	r.HandleFunc("/debug/free", func(w http.ResponseWriter, r *http.Request) {
		debug.FreeOSMemory()
		w.Write([]byte("DONE"))
	})
	bToMb := func(b uint64) string {
		return strconv.Itoa(int(b / 1024 / 1024))
	}
	r.HandleFunc("/debug/memory", func(w http.ResponseWriter, r *http.Request) {
		var m runtime.MemStats
		runtime.ReadMemStats(&m)
		w.Write([]byte("
"))
		w.Write([]byte("Alloc      = " + bToMb(m.Alloc) + "MiB
"))
		w.Write([]byte("TotalAlloc = " + bToMb(m.TotalAlloc) + "MiB
"))
		w.Write([]byte("Sys        = " + bToMb(m.Sys) + "MiB
"))
		w.Write([]byte("NumGC      = " + strconv.Itoa(int(m.NumGC))))
		w.Write([]byte("
"))
	})
}

func ensureAppHasBooted(address string, message string) {
	i := 0
	for {
		if i > 10 {
			Log.Warning("Filestash hasn't boot ?!?")
			break
		}
		time.Sleep(250 * time.Millisecond)
		res, err := http.Get(address)
		if err != nil {
			i += 1
			continue
		}
		res.Body.Close()
		if res.StatusCode != http.StatusOK {
			i += 1
			continue
		}
		Log.Stdout(message)
		break
	}
}
<commit_msg>improve (favicon): remove redirection on favicon<commit_after>package main

import (
	"fmt"
	"github.com/gorilla/mux"
	. "github.com/mickael-kerjean/filestash/server/common"
	. "github.com/mickael-kerjean/filestash/server/ctrl"
	. "github.com/mickael-kerjean/filestash/server/middleware"
	_ "github.com/mickael-kerjean/filestash/server/plugin"
	"net/http"
    "net/http/pprof"
	"os"
	"runtime"
	"runtime/debug"
	"strconv"
	"time"
)

func main() {
	app := App{}
	Init(&app)
}

func Init(a *App) {
	var middlewares []Middleware
	r := mux.NewRouter()

	if os.Getenv("DEBUG") == "true" {
		initDebugRoutes(r)
	}

	// API for Session
	session := r.PathPrefix("/api/session").Subrouter()
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart }
	session.HandleFunc("",                NewMiddlewareChain(SessionGet,          middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser }
	session.HandleFunc("",                NewMiddlewareChain(SessionAuthenticate, middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionTry }
	session.HandleFunc("",                NewMiddlewareChain(SessionLogout,       middlewares, *a)).Methods("DELETE")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax }
	session.HandleFunc("/auth/{service}", NewMiddlewareChain(SessionOAuthBackend, middlewares, *a)).Methods("GET")

	// API for admin
	middlewares = []Middleware{ ApiHeaders, SecureAjax }
	admin := r.PathPrefix("/admin/api").Subrouter()
	admin.HandleFunc("/session", NewMiddlewareChain(AdminSessionGet,            middlewares, *a)).Methods("GET")
	admin.HandleFunc("/session", NewMiddlewareChain(AdminSessionAuthenticate,   middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ ApiHeaders, AdminOnly, SecureAjax }
	admin.HandleFunc("/config",  NewMiddlewareChain(PrivateConfigHandler,       middlewares, *a)).Methods("GET")
	admin.HandleFunc("/config",  NewMiddlewareChain(PrivateConfigUpdateHandler, middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ IndexHeaders }
	admin.HandleFunc("/log",                        NewMiddlewareChain(FetchLogHandler,          middlewares, *a)).Methods("GET")
	r.PathPrefix("/admin").Handler(http.HandlerFunc(NewMiddlewareChain(IndexHandler(FILE_INDEX), middlewares, *a))).Methods("GET")

	// API for File management
	files := r.PathPrefix("/api/files").Subrouter()
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly }
	files.HandleFunc("/cat",    NewMiddlewareChain(FileCat,    middlewares, *a)).Methods("GET", "HEAD")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart, LoggedInOnly }
	files.HandleFunc("/cat",    NewMiddlewareChain(FileAccess, middlewares, *a)).Methods("OPTIONS")
	files.HandleFunc("/cat",    NewMiddlewareChain(FileSave,   middlewares, *a)).Methods("POST")
	files.HandleFunc("/ls",     NewMiddlewareChain(FileLs,     middlewares, *a)).Methods("GET")
	files.HandleFunc("/mv",     NewMiddlewareChain(FileMv,     middlewares, *a)).Methods("GET")
	files.HandleFunc("/rm",     NewMiddlewareChain(FileRm,     middlewares, *a)).Methods("GET")
	files.HandleFunc("/mkdir",  NewMiddlewareChain(FileMkdir,  middlewares, *a)).Methods("GET")
	files.HandleFunc("/touch",  NewMiddlewareChain(FileTouch,  middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ ApiHeaders, SessionStart, LoggedInOnly }
	files.HandleFunc("/search",  NewMiddlewareChain(FileSearch,  middlewares, *a)).Methods("GET")

	// API for exporter
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, RedirectSharedLoginIfNeeded, SessionStart, LoggedInOnly }
	r.PathPrefix("/api/export/{share}/{mtype0}/{mtype1}").Handler(NewMiddlewareChain(FileExport,  middlewares, *a))

	// API for Shared link
	share := r.PathPrefix("/api/share").Subrouter()
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart, LoggedInOnly }
	share.HandleFunc("",               NewMiddlewareChain(ShareList,        middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser }
	share.HandleFunc("/{share}/proof", NewMiddlewareChain(ShareVerifyProof, middlewares, *a)).Methods("POST")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, CanManageShare }
	share.HandleFunc("/{share}",       NewMiddlewareChain(ShareDelete,      middlewares, *a)).Methods("DELETE")
	middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser, CanManageShare }
	share.HandleFunc("/{share}",       NewMiddlewareChain(ShareUpsert,      middlewares, *a)).Methods("POST")

	// Webdav server / Shared Link
	middlewares = []Middleware{ IndexHeaders, SecureHeaders }
	r.HandleFunc("/s/{share}",         NewMiddlewareChain(IndexHandler(FILE_INDEX), middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ WebdavBlacklist, SessionStart }
	r.PathPrefix("/s/{share}").Handler(NewMiddlewareChain(WebdavHandler,            middlewares, *a))

	// Application Resources
	middlewares = []Middleware{ ApiHeaders }
	r.HandleFunc("/api/config",  NewMiddlewareChain(PublicConfigHandler,                             middlewares, *a)).Methods("GET")
	r.HandleFunc("/api/backend", NewMiddlewareChain(AdminBackend,                                    middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ StaticHeaders }
	r.PathPrefix("/assets").Handler(http.HandlerFunc(NewMiddlewareChain(StaticHandler(FILE_ASSETS),  middlewares, *a))).Methods("GET")
	r.HandleFunc("/favicon.ico", NewMiddlewareChain(StaticHandler(FILE_ASSETS + "/assets/logo/"),    middlewares, *a)).Methods("GET")
	middlewares = []Middleware{ IndexHeaders }
	r.HandleFunc("/about",                     NewMiddlewareChain(AboutHandler,                      middlewares, *a)).Methods("GET")
	for _, obj := range Hooks.Get.HttpEndpoint() {
		obj(r)
	}
	r.HandleFunc("/robots.txt", func(res http.ResponseWriter, req *http.Request) {
		res.Write([]byte(""))
	})
	r.PathPrefix("/").Handler(http.HandlerFunc(NewMiddlewareChain(IndexHandler(FILE_INDEX),          middlewares, *a))).Methods("GET")

	port := Config.Get("general.port").Int()
	srv := &http.Server{
		Addr:    ":" + strconv.Itoa(port),
		Handler: r,
	}
	Log.Stdout("Filestash %s: starting", APP_VERSION)
	go ensureAppHasBooted(fmt.Sprintf("http://localhost:%d/about", port), fmt.Sprintf("listening on :%d", port))
	if err := srv.ListenAndServe(); err != nil {
		Log.Stdout("error: %v", err)
		return
	}
}

func initDebugRoutes(r *mux.Router) {
	r.HandleFunc("/debug/pprof/", pprof.Index)
	r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
	r.HandleFunc("/debug/pprof/profile", pprof.Profile)
	r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
	r.HandleFunc("/debug/pprof/trace", pprof.Trace)
	r.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine"))
	r.Handle("/debug/pprof/heap", pprof.Handler("heap"))
	r.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate"))
	r.Handle("/debug/pprof/block", pprof.Handler("block"))
	r.Handle("/debug/pprof/allocs", pprof.Handler("allocs"))
	r.Handle("/debug/pprof/mutex", pprof.Handler("mutex"))
	r.HandleFunc("/debug/free", func(w http.ResponseWriter, r *http.Request) {
		debug.FreeOSMemory()
		w.Write([]byte("DONE"))
	})
	bToMb := func(b uint64) string {
		return strconv.Itoa(int(b / 1024 / 1024))
	}
	r.HandleFunc("/debug/memory", func(w http.ResponseWriter, r *http.Request) {
		var m runtime.MemStats
		runtime.ReadMemStats(&m)
		w.Write([]byte("
"))
		w.Write([]byte("Alloc      = " + bToMb(m.Alloc) + "MiB
"))
		w.Write([]byte("TotalAlloc = " + bToMb(m.TotalAlloc) + "MiB
"))
		w.Write([]byte("Sys        = " + bToMb(m.Sys) + "MiB
"))
		w.Write([]byte("NumGC      = " + strconv.Itoa(int(m.NumGC))))
		w.Write([]byte("
"))
	})
}

func ensureAppHasBooted(address string, message string) {
	i := 0
	for {
		if i > 10 {
			Log.Warning("Filestash hasn't boot ?!?")
			break
		}
		time.Sleep(250 * time.Millisecond)
		res, err := http.Get(address)
		if err != nil {
			i += 1
			continue
		}
		res.Body.Close()
		if res.StatusCode != http.StatusOK {
			i += 1
			continue
		}
		Log.Stdout(message)
		break
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"

	"github.com/ant0ine/go-json-rest/rest"

	"github.com/xa4a/roomba-api"
)

func hello(w rest.ResponseWriter, req *rest.Request) {
	w.WriteJson(&roomba_api.Status{Status: "ok"})
}

func main() {
	fmt.Println("Serving..")
	handler := roomba_api.MakeHttpHandler()
	http.ListenAndServe(":8080", &handler)
}
<commit_msg>Be more verbose when failing to start HTTP server.<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/ant0ine/go-json-rest/rest"

	"github.com/xa4a/roomba-api"
)

func hello(w rest.ResponseWriter, req *rest.Request) {
	w.WriteJson(&roomba_api.Status{Status: "ok"})
}

func main() {
	fmt.Println("Serving..")
	handler := roomba_api.MakeHttpHandler()
	err := http.ListenAndServe(":8080", &handler)
	if err != nil {
		log.Fatalf("failed starting server: %s", err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 docker-cluster authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cluster

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"strings"
	"sync"

	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/tsuru/provision/docker/fix"
)

type ImageHistory struct {
	Node    string
	ImageId string
}

type Image struct {
	Repository string `bson:"_id"`
	LastNode   string
	LastId     string
	LastDigest string
	History    []ImageHistory
}

// RemoveImageIgnoreLast works similarly to RemoveImage except it won't
// remove the last built/pulled/commited image.
func (c *Cluster) RemoveImageIgnoreLast(name string) error {
	return c.removeImage(name, true)
}

// RemoveImage removes an image from the nodes where this images exists,
// returning an error in case of failure. Will wait for the image to be
// removed on all nodes.
func (c *Cluster) RemoveImage(name string) error {
	return c.removeImage(name, false)
}

func (c *Cluster) removeImage(name string, ignoreLast bool) error {
	stor := c.storage()
	image, err := stor.RetrieveImage(name)
	if err != nil {
		return err
	}
	hosts := []string{}
	idMap := map[string][]string{}
	for _, entry := range image.History {
		_, isOld := idMap[entry.Node]
		idMap[entry.Node] = append(idMap[entry.Node], entry.ImageId)
		if !isOld {
			hosts = append(hosts, entry.Node)
		}
	}
	_, err = c.runOnNodes(func(n node) (interface{}, error) {
		imgIds, _ := idMap[n.addr]
		var lastErr error
		for _, imgId := range imgIds {
			if ignoreLast && imgId == image.LastId {
				continue
			}
			err := n.RemoveImage(imgId)
			_, isNetErr := err.(*net.OpError)
			if err == nil || err == docker.ErrNoSuchImage || isNetErr {
				err = stor.RemoveImage(name, imgId, n.addr)
				if err != nil {
					lastErr = err
				}
			} else {
				lastErr = err
			}
		}
		return nil, lastErr
	}, docker.ErrNoSuchImage, true, hosts...)
	return err
}

func parseImageRegistry(imageId string) (string, string) {
	parts := strings.SplitN(imageId, "/", 3)
	if len(parts) < 3 {
		return "", strings.Join(parts, "/")
	}
	return parts[0], strings.Join(parts[1:], "/")
}

func (c *Cluster) RemoveFromRegistry(imageId string) error {
	registryServer, imageTag := parseImageRegistry(imageId)
	if registryServer == "" {
		return nil
	}
	url := fmt.Sprintf("http://%s/v1/repositories/%s/", registryServer, imageTag)
	resp, err := deleteImage(url)
	if err != nil {
		return err
	}
	if resp.StatusCode == 404 {
		var imageTagName string
		imageData := strings.SplitN(imageTag, ":", 2)
		imageTagName = imageData[0]
		img, err := c.storage().RetrieveImage(imageId)
		if err != nil && img.LastDigest == "" {
			return err
		}
		url := fmt.Sprintf("http://%s/v2/%s/manifests/%s", registryServer, imageTagName, img.LastDigest)
		_, err = deleteImage(url)
		return err
	}
	return nil
}

func deleteImage(url string) (*http.Response, error) {
	request, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return nil, err
	}
	request.Close = true
	rsp, err := timeout10Client.Do(request)
	if err == nil {
		rsp.Body.Close()
	}
	return rsp, err
}

// PullImage pulls an image from a remote registry server, returning an error
// in case of failure.
//
// It will pull all images in parallel, so users need to make sure that the
// given buffer is safe.
func (c *Cluster) PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration, nodes ...string) error {
	_, err := c.runOnNodes(func(n node) (interface{}, error) {
		key := imageKey(opts.Repository, opts.Tag)
		n.setPersistentClient()
		var w bytes.Buffer
		if opts.OutputStream != nil {
			mw := io.MultiWriter(&w, opts.OutputStream)
			opts.OutputStream = mw
		} else {
			opts.OutputStream = &w
		}
		err := n.PullImage(opts, auth)
		if err != nil {
			return nil, err
		}
		img, err := n.InspectImage(key)
		if err != nil {
			return nil, err
		}
		err = c.storage().StoreImage(key, img.ID, n.addr)
		if err != nil {
			return nil, err
		}
		digest, _ := fix.GetImageDigest(w.String())
		return nil, c.storage().SetImageDigest(key, digest)
	}, docker.ErrNoSuchImage, true, nodes...)
	return err
}

// TagImage adds a tag to the given image, returning an error in case of
// failure.
func (c *Cluster) TagImage(name string, opts docker.TagImageOptions) error {
	img, err := c.storage().RetrieveImage(name)
	if err != nil {
		return err
	}
	node, err := c.getNodeByAddr(img.LastNode)
	if err != nil {
		return err
	}
	err = node.TagImage(name, opts)
	if err != nil {
		return wrapError(node, err)
	}
	key := imageKey(opts.Repo, opts.Tag)
	return c.storage().StoreImage(key, img.LastId, node.addr)
}

// PushImage pushes an image to a remote registry server, returning an error in
// case of failure.
func (c *Cluster) PushImage(opts docker.PushImageOptions, auth docker.AuthConfiguration) error {
	key := imageKey(opts.Name, opts.Tag)
	img, err := c.storage().RetrieveImage(key)
	if err != nil {
		return err
	}
	node, err := c.getNodeByAddr(img.LastNode)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	return wrapError(node, node.PushImage(opts, auth))
}

// InspectContainer inspects an image based on its repo name
func (c *Cluster) InspectImage(repo string) (*docker.Image, error) {
	img, err := c.storage().RetrieveImage(repo)
	if err != nil {
		return nil, err
	}
	node, err := c.getNodeByAddr(img.LastNode)
	if err != nil {
		return nil, err
	}
	dockerImg, err := node.InspectImage(repo)
	return dockerImg, wrapError(node, err)
}

// ListImages lists images existing in each cluster node
func (c *Cluster) ListImages(opts docker.ListImagesOptions) ([]docker.APIImages, error) {
	nodes, err := c.UnfilteredNodes()
	if err != nil {
		return nil, err
	}
	resultChan := make(chan []docker.APIImages, len(nodes))
	errChan := make(chan error, len(nodes))
	var wg sync.WaitGroup
	for _, node := range nodes {
		wg.Add(1)
		go func(addr string) {
			defer wg.Done()
			client, err := c.getNodeByAddr(addr)
			if err != nil {
				errChan <- err
			}
			nodeImages, err := client.ListImages(opts)
			if err != nil {
				errChan <- wrapError(client, err)
			}
			resultChan <- nodeImages
		}(node.Address)
	}
	wg.Wait()
	close(resultChan)
	close(errChan)
	var allImages []docker.APIImages
	for images := range resultChan {
		allImages = append(allImages, images...)
	}
	select {
	case err := <-errChan:
		return allImages, err
	default:
	}
	return allImages, nil
}

// ImportImage imports an image from a url or stdin
func (c *Cluster) ImportImage(opts docker.ImportImageOptions) error {
	_, err := c.runOnNodes(func(n node) (interface{}, error) {
		return nil, n.ImportImage(opts)
	}, docker.ErrNoSuchImage, false)
	return err
}

//BuildImage build an image and pushes it to registry
func (c *Cluster) BuildImage(buildOptions docker.BuildImageOptions) error {
	nodes, err := c.Nodes()
	if err != nil {
		return err
	}
	if len(nodes) < 1 {
		return errors.New("There is no docker node. Please list one in tsuru.conf or add one with `tsuru docker-node-add`.")
	}
	nodeAddress := nodes[0].Address
	node, err := c.getNodeByAddr(nodeAddress)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	err = node.BuildImage(buildOptions)
	if err != nil {
		return wrapError(node, err)
	}
	img, err := node.InspectImage(buildOptions.Name)
	if err != nil {
		return wrapError(node, err)
	}
	return c.storage().StoreImage(buildOptions.Name, img.ID, nodeAddress)
}

func imageKey(repo, tag string) string {
	key := repo
	if key != "" && tag != "" {
		key = fmt.Sprintf("%s:%s", key, tag)
	}
	return key
}
<commit_msg>cluster/image: fix race condition on writing to output in PullImage. Related to tsuru/tsuru#1361<commit_after>// Copyright 2016 docker-cluster authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cluster

import (
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"strings"
	"sync"

	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/tsuru/provision/docker/fix"
	"github.com/tsuru/tsuru/safe"
)

type ImageHistory struct {
	Node    string
	ImageId string
}

type Image struct {
	Repository string `bson:"_id"`
	LastNode   string
	LastId     string
	LastDigest string
	History    []ImageHistory
}

// RemoveImageIgnoreLast works similarly to RemoveImage except it won't
// remove the last built/pulled/commited image.
func (c *Cluster) RemoveImageIgnoreLast(name string) error {
	return c.removeImage(name, true)
}

// RemoveImage removes an image from the nodes where this images exists,
// returning an error in case of failure. Will wait for the image to be
// removed on all nodes.
func (c *Cluster) RemoveImage(name string) error {
	return c.removeImage(name, false)
}

func (c *Cluster) removeImage(name string, ignoreLast bool) error {
	stor := c.storage()
	image, err := stor.RetrieveImage(name)
	if err != nil {
		return err
	}
	hosts := []string{}
	idMap := map[string][]string{}
	for _, entry := range image.History {
		_, isOld := idMap[entry.Node]
		idMap[entry.Node] = append(idMap[entry.Node], entry.ImageId)
		if !isOld {
			hosts = append(hosts, entry.Node)
		}
	}
	_, err = c.runOnNodes(func(n node) (interface{}, error) {
		imgIds, _ := idMap[n.addr]
		var lastErr error
		for _, imgId := range imgIds {
			if ignoreLast && imgId == image.LastId {
				continue
			}
			err := n.RemoveImage(imgId)
			_, isNetErr := err.(*net.OpError)
			if err == nil || err == docker.ErrNoSuchImage || isNetErr {
				err = stor.RemoveImage(name, imgId, n.addr)
				if err != nil {
					lastErr = err
				}
			} else {
				lastErr = err
			}
		}
		return nil, lastErr
	}, docker.ErrNoSuchImage, true, hosts...)
	return err
}

func parseImageRegistry(imageId string) (string, string) {
	parts := strings.SplitN(imageId, "/", 3)
	if len(parts) < 3 {
		return "", strings.Join(parts, "/")
	}
	return parts[0], strings.Join(parts[1:], "/")
}

func (c *Cluster) RemoveFromRegistry(imageId string) error {
	registryServer, imageTag := parseImageRegistry(imageId)
	if registryServer == "" {
		return nil
	}
	url := fmt.Sprintf("http://%s/v1/repositories/%s/", registryServer, imageTag)
	resp, err := deleteImage(url)
	if err != nil {
		return err
	}
	if resp.StatusCode == 404 {
		var imageTagName string
		imageData := strings.SplitN(imageTag, ":", 2)
		imageTagName = imageData[0]
		img, err := c.storage().RetrieveImage(imageId)
		if err != nil && img.LastDigest == "" {
			return err
		}
		url := fmt.Sprintf("http://%s/v2/%s/manifests/%s", registryServer, imageTagName, img.LastDigest)
		_, err = deleteImage(url)
		return err
	}
	return nil
}

func deleteImage(url string) (*http.Response, error) {
	request, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return nil, err
	}
	request.Close = true
	rsp, err := timeout10Client.Do(request)
	if err == nil {
		rsp.Body.Close()
	}
	return rsp, err
}

// PullImage pulls an image from a remote registry server, returning an error
// in case of failure.
//
// It will pull all images in parallel, so users need to make sure that the
// given buffer is safe.
func (c *Cluster) PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration, nodes ...string) error {
	var w safe.Buffer
	if opts.OutputStream != nil {
		mw := io.MultiWriter(&w, opts.OutputStream)
		opts.OutputStream = mw
	} else {
		opts.OutputStream = &w
	}
	key := imageKey(opts.Repository, opts.Tag)
	_, err := c.runOnNodes(func(n node) (interface{}, error) {
		n.setPersistentClient()
		err := n.PullImage(opts, auth)
		if err != nil {
			return nil, err
		}
		img, err := n.InspectImage(key)
		if err != nil {
			return nil, err
		}
		return nil, c.storage().StoreImage(key, img.ID, n.addr)
	}, docker.ErrNoSuchImage, true, nodes...)
	if err != nil {
		return err
	}
	digest, _ := fix.GetImageDigest(w.String())
	return c.storage().SetImageDigest(key, digest)
}

// TagImage adds a tag to the given image, returning an error in case of
// failure.
func (c *Cluster) TagImage(name string, opts docker.TagImageOptions) error {
	img, err := c.storage().RetrieveImage(name)
	if err != nil {
		return err
	}
	node, err := c.getNodeByAddr(img.LastNode)
	if err != nil {
		return err
	}
	err = node.TagImage(name, opts)
	if err != nil {
		return wrapError(node, err)
	}
	key := imageKey(opts.Repo, opts.Tag)
	return c.storage().StoreImage(key, img.LastId, node.addr)
}

// PushImage pushes an image to a remote registry server, returning an error in
// case of failure.
func (c *Cluster) PushImage(opts docker.PushImageOptions, auth docker.AuthConfiguration) error {
	key := imageKey(opts.Name, opts.Tag)
	img, err := c.storage().RetrieveImage(key)
	if err != nil {
		return err
	}
	node, err := c.getNodeByAddr(img.LastNode)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	return wrapError(node, node.PushImage(opts, auth))
}

// InspectContainer inspects an image based on its repo name
func (c *Cluster) InspectImage(repo string) (*docker.Image, error) {
	img, err := c.storage().RetrieveImage(repo)
	if err != nil {
		return nil, err
	}
	node, err := c.getNodeByAddr(img.LastNode)
	if err != nil {
		return nil, err
	}
	dockerImg, err := node.InspectImage(repo)
	return dockerImg, wrapError(node, err)
}

// ListImages lists images existing in each cluster node
func (c *Cluster) ListImages(opts docker.ListImagesOptions) ([]docker.APIImages, error) {
	nodes, err := c.UnfilteredNodes()
	if err != nil {
		return nil, err
	}
	resultChan := make(chan []docker.APIImages, len(nodes))
	errChan := make(chan error, len(nodes))
	var wg sync.WaitGroup
	for _, node := range nodes {
		wg.Add(1)
		go func(addr string) {
			defer wg.Done()
			client, err := c.getNodeByAddr(addr)
			if err != nil {
				errChan <- err
			}
			nodeImages, err := client.ListImages(opts)
			if err != nil {
				errChan <- wrapError(client, err)
			}
			resultChan <- nodeImages
		}(node.Address)
	}
	wg.Wait()
	close(resultChan)
	close(errChan)
	var allImages []docker.APIImages
	for images := range resultChan {
		allImages = append(allImages, images...)
	}
	select {
	case err := <-errChan:
		return allImages, err
	default:
	}
	return allImages, nil
}

// ImportImage imports an image from a url or stdin
func (c *Cluster) ImportImage(opts docker.ImportImageOptions) error {
	_, err := c.runOnNodes(func(n node) (interface{}, error) {
		return nil, n.ImportImage(opts)
	}, docker.ErrNoSuchImage, false)
	return err
}

//BuildImage build an image and pushes it to registry
func (c *Cluster) BuildImage(buildOptions docker.BuildImageOptions) error {
	nodes, err := c.Nodes()
	if err != nil {
		return err
	}
	if len(nodes) < 1 {
		return errors.New("There is no docker node. Please list one in tsuru.conf or add one with `tsuru docker-node-add`.")
	}
	nodeAddress := nodes[0].Address
	node, err := c.getNodeByAddr(nodeAddress)
	if err != nil {
		return err
	}
	node.setPersistentClient()
	err = node.BuildImage(buildOptions)
	if err != nil {
		return wrapError(node, err)
	}
	img, err := node.InspectImage(buildOptions.Name)
	if err != nil {
		return wrapError(node, err)
	}
	return c.storage().StoreImage(buildOptions.Name, img.ID, nodeAddress)
}

func imageKey(repo, tag string) string {
	key := repo
	if key != "" && tag != "" {
		key = fmt.Sprintf("%s:%s", key, tag)
	}
	return key
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/skygeario/skygear-server/pkg/auth"
	authTemplate "github.com/skygeario/skygear-server/pkg/auth/template"
	"github.com/skygeario/skygear-server/pkg/core/async"
	"github.com/skygeario/skygear-server/pkg/core/auth/authn/resolver"
	"github.com/skygeario/skygear-server/pkg/core/template"

	"github.com/kelseyhightower/envconfig"

	"github.com/joho/godotenv"
	"github.com/skygeario/skygear-server/pkg/auth/handler"
	forgotpwdhandler "github.com/skygeario/skygear-server/pkg/auth/handler/forgotpwd"
	ssohandler "github.com/skygeario/skygear-server/pkg/auth/handler/sso"
	userverifyhandler "github.com/skygeario/skygear-server/pkg/auth/handler/userverify"
	"github.com/skygeario/skygear-server/pkg/auth/task"
	"github.com/skygeario/skygear-server/pkg/core/config"
	"github.com/skygeario/skygear-server/pkg/core/logging"
	"github.com/skygeario/skygear-server/pkg/core/middleware"
	"github.com/skygeario/skygear-server/pkg/core/server"
)

type configuration struct {
	Standalone                        bool
	StandaloneTenantConfigurationFile string `envconfig:"STANDALONE_TENANT_CONFIG_FILE" default:"standalone-tenant-config.yaml"`
	PathPrefix                        string `envconfig:"PATH_PREFIX"`
	Host                              string `default:"localhost:3000"`
}

/*
	@API Auth Gear
	@Version 1.0.0
	@Server {base_url}/_auth
		Auth Gear URL
		@Variable base_url https://my_app.skygearapis.com
			Skygear App URL

	@SecuritySchemeAPIKey access_key header X-Skygear-API-Key
		Access key used by client app
	@SecuritySchemeAPIKey master_key header X-Skygear-API-Key
		Master key used by admins, can perform administrative operations.
		Can be used as access key as well.
	@SecuritySchemeHTTP access_token Bearer JWT
		Access token of user
	@SecurityRequirement access_key

	@Tag User
		User information
	@Tag User Verification
		Login IDs verification
	@Tag Forgot Password
		Password recovery process
	@Tag Administration
		Administrative operation
	@Tag SSO
		Single sign-on
*/
func main() {
	envErr := godotenv.Load()
	if envErr != nil {
		log.Print("Error in loading .env file")
	}

	configuration := configuration{}
	envconfig.Process("", &configuration)

	// default template initialization
	templateEngine := template.NewEngine()
	authTemplate.RegisterDefaultTemplates(templateEngine)

	// logging initialization
	logging.SetModule("auth")

	asyncTaskExecutor := async.NewExecutor()
	authDependency := auth.DependencyMap{
		AsyncTaskExecutor: asyncTaskExecutor,
		TemplateEngine:    templateEngine,
	}

	task.AttachVerifyCodeSendTask(asyncTaskExecutor, authDependency)
	task.AttachPwHousekeeperTask(asyncTaskExecutor, authDependency)
	task.AttachWelcomeEmailSendTask(asyncTaskExecutor, authDependency)

	authContextResolverFactory := resolver.AuthContextResolverFactory{}

	var srv server.Server
	if configuration.Standalone {
		filename := configuration.StandaloneTenantConfigurationFile
		tenantConfig, err := config.NewTenantConfigurationFromYAMLAndEnv(func() (io.Reader, error) {
			return os.Open(filename)
		})
		if err != nil {
			log.Fatal(err)
		}

		serverOption := server.DefaultOption()
		serverOption.GearPathPrefix = configuration.PathPrefix
		srv = server.NewServerWithOption(configuration.Host, authContextResolverFactory, serverOption)
		srv.Use(middleware.TenantConfigurationMiddleware{
			ConfigurationProvider: middleware.ConfigurationProviderFunc(func(_ *http.Request) (config.TenantConfiguration, error) {
				return *tenantConfig, nil
			}),
		}.Handle)
		srv.Use(middleware.RequestIDMiddleware{}.Handle)
		srv.Use(middleware.CORSMiddleware{}.Handle)
	} else {
		srv = server.NewServer(configuration.Host, authContextResolverFactory)
	}

	handler.AttachSignupHandler(&srv, authDependency)
	handler.AttachLoginHandler(&srv, authDependency)
	handler.AttachLogoutHandler(&srv, authDependency)
	handler.AttachMeHandler(&srv, authDependency)
	handler.AttachSetDisableHandler(&srv, authDependency)
	handler.AttachChangePasswordHandler(&srv, authDependency)
	handler.AttachResetPasswordHandler(&srv, authDependency)
	handler.AttachWelcomeEmailHandler(&srv, authDependency)
	handler.AttachUpdateMetadataHandler(&srv, authDependency)
	forgotpwdhandler.AttachForgotPasswordHandler(&srv, authDependency)
	forgotpwdhandler.AttachForgotPasswordResetHandler(&srv, authDependency)
	userverifyhandler.AttachVerifyRequestHandler(&srv, authDependency)
	userverifyhandler.AttachVerifyCodeHandler(&srv, authDependency)
	ssohandler.AttachAuthURLHandler(&srv, authDependency)
	ssohandler.AttachConfigHandler(&srv, authDependency)
	ssohandler.AttachIFrameHandlerFactory(&srv, authDependency)
	ssohandler.AttachCustomTokenLoginHandler(&srv, authDependency)
	ssohandler.AttachAuthHandler(&srv, authDependency)
	ssohandler.AttachLoginHandler(&srv, authDependency)
	ssohandler.AttachLinkHandler(&srv, authDependency)
	ssohandler.AttachUnlinkHandler(&srv, authDependency)

	go func() {
		log.Printf("Auth gear boot")
		if err := srv.ListenAndServe(); err != nil {
			log.Println(err)
		}
	}()

	sig := make(chan os.Signal, 1)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)

	// wait interrupt signal
	select {
	case <-sig:
		log.Printf("Stoping http server ...\n")
	}

	// create shutdown context with 10 second timeout
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// shutdown the server
	err := srv.Shutdown(ctx)
	if err != nil {
		log.Printf("Shutdown request error: %v\n", err)
	}
}
<commit_msg>Print the full json schema validation error if possible<commit_after>package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/joho/godotenv"
	"github.com/kelseyhightower/envconfig"

	"github.com/skygeario/skygear-server/pkg/auth"
	authTemplate "github.com/skygeario/skygear-server/pkg/auth/template"
	"github.com/skygeario/skygear-server/pkg/core/async"
	"github.com/skygeario/skygear-server/pkg/core/auth/authn/resolver"
	"github.com/skygeario/skygear-server/pkg/core/template"

	"github.com/skygeario/skygear-server/pkg/auth/handler"
	forgotpwdhandler "github.com/skygeario/skygear-server/pkg/auth/handler/forgotpwd"
	ssohandler "github.com/skygeario/skygear-server/pkg/auth/handler/sso"
	userverifyhandler "github.com/skygeario/skygear-server/pkg/auth/handler/userverify"
	"github.com/skygeario/skygear-server/pkg/auth/task"
	"github.com/skygeario/skygear-server/pkg/core/config"
	"github.com/skygeario/skygear-server/pkg/core/logging"
	"github.com/skygeario/skygear-server/pkg/core/middleware"
	"github.com/skygeario/skygear-server/pkg/core/server"
	"github.com/skygeario/skygear-server/pkg/core/skyerr"
)

type configuration struct {
	Standalone                        bool
	StandaloneTenantConfigurationFile string `envconfig:"STANDALONE_TENANT_CONFIG_FILE" default:"standalone-tenant-config.yaml"`
	PathPrefix                        string `envconfig:"PATH_PREFIX"`
	Host                              string `default:"localhost:3000"`
}

/*
	@API Auth Gear
	@Version 1.0.0
	@Server {base_url}/_auth
		Auth Gear URL
		@Variable base_url https://my_app.skygearapis.com
			Skygear App URL

	@SecuritySchemeAPIKey access_key header X-Skygear-API-Key
		Access key used by client app
	@SecuritySchemeAPIKey master_key header X-Skygear-API-Key
		Master key used by admins, can perform administrative operations.
		Can be used as access key as well.
	@SecuritySchemeHTTP access_token Bearer JWT
		Access token of user
	@SecurityRequirement access_key

	@Tag User
		User information
	@Tag User Verification
		Login IDs verification
	@Tag Forgot Password
		Password recovery process
	@Tag Administration
		Administrative operation
	@Tag SSO
		Single sign-on
*/
func main() {
	envErr := godotenv.Load()
	if envErr != nil {
		log.Print("Error in loading .env file")
	}

	configuration := configuration{}
	envconfig.Process("", &configuration)

	// default template initialization
	templateEngine := template.NewEngine()
	authTemplate.RegisterDefaultTemplates(templateEngine)

	// logging initialization
	logging.SetModule("auth")

	asyncTaskExecutor := async.NewExecutor()
	authDependency := auth.DependencyMap{
		AsyncTaskExecutor: asyncTaskExecutor,
		TemplateEngine:    templateEngine,
	}

	task.AttachVerifyCodeSendTask(asyncTaskExecutor, authDependency)
	task.AttachPwHousekeeperTask(asyncTaskExecutor, authDependency)
	task.AttachWelcomeEmailSendTask(asyncTaskExecutor, authDependency)

	authContextResolverFactory := resolver.AuthContextResolverFactory{}

	var srv server.Server
	if configuration.Standalone {
		filename := configuration.StandaloneTenantConfigurationFile
		tenantConfig, err := config.NewTenantConfigurationFromYAMLAndEnv(func() (io.Reader, error) {
			return os.Open(filename)
		})
		if err != nil {
			if skyError, ok := err.(skyerr.Error); ok {
				info := skyError.Info()
				if arguments, ok := info["arguments"].([]string); ok {
					for _, a := range arguments {
						fmt.Fprintf(os.Stderr, "%v\n", a)
					}
				}
			}
			log.Fatal(err)
		}

		serverOption := server.DefaultOption()
		serverOption.GearPathPrefix = configuration.PathPrefix
		srv = server.NewServerWithOption(configuration.Host, authContextResolverFactory, serverOption)
		srv.Use(middleware.TenantConfigurationMiddleware{
			ConfigurationProvider: middleware.ConfigurationProviderFunc(func(_ *http.Request) (config.TenantConfiguration, error) {
				return *tenantConfig, nil
			}),
		}.Handle)
		srv.Use(middleware.RequestIDMiddleware{}.Handle)
		srv.Use(middleware.CORSMiddleware{}.Handle)
	} else {
		srv = server.NewServer(configuration.Host, authContextResolverFactory)
	}

	handler.AttachSignupHandler(&srv, authDependency)
	handler.AttachLoginHandler(&srv, authDependency)
	handler.AttachLogoutHandler(&srv, authDependency)
	handler.AttachMeHandler(&srv, authDependency)
	handler.AttachSetDisableHandler(&srv, authDependency)
	handler.AttachChangePasswordHandler(&srv, authDependency)
	handler.AttachResetPasswordHandler(&srv, authDependency)
	handler.AttachWelcomeEmailHandler(&srv, authDependency)
	handler.AttachUpdateMetadataHandler(&srv, authDependency)
	forgotpwdhandler.AttachForgotPasswordHandler(&srv, authDependency)
	forgotpwdhandler.AttachForgotPasswordResetHandler(&srv, authDependency)
	userverifyhandler.AttachVerifyRequestHandler(&srv, authDependency)
	userverifyhandler.AttachVerifyCodeHandler(&srv, authDependency)
	ssohandler.AttachAuthURLHandler(&srv, authDependency)
	ssohandler.AttachConfigHandler(&srv, authDependency)
	ssohandler.AttachIFrameHandlerFactory(&srv, authDependency)
	ssohandler.AttachCustomTokenLoginHandler(&srv, authDependency)
	ssohandler.AttachAuthHandler(&srv, authDependency)
	ssohandler.AttachLoginHandler(&srv, authDependency)
	ssohandler.AttachLinkHandler(&srv, authDependency)
	ssohandler.AttachUnlinkHandler(&srv, authDependency)

	go func() {
		log.Printf("Auth gear boot")
		if err := srv.ListenAndServe(); err != nil {
			log.Println(err)
		}
	}()

	sig := make(chan os.Signal, 1)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)

	// wait interrupt signal
	select {
	case <-sig:
		log.Printf("Stoping http server ...\n")
	}

	// create shutdown context with 10 second timeout
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// shutdown the server
	err := srv.Shutdown(ctx)
	if err != nil {
		log.Printf("Shutdown request error: %v\n", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/rpc"
	"strings"
	"sync"
	"time"

	"github.com/ianremmler/bort"
	"github.com/sorcix/bot"
	"github.com/sorcix/irc"
	"github.com/sorcix/irc/ctcp"
)

var (
	// flags
	flags   Config
	cfgFile string

	mut    sync.Mutex
	isLive bool
	botc   *bot.Client
	rpcc   *rpc.Client
)

// configuration, initialized to defaults
var cfg = Config{
	Nick:       "bort",
	Server:     "irc.freenode.net:6667",
	Channel:    "#bort",
	Address:    bort.DefaultAddress,
	CmdPrefix:  "bort:",
	PollPeriod: 5,
}

// Config holds the configurable values for the program.
type Config struct {
	Nick       string
	Server     string
	Channel    string
	Address    string
	CmdPrefix  string
	PollPeriod uint
}

func main() {
	flag.Parse()
	config()
	if len(cfg.Channel) < 2 || !strings.HasPrefix(cfg.Channel, "#") {
		log.Fatalf("'%s' is not a valid channel", cfg.Channel)
	}
	if cfg.PollPeriod < 1 {
		cfg.PollPeriod = 1
	}
	go pollPushes()
	for {
		run()
	}
}

// run starts the bot
func run() {
	con, err := irc.Dial(cfg.Server)
	if err != nil {
		log.Println(err)
		time.Sleep(time.Second)
		return
	}

	if botc = bot.NewClient(con, handleMessage); botc == nil {
		return
	}
	botc.Identify(cfg.Nick, cfg.Nick, cfg.Nick)
	botc.Wait()

	mut.Lock()
	isLive = false
	mut.Unlock()
}

// setup looks for a welcome response, joins the channel, and connects to bortplug.
func setup(msg *irc.Message, snd irc.Sender) {
	switch msg.Command {
	case irc.RPL_WELCOME:
		log.Printf("connected to IRC server %s (%s)\n", cfg.Server, msg.Name)
		out := &irc.Message{Command: irc.JOIN, Params: []string{cfg.Channel}}
		if err := snd.Send(out); err != nil {
			log.Println(err)
		}
	case irc.JOIN:
		if msg.Name != cfg.Nick {
			break
		}
		if len(msg.Params) > 0 {
			log.Printf("joined %s as %s\n", msg.Params[0], msg.Name)
		}
		isLive = true
	}
}

// handleMessage processes incoming IRC messages.
func handleMessage(msg *irc.Message, snd irc.Sender) {
	mut.Lock()
	defer mut.Unlock()

	if !isLive {
		setup(msg, snd)
		return
	}
	if connectPlug() != nil {
		return
	}

	in := convertMsg(msg)
	msgs := []bort.Message{}
	if err := rpcc.Call("Plugin.Process", in, &msgs); err != nil {
		handleRPCError(err)
		return
	}
	sendMessages(msgs)
}

// deliverPushes periodically fetches and handles messages pushed by plugins.
func deliverPushes() {
	mut.Lock()
	defer mut.Unlock()

	if !isLive || connectPlug() != nil {
		return
	}

	msgs := []bort.Message{}
	if err := rpcc.Call("Plugin.Pull", struct{}{}, &msgs); err != nil {
		handleRPCError(err)
		return
	}
	sendMessages(msgs)
}

// handleRPCError handles errors from RPC calls.
func handleRPCError(err error) {
	switch err {
	case nil:
	case rpc.ErrShutdown, io.EOF, io.ErrUnexpectedEOF:
		log.Println("disconnected from bortplug")
		rpcc.Close()
		rpcc = nil
		connectPlug()
	default:
		log.Println(err)
	}
}

// sendMessages sends a slice of messages to the server.
func sendMessages(msgs []bort.Message) {
	for i := range msgs {
		if msgs[i].Context == "" {
			msgs[i].Context = cfg.Channel
		}
		if err := send(botc, &msgs[i]); err != nil {
			log.Println(err)
		}
	}
}

// pollPushes periodically delivers pending push messages.
func pollPushes() {
	t := time.Tick(time.Duration(cfg.PollPeriod) * time.Second)
	for {
		<-t
		deliverPushes()
	}
}

// send sends an IRC message to the server according to its content.
func send(snd irc.Sender, in *bort.Message) error {
	base := irc.Message{Command: irc.PRIVMSG, Params: []string{in.Context}}
	switch in.Type {
	case bort.None:
	case bort.PrivMsg:
		text := strings.TrimRight(in.Text, "\n")
		for _, str := range strings.Split(text, "\n") {
			out := base
			out.Trailing = str
			snd.Send(&out)
		}
	case bort.Action:
		text := strings.SplitN(in.Text+"\n", "\n", 2)[0]
		out := base
		out.Trailing = ctcp.Action(text)
		snd.Send(&out)
	default:
		return fmt.Errorf("unknown message type: %d", in.Type)
	}
	return nil
}

// convertMsg converts an irc.Message to a bort.Message.
func convertMsg(imsg *irc.Message) *bort.Message {
	bmsg := &bort.Message{
		Context: cfg.Channel,
		IRCCmd:  imsg.Command,
		Nick:    imsg.Name,
		User:    imsg.User,
		Host:    imsg.Host,
		Params:  append([]string(nil), imsg.Params...),
		Text:    imsg.Trailing,
	}
	if len(bmsg.Params) > 0 && bmsg.Params[0] != cfg.Channel {
		bmsg.Context = bmsg.Nick
	}
	switch bmsg.IRCCmd {
	case irc.PRIVMSG:
		// handle actions
		if tag, text, ok := ctcp.Decode(bmsg.Text); ok && tag == ctcp.ACTION {
			bmsg.Type = bort.Action
			bmsg.Text = text
			break
		}

		bmsg.Type = bort.PrivMsg
		isCmd := (bmsg.Context != cfg.Channel)
		text := strings.TrimSpace(bmsg.Text)
		if strings.HasPrefix(text, cfg.CmdPrefix) {
			text = strings.TrimLeft(text[len(cfg.CmdPrefix):], " ")
			isCmd = true
		}
		if isCmd {
			cmdAndArgs := strings.SplitN(text+" ", " ", 2)
			if len(cmdAndArgs) == 2 {
				bmsg.Command = cmdAndArgs[0]
				bmsg.Args = strings.TrimSpace(cmdAndArgs[1])
			}
		}
	case irc.JOIN:
		bmsg.Type = bort.Join
		bmsg.Text = bmsg.Nick
	case irc.PART:
		bmsg.Type = bort.Part
		bmsg.Text = bmsg.Nick
	}
	return bmsg
}

// connectPlug connects to bortplug's RPC socket.
func connectPlug() error {
	if rpcc != nil {
		return nil
	}

	var err error
	rpcc, err = rpc.Dial("tcp", cfg.Address)
	if err == nil {
		log.Printf("connected to bortplug (%s)\n", cfg.Address)
	}
	return err
}

// config overrides defaults with config file and flag values.
func config() {
	if err := bort.LoadConfig(&cfg, cfgFile); err != nil {
		log.Println(err)
	}
	flag.Visit(func(f *flag.Flag) {
		switch f.Name {
		case "n":
			cfg.Nick = flags.Nick
		case "s":
			cfg.Server = flags.Server
		case "c":
			cfg.Channel = flags.Channel
		case "a":
			cfg.Address = flags.Address
		case "p":
			cfg.CmdPrefix = flags.CmdPrefix
		case "t":
			cfg.PollPeriod = flags.PollPeriod
		}
	})
}

func init() {
	flag.StringVar(&flags.Nick, "n", cfg.Nick, "nick of the bot")
	flag.StringVar(&flags.Server, "s", cfg.Server, "IRC server")
	flag.StringVar(&flags.Channel, "c", cfg.Channel, "channel")
	flag.StringVar(&flags.Address, "a", cfg.Address, "bortplug address")
	flag.StringVar(&flags.CmdPrefix, "p", cfg.CmdPrefix, "command prefix")
	flag.UintVar(&flags.PollPeriod, "t", cfg.PollPeriod, "plugin push message poll period in seconds")
	flag.StringVar(&cfgFile, "f", "", "configuration file")
}
<commit_msg>Check incoming message for nil pointers.<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/rpc"
	"strings"
	"sync"
	"time"

	"github.com/ianremmler/bort"
	"github.com/sorcix/bot"
	"github.com/sorcix/irc"
	"github.com/sorcix/irc/ctcp"
)

var (
	// flags
	flags   Config
	cfgFile string

	mut    sync.Mutex
	isLive bool
	botc   *bot.Client
	rpcc   *rpc.Client
)

// configuration, initialized to defaults
var cfg = Config{
	Nick:       "bort",
	Server:     "irc.freenode.net:6667",
	Channel:    "#bort",
	Address:    bort.DefaultAddress,
	CmdPrefix:  "bort:",
	PollPeriod: 5,
}

// Config holds the configurable values for the program.
type Config struct {
	Nick       string
	Server     string
	Channel    string
	Address    string
	CmdPrefix  string
	PollPeriod uint
}

func main() {
	flag.Parse()
	config()
	if len(cfg.Channel) < 2 || !strings.HasPrefix(cfg.Channel, "#") {
		log.Fatalf("'%s' is not a valid channel", cfg.Channel)
	}
	if cfg.PollPeriod < 1 {
		cfg.PollPeriod = 1
	}
	go pollPushes()
	for {
		run()
	}
}

// run starts the bot
func run() {
	con, err := irc.Dial(cfg.Server)
	if err != nil {
		log.Println(err)
		time.Sleep(time.Second)
		return
	}

	if botc = bot.NewClient(con, handleMessage); botc == nil {
		return
	}
	botc.Identify(cfg.Nick, cfg.Nick, cfg.Nick)
	botc.Wait()

	mut.Lock()
	isLive = false
	mut.Unlock()
}

// setup looks for a welcome response, joins the channel, and connects to bortplug.
func setup(msg *irc.Message, snd irc.Sender) {
	switch msg.Command {
	case irc.RPL_WELCOME:
		log.Printf("connected to IRC server %s (%s)\n", cfg.Server, msg.Name)
		out := &irc.Message{Command: irc.JOIN, Params: []string{cfg.Channel}}
		if err := snd.Send(out); err != nil {
			log.Println(err)
		}
	case irc.JOIN:
		if msg.Name != cfg.Nick {
			break
		}
		if len(msg.Params) > 0 {
			log.Printf("joined %s as %s\n", msg.Params[0], msg.Name)
		}
		isLive = true
	}
}

// handleMessage processes incoming IRC messages.
func handleMessage(msg *irc.Message, snd irc.Sender) {
	if msg == nil || msg.Prefix == nil {
		return
	}

	mut.Lock()
	defer mut.Unlock()

	if !isLive {
		setup(msg, snd)
		return
	}
	if connectPlug() != nil {
		return
	}

	in := convertMsg(msg)
	msgs := []bort.Message{}
	if err := rpcc.Call("Plugin.Process", in, &msgs); err != nil {
		handleRPCError(err)
		return
	}
	sendMessages(msgs)
}

// deliverPushes periodically fetches and handles messages pushed by plugins.
func deliverPushes() {
	mut.Lock()
	defer mut.Unlock()

	if !isLive || connectPlug() != nil {
		return
	}

	msgs := []bort.Message{}
	if err := rpcc.Call("Plugin.Pull", struct{}{}, &msgs); err != nil {
		handleRPCError(err)
		return
	}
	sendMessages(msgs)
}

// handleRPCError handles errors from RPC calls.
func handleRPCError(err error) {
	switch err {
	case nil:
	case rpc.ErrShutdown, io.EOF, io.ErrUnexpectedEOF:
		log.Println("disconnected from bortplug")
		rpcc.Close()
		rpcc = nil
		connectPlug()
	default:
		log.Println(err)
	}
}

// sendMessages sends a slice of messages to the server.
func sendMessages(msgs []bort.Message) {
	for i := range msgs {
		if msgs[i].Context == "" {
			msgs[i].Context = cfg.Channel
		}
		if err := send(botc, &msgs[i]); err != nil {
			log.Println(err)
		}
	}
}

// pollPushes periodically delivers pending push messages.
func pollPushes() {
	t := time.Tick(time.Duration(cfg.PollPeriod) * time.Second)
	for {
		<-t
		deliverPushes()
	}
}

// send sends an IRC message to the server according to its content.
func send(snd irc.Sender, in *bort.Message) error {
	base := irc.Message{Command: irc.PRIVMSG, Params: []string{in.Context}}
	switch in.Type {
	case bort.None:
	case bort.PrivMsg:
		text := strings.TrimRight(in.Text, "\n")
		for _, str := range strings.Split(text, "\n") {
			out := base
			out.Trailing = str
			snd.Send(&out)
		}
	case bort.Action:
		text := strings.SplitN(in.Text+"\n", "\n", 2)[0]
		out := base
		out.Trailing = ctcp.Action(text)
		snd.Send(&out)
	default:
		return fmt.Errorf("unknown message type: %d", in.Type)
	}
	return nil
}

// convertMsg converts an irc.Message to a bort.Message.
func convertMsg(imsg *irc.Message) *bort.Message {
	bmsg := &bort.Message{
		Context: cfg.Channel,
		IRCCmd:  imsg.Command,
		Nick:    imsg.Name,
		User:    imsg.User,
		Host:    imsg.Host,
		Params:  append([]string(nil), imsg.Params...),
		Text:    imsg.Trailing,
	}
	if len(bmsg.Params) > 0 && bmsg.Params[0] != cfg.Channel {
		bmsg.Context = bmsg.Nick
	}
	switch bmsg.IRCCmd {
	case irc.PRIVMSG:
		// handle actions
		if tag, text, ok := ctcp.Decode(bmsg.Text); ok && tag == ctcp.ACTION {
			bmsg.Type = bort.Action
			bmsg.Text = text
			break
		}

		bmsg.Type = bort.PrivMsg
		isCmd := (bmsg.Context != cfg.Channel)
		text := strings.TrimSpace(bmsg.Text)
		if strings.HasPrefix(text, cfg.CmdPrefix) {
			text = strings.TrimLeft(text[len(cfg.CmdPrefix):], " ")
			isCmd = true
		}
		if isCmd {
			cmdAndArgs := strings.SplitN(text+" ", " ", 2)
			if len(cmdAndArgs) == 2 {
				bmsg.Command = cmdAndArgs[0]
				bmsg.Args = strings.TrimSpace(cmdAndArgs[1])
			}
		}
	case irc.JOIN:
		bmsg.Type = bort.Join
		bmsg.Text = bmsg.Nick
	case irc.PART:
		bmsg.Type = bort.Part
		bmsg.Text = bmsg.Nick
	}
	return bmsg
}

// connectPlug connects to bortplug's RPC socket.
func connectPlug() error {
	if rpcc != nil {
		return nil
	}

	var err error
	rpcc, err = rpc.Dial("tcp", cfg.Address)
	if err == nil {
		log.Printf("connected to bortplug (%s)\n", cfg.Address)
	}
	return err
}

// config overrides defaults with config file and flag values.
func config() {
	if err := bort.LoadConfig(&cfg, cfgFile); err != nil {
		log.Println(err)
	}
	flag.Visit(func(f *flag.Flag) {
		switch f.Name {
		case "n":
			cfg.Nick = flags.Nick
		case "s":
			cfg.Server = flags.Server
		case "c":
			cfg.Channel = flags.Channel
		case "a":
			cfg.Address = flags.Address
		case "p":
			cfg.CmdPrefix = flags.CmdPrefix
		case "t":
			cfg.PollPeriod = flags.PollPeriod
		}
	})
}

func init() {
	flag.StringVar(&flags.Nick, "n", cfg.Nick, "nick of the bot")
	flag.StringVar(&flags.Server, "s", cfg.Server, "IRC server")
	flag.StringVar(&flags.Channel, "c", cfg.Channel, "channel")
	flag.StringVar(&flags.Address, "a", cfg.Address, "bortplug address")
	flag.StringVar(&flags.CmdPrefix, "p", cfg.CmdPrefix, "command prefix")
	flag.UintVar(&flags.PollPeriod, "t", cfg.PollPeriod, "plugin push message poll period in seconds")
	flag.StringVar(&cfgFile, "f", "", "configuration file")
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"
	"runtime"
)

// Braindead helps the poor little windows users that don't know what's
// a terminal, and have opened bancho by doubleclicking on the executable
func Braindead() {
	if runtime.GOOS == "windows" {
		fmt.Print("Press a key to continue . . .")
		os.Stdin.Read(make([]byte, 1))
		fmt.Println()
	}
}
<commit_msg>add recover to Braindead<commit_after>package cmd

import (
	"fmt"
	"os"
	"runtime"
)

// Braindead helps the poor little windows users that don't know what's
// a terminal, and have opened bancho by doubleclicking on the executable
func Braindead() {
	c := recover()
	if c != nil {
		fmt.Println("An error happened while attempting to execute bnch.")
		fmt.Println(c)
	}
	if runtime.GOOS == "windows" {
		fmt.Print("Press a key to continue . . .")
		os.Stdin.Read(make([]byte, 1))
		fmt.Println()
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"

	"github.com/driusan/dgit/git"
)

func FetchPack(c *git.Client, args []string) error {
	flags := newFlagSet("fetch-pack")
	opts := git.FetchPackOptions{}
	flags.BoolVar(&opts.All, "all", false, "Fetch all remote refs")
	flags.BoolVar(&opts.Quiet, "quiet", false, "Do not print indexing status")
	flags.BoolVar(&opts.Quiet, "q", false, "Alias of --quiet")
	flags.BoolVar(&opts.Keep, "keep", false, "Not implemented")
	flags.BoolVar(&opts.Keep, "k", false, "Not implemented")
	flags.BoolVar(&opts.Thin, "thin", false, "Fetches a thin pack (Not implemented)")
	flags.BoolVar(&opts.IncludeTag, "include-tag", false, "Send annotated tags along with other objects")
	flags.BoolVar(&opts.NoProgress, "no-progress", false, "Do not show progress information")
	flags.StringVar(&opts.UploadPack, "upload-pack", "", "Execute upload-pack instead of git-upload-pack")
	flags.StringVar(&opts.UploadPack, "exec", "", "Execute upload-pack instead of git-upload-pack")
	depth := flags.Int("depth", 2147483647, "Not implemented")
	_ = flags.String("shallow-since", "", "Not implemented")
	_ = flags.String("shallow-exclude", "", "Not implemented")
	flags.BoolVar(&opts.DeepenRelative, "deepen-relative", false, "Not implemented")
	flags.BoolVar(&opts.CheckSelfContainedAndConnected, "check-self-contained-and-connected", false, "Not implemented")
	flags.BoolVar(&opts.Verbose, "verbose", false, "Be more verbose")
	flags.Parse(args)
	args = flags.Args()
	opts.Depth = int32(*depth)
	if len(args) < 1 {
		flags.Usage()
		return fmt.Errorf("Invalid flag usage")
	}
	rmt := git.Remote(args[0])
	var wants []git.Refname
	for _, name := range args[1:] {
		wants = append(wants, git.Refname(name))
	}
	_, err := git.FetchPack(c, opts, rmt, wants)
	return err
}
<commit_msg>Add -v as an alias of -verbose in fetch-pack<commit_after>package cmd

import (
	"fmt"

	"github.com/driusan/dgit/git"
)

func FetchPack(c *git.Client, args []string) error {
	flags := newFlagSet("fetch-pack")
	opts := git.FetchPackOptions{}
	flags.BoolVar(&opts.All, "all", false, "Fetch all remote refs")
	flags.BoolVar(&opts.Quiet, "quiet", false, "Do not print indexing status")
	flags.BoolVar(&opts.Quiet, "q", false, "Alias of --quiet")
	flags.BoolVar(&opts.Keep, "keep", false, "Not implemented")
	flags.BoolVar(&opts.Keep, "k", false, "Not implemented")
	flags.BoolVar(&opts.Thin, "thin", false, "Fetches a thin pack (Not implemented)")
	flags.BoolVar(&opts.IncludeTag, "include-tag", false, "Send annotated tags along with other objects")
	flags.BoolVar(&opts.NoProgress, "no-progress", false, "Do not show progress information")
	flags.StringVar(&opts.UploadPack, "upload-pack", "", "Execute upload-pack instead of git-upload-pack")
	flags.StringVar(&opts.UploadPack, "exec", "", "Execute upload-pack instead of git-upload-pack")
	depth := flags.Int("depth", 2147483647, "Not implemented")
	_ = flags.String("shallow-since", "", "Not implemented")
	_ = flags.String("shallow-exclude", "", "Not implemented")
	flags.BoolVar(&opts.DeepenRelative, "deepen-relative", false, "Not implemented")
	flags.BoolVar(&opts.CheckSelfContainedAndConnected, "check-self-contained-and-connected", false, "Not implemented")
	flags.BoolVar(&opts.Verbose, "verbose", false, "Be more verbose")
	flags.BoolVar(&opts.Verbose, "v", false, "Alias of verbose")
	flags.Parse(args)
	args = flags.Args()
	opts.Depth = int32(*depth)
	if len(args) < 1 {
		flags.Usage()
		return fmt.Errorf("Invalid flag usage")
	}
	rmt := git.Remote(args[0])
	var wants []git.Refname
	for _, name := range args[1:] {
		wants = append(wants, git.Refname(name))
	}
	_, err := git.FetchPack(c, opts, rmt, wants)
	return err
}
<|endoftext|>