<commit_before>package main

import (
	"bytes"
	"koding/tools/dnode"
	"koding/tools/kite"
	"koding/tools/log"
	"koding/tools/pty"
	"koding/tools/utils"
	"koding/virt"
	"strconv"
	"strings"
	"syscall"
	"time"
	"unicode/utf8"
)

type WebtermServer struct {
	Session          string `json:"session"`
	remote           WebtermRemote
	vm               *virt.VM
	user             *virt.User
	isForeignSession bool
	pty              *pty.PTY
	currentSecond    int64
	messageCounter   int
	byteCounter      int
	lineFeeedCounter int
}

type WebtermRemote struct {
	Output       dnode.Callback
	SessionEnded dnode.Callback
}

func registerWebtermMethods(k *kite.Kite) {
	registerVmMethod(k, "webterm.getSessions", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		// We need to use ls here, because /var/run/screen mount is only visible from inside of container. Errors are ignored.
		out, _ := vos.VM.AttachCommand(vos.User.Uid, "", "ls", "/var/run/screen/S-"+vos.User.Name).Output()
		names := strings.Split(string(out[:len(out)-1]), "\n")
		sessions := make([]string, len(names))
		for i, name := range names {
			segements := strings.SplitN(name, ".", 2)
			sessions[i] = segements[1]
		}
		return sessions, nil
	})

	// this method is special cased in oskite.go to allow foreign access
	registerVmMethod(k, "webterm.connect", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		var params struct {
			Remote       WebtermRemote
			Session      string
			SizeX, SizeY int
		}
		if args.Unmarshal(&params) != nil || params.SizeX <= 0 || params.SizeY <= 0 {
			return nil, &kite.ArgumentError{Expected: "{ remote: [object], session: [string], sizeX: [integer], sizeY: [integer] }"}
		}

		server := newWebtermServer(vos.VM, vos.User, params.Remote, params.Session, params.SizeX, params.SizeY)
		server.isForeignSession = (vos.User.Name != channel.Username)
		channel.OnDisconnect(func() { server.Close() })
		return server, nil
	})
}

func newWebtermServer(vm *virt.VM, user *virt.User, remote WebtermRemote, session string, sizeX, sizeY int) *WebtermServer {
	newSession := false
	if session == "" {
		session = utils.RandomString()
		newSession = true
	}

	server := &WebtermServer{
		Session: session,
		remote:  remote,
		vm:      vm,
		user:    user,
		pty:     pty.New(vm.PtsDir()),
	}
	server.SetSize(float64(sizeX), float64(sizeY))

	args := []string{"/usr/bin/screen", "-e^Bb", "-S", "koding." + session}
	if !newSession {
		args = append(args, "-x")
	}
	server.pty.Slave.Chown(user.Uid, -1)
	cmd := vm.AttachCommand(user.Uid, "/dev/pts/"+strconv.Itoa(server.pty.No), args...)

	err := cmd.Start()
	if err != nil {
		panic(err)
	}

	go func() {
		defer log.RecoverAndLog()

		cmd.Wait()
		server.pty.Slave.Close()
		server.pty.Master.Close()
		server.remote.SessionEnded()
	}()

	go func() {
		defer log.RecoverAndLog()

		buf := make([]byte, (1<<12)-utf8.UTFMax, 1<<12)
		for {
			n, err := server.pty.Master.Read(buf)
			for n < cap(buf)-1 {
				r, _ := utf8.DecodeLastRune(buf[:n])
				if r != utf8.RuneError {
					break
				}
				server.pty.Master.Read(buf[n : n+1])
				n++
			}

			s := time.Now().Unix()
			if server.currentSecond != s {
				server.currentSecond = s
				server.messageCounter = 0
				server.byteCounter = 0
				server.lineFeeedCounter = 0
			}
			server.messageCounter += 1
			server.byteCounter += n
			server.lineFeeedCounter += bytes.Count(buf[:n], []byte{'\n'})
			if server.messageCounter > 100 || server.byteCounter > 1<<18 || server.lineFeeedCounter > 300 {
				time.Sleep(time.Second)
			}

			server.remote.Output(string(utils.FilterInvalidUTF8(buf[:n])))
			if err != nil {
				break
			}
		}
	}()

	return server
}

func (server *WebtermServer) Input(data string) {
	server.pty.Master.Write([]byte(data))
}

func (server *WebtermServer) ControlSequence(data string) {
	server.pty.MasterEncoded.Write([]byte(data))
}

func (server *WebtermServer) SetSize(x, y float64) {
	server.pty.SetSize(uint16(x), uint16(y))
}

func (server *WebtermServer) Close() error {
	server.pty.Signal(syscall.SIGHUP)
	return nil
}

func (server *WebtermServer) Terminate() error {
	server.Close()
	if !server.isForeignSession {
		server.vm.AttachCommand(server.user.Uid, "", "/usr/bin/screen", "-S", "koding."+server.Session, "-X", "quit").Run()
	}
	return nil
}
<commit_msg>oskite: Refactored webterm.go<commit_after>package main

import (
	"bytes"
	"koding/tools/dnode"
	"koding/tools/kite"
	"koding/tools/log"
	"koding/tools/pty"
	"koding/tools/utils"
	"koding/virt"
	"strconv"
	"strings"
	"syscall"
	"time"
	"unicode/utf8"
)

type WebtermServer struct {
	Session          string `json:"session"`
	remote           WebtermRemote
	vm               *virt.VM
	user             *virt.User
	isForeignSession bool
	pty              *pty.PTY
	currentSecond    int64
	messageCounter   int
	byteCounter      int
	lineFeeedCounter int
}

type WebtermRemote struct {
	Output       dnode.Callback
	SessionEnded dnode.Callback
}

func registerWebtermMethods(k *kite.Kite) {
	registerVmMethod(k, "webterm.getSessions", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		// We need to use ls here, because /var/run/screen mount is only visible from inside of container. Errors are ignored.
		out, _ := vos.VM.AttachCommand(vos.User.Uid, "", "ls", "/var/run/screen/S-"+vos.User.Name).Output()
		names := strings.Split(string(out[:len(out)-1]), "\n")
		sessions := make([]string, len(names))
		for i, name := range names {
			segements := strings.SplitN(name, ".", 2)
			sessions[i] = segements[1]
		}
		return sessions, nil
	})

	// this method is special cased in oskite.go to allow foreign access
	registerVmMethod(k, "webterm.connect", false, func(args *dnode.Partial, channel *kite.Channel, vos *virt.VOS) (interface{}, error) {
		var params struct {
			Remote       WebtermRemote
			Session      string
			SizeX, SizeY int
		}
		if args.Unmarshal(&params) != nil || params.SizeX <= 0 || params.SizeY <= 0 {
			return nil, &kite.ArgumentError{Expected: "{ remote: [object], session: [string], sizeX: [integer], sizeY: [integer] }"}
		}

		newSession := false
		if params.Session == "" {
			params.Session = utils.RandomString()
			newSession = true
		}

		server := &WebtermServer{
			Session:          params.Session,
			remote:           params.Remote,
			vm:               vos.VM,
			user:             vos.User,
			isForeignSession: vos.User.Name != channel.Username,
			pty:              pty.New(vos.VM.PtsDir()),
		}
		server.SetSize(float64(params.SizeX), float64(params.SizeY))

		cmdArgs := []string{"/usr/bin/screen", "-e^Bb", "-S", "koding." + params.Session}
		if !newSession {
			cmdArgs = append(cmdArgs, "-x")
		}
		server.pty.Slave.Chown(vos.User.Uid, -1)
		cmd := vos.VM.AttachCommand(vos.User.Uid, "/dev/pts/"+strconv.Itoa(server.pty.No), cmdArgs...)

		err := cmd.Start()
		if err != nil {
			panic(err)
		}

		go func() {
			defer log.RecoverAndLog()

			cmd.Wait()
			server.pty.Slave.Close()
			server.pty.Master.Close()
			server.remote.SessionEnded()
		}()

		go func() {
			defer log.RecoverAndLog()

			buf := make([]byte, (1<<12)-utf8.UTFMax, 1<<12)
			for {
				n, err := server.pty.Master.Read(buf)
				for n < cap(buf)-1 {
					r, _ := utf8.DecodeLastRune(buf[:n])
					if r != utf8.RuneError {
						break
					}
					server.pty.Master.Read(buf[n : n+1])
					n++
				}

				s := time.Now().Unix()
				if server.currentSecond != s {
					server.currentSecond = s
					server.messageCounter = 0
					server.byteCounter = 0
					server.lineFeeedCounter = 0
				}
				server.messageCounter += 1
				server.byteCounter += n
				server.lineFeeedCounter += bytes.Count(buf[:n], []byte{'\n'})
				if server.messageCounter > 100 || server.byteCounter > 1<<18 || server.lineFeeedCounter > 300 {
					time.Sleep(time.Second)
				}

				server.remote.Output(string(utils.FilterInvalidUTF8(buf[:n])))
				if err != nil {
					break
				}
			}
		}()

		channel.OnDisconnect(func() { server.Close() })

		return server, nil
	})
}

func (server *WebtermServer) Input(data string) {
	server.pty.Master.Write([]byte(data))
}

func (server *WebtermServer) ControlSequence(data string) {
	server.pty.MasterEncoded.Write([]byte(data))
}

func (server *WebtermServer) SetSize(x, y float64) {
	server.pty.SetSize(uint16(x), uint16(y))
}

func (server *WebtermServer) Close() error {
	server.pty.Signal(syscall.SIGHUP)
	return nil
}

func (server *WebtermServer) Terminate() error {
	server.Close()
	if !server.isForeignSession {
		server.vm.AttachCommand(server.user.Uid, "", "/usr/bin/screen", "-S", "koding."+server.Session, "-X", "quit").Run()
	}
	return nil
}
<|endoftext|>


<commit_before>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
		}
		if host, _, err := net.SplitHostPort(u.Host); err == nil {
			s.GitHost = host
		} else {
			s.GitHost = u.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
}
<commit_msg>cli: Don't allow duplicate servers to be added<commit_after>package main

import (
	"fmt"
	"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
		}
		if host, _, err := net.SplitHostPort(u.Host); err == nil {
			s.GitHost = host
		} else {
			s.GitHost = u.Host
		}
	}

	for _, existing := range config.Servers {
		if existing.Name == s.Name {
			return fmt.Errorf("Server %q already exists in ~/.flynnrc", s.Name)
		}
		if existing.URL == s.URL {
			return fmt.Errorf("A server with the URL %q already exists in ~/.flynnrc", s.URL)
		}
		if existing.GitHost == s.GitHost {
			return fmt.Errorf("A server with the git host %q already exists in ~/.flynnrc", s.GitHost)
		}
	}

	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 %q added.", s.Name)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"net/url"

	"github.com/rcrowley/go-tigertonic"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

//curl -H "Content-Type: application/json" -XPUT -d '{"P"}' -f -v http://localhost:3000/beacon/{id}

const (
	dbName = "artroomServer"
	//DBURI for the mongodb
	DBURI = "127.0.0.1"

	waltersAPIPrefix    = "http://api.thewalters.org/v1/objects?apikey=ShxvahaBFNIcfWR7E78xXdssKIlXtUAJk9rDDrrmlvbOlxQKtASCzV4op5aHv2Il&keyword="
	waltersImagePrefix  = "http://static.thewalters.org/images/"
	waltersImagePostfix = "?width=500"
)

var (
	s = Server{}
	//CollectionNames is the shiz
	CollectionNames = []string{"beacon", "art"}
	beaconIndex     = mgo.Index{
		Key:        []string{"MinorID"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
		Name:       "beaconIndex",
		//ExpireAf
	}

	artIndex = mgo.Index{
		Key:        []string{"Beacon", "Title"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
		Name:       "ArtIndex",
		//ExpireAf
	}
	indices = []mgo.Index{beaconIndex, artIndex}
	mux     *tigertonic.TrieServeMux
)

type (
	//Server is the name for the server deal wit it
	Server struct {
		Session *mgo.Session // The main session we'll we be cloning
		DBURI   string       // Where the DB is on the network
		dbName  string       // Name of the MongoDB
	}

	//Beacon is the struct that structures what the data for a beacon will look like
	Beacon struct {
		ProxID  string
		MajorID int
		MinorID int
	}
	//FormResponse is what we get back from the form
	FormResponse struct {
		Date        string
		Author      string
		Title       string
		ProxID      string
		MajorID     int
		MinorID     int
		Description string
	}

	//The structure the walter api gives us more or less
	WalterObj struct {
		ObjectID       int
		Collection     string
		Title          string
		Medium         string
		Description    string
		Images         string
		CuratorComment string
		Beacon         Beacon
		ImageURL       string
	}
	//Walters objects
	Walters struct {
		Items []WalterObj
	}
)

func main() {
	log.Println("Server is warming up...")
	initDB()
	initHandlers()
	defer s.Session.Close()
	server := tigertonic.NewServer("localhost:3000", mux)
	log.Fatal(server.ListenAndServe())
}

func initHandlers() {
	cors := tigertonic.NewCORSBuilder().AddAllowedOrigins("*").AddAllowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept")
	mux = tigertonic.NewTrieServeMux()
	mux.Handle(
		"POST",
		"/beacon",
		cors.Build(tigertonic.Marshaled(handlePOSTBeacon)),
	)
	//Could use go-metrics to do hot piece of art
	mux.Handle(
		"GET",
		"/beacon/{minorID}",
		cors.Build(tigertonic.Marshaled(handleBeacon)),
	)
}

func handlePOSTBeacon(u *url.URL, h http.Header, formResponse *FormResponse) (status int, responseHeaders http.Header, _ interface{}, err error) {
	log.Printf("We have begun the ritual, %v", h)
	client := &http.Client{}
	req, _ := http.NewRequest("GET", waltersAPIPrefix+formResponse.Title, nil)
	req.Header.Add("Accept", "application/json")
	res, err := client.Do(req)
	if err != nil {
		return 500, h, nil, errors.New("Req didn't go through")
		//		log.Fatalf("Req didn't go through, %v", err)
	}
	defer res.Body.Close()
	var data json.RawMessage
	err = json.NewDecoder(res.Body).Decode(&data)
	if err != nil {
		return 500, h, nil, errors.New("Couldn't decode data...")
		//		log.Fatalf("Can't resolve the datum?%v", err)
	}
	w := Walters{}
	err = json.Unmarshal(data, &w)
	if err != nil {
		return 500, h, nil, errors.New("Couldn't marshall into individual waltOBJ'")
		//		log.Fatalf("Can't unmarshall into individ waltOBJ, %v", err)
	}
	waltersObject := w.Items[0]
	waltersObject.Beacon = Beacon{formResponse.ProxID, formResponse.MajorID, formResponse.MinorID}
	waltersObject.ImageURL = waltersImagePrefix + waltersObject.Images + waltersImagePostfix
	waltersObject.CuratorComment = formResponse.Description
	err = Insert("beacon", waltersObject.Beacon)
	if err != nil {
		//Return a 500
		return 500, h, nil, errors.New("Couldn't insert corresponding beacon.'")
	}

	err = Insert("art", waltersObject)
	if err != nil {
		//Return a 500
		return 500, h, nil, errors.New("Couldn't insert corresponding art piece.'")
	}

	return 200, h, nil, nil
}

func handleBeacon(u *url.URL, h http.Header, _ interface{}) (status int, responseHeaders http.Header, waltersObj *WalterObj, err error) {
	minorID := u.Query().Get("minorID")
	log.Println(minorID)
	beacon, err := SearchBeaconByID(minorID, 0, -1)
	if err != nil {
		//Beacon not found return 404
		return 404, responseHeaders, nil, errors.New("Beacon not found in db")
	}
	for _, i := range beacon {
		arts, error := SearchArtByBeacon(i, 0, -1)
		if error != nil {
			return 404, responseHeaders, nil, errors.New("Beacon not assigned to art piece")
		}
		return 200, responseHeaders, &arts[0], nil

	}
	//	responseHeaders.Add("Accept","application/json")
	return 404, responseHeaders, nil, errors.New("Beacon not found in db")
	//Send a get request to api with keyword param
}

func initDB() {
	s.DBURI = DBURI
	s.dbName = dbName
	s.getSession()
	s.Session.SetSafe(&mgo.Safe{})
	s.Session.SetMode(mgo.Monotonic, true)
	cNames, errors := EnsureIndex(CollectionNames, indices...)
	for k, err := range errors {
		if err != nil {
			log.Fatalf("Indices not taking for %v;%v\n", cNames[k], err)
		}
	}
}

//EnsureIndex ensures that when we store things, we get the expected results
func EnsureIndex(collectionNames []string, indices ...mgo.Index) (s []string, e []error) {
	for j, k := range indices {
		function := func(c *mgo.Collection) error {
			return c.EnsureIndex(k)
		}
		err := withCollection(collectionNames[j], function)
		if err != nil {
			s = append(s, collectionNames[j])
			e = append(e, err)
		}
	}
	return
}

func (s *Server) getSession() *mgo.Session {
	if s.Session == nil {
		var err error
		dialInfo := &mgo.DialInfo{
			Addrs:    []string{s.DBURI},
			Direct:   true,
			FailFast: false,
		}
		s.Session, err = mgo.DialWithInfo(dialInfo)
		if err != nil {
			log.Fatalf("Can't find MongoDB. Is it started? %v\n", err)
		}
	}
	// Returns a copy of the session so we don't waste le resources? Doesn't reuse socket however
	return s.Session.Copy()
}

func withCollection(collection string, fn func(*mgo.Collection) error) error {
	session := s.getSession()
	defer session.Close()
	c := session.DB(s.dbName).C(collection)
	return fn(c)
}

//Insert datum into a specific collection
func Insert(collectionName string, values ...interface{}) error {
	function := func(c *mgo.Collection) error {
		err := c.Insert(values...)
		if err != nil {
			log.Printf("Can't insert document, %v\n", err)
		}
		return err
	}
	return withCollection(collectionName, function)
}

//SearchBeacon searches for a beacon using a passed in struct
func SearchBeacon(q interface{}, skip int, limit int) (searchResults []Beacon, err error) {
	searchResults = []Beacon{}
	query := func(c *mgo.Collection) error {
		function := c.Find(q).Skip(skip).Limit(limit).All(&searchResults)
		if limit < 0 {
			function = c.Find(q).Skip(skip).All(&searchResults)
		}
		return function
	}
	search := func() error {
		return withCollection("beacon", query)
	}
	err = search()
	return
}

//Estimote id
//

//SearchBeaconByID is a
func SearchBeaconByID(beacon string, skip int, limit int) (searchResults []Beacon, err error) {
	if len(beacon) == 20 {
		return SearchBeacon(bson.M{"MinorID": beacon}, skip, limit)
	}
	return nil, errors.New("Not long enough to be a beacon")
}

//SearchArt is a
func SearchArt(q interface{}, skip int, limit int) (searchResults []WalterObj, err error) {
	searchResults = []WalterObj{}
	query := func(c *mgo.Collection) error {
		function := c.Find(q).Skip(skip).Limit(limit).All(&searchResults)
		if limit < 0 {
			function = c.Find(q).Skip(skip).All(&searchResults)
		}
		return function
	}
	search := func() error {
		return withCollection("art", query)
	}
	err = search()
	return
}

//SearchArtByBeacon is a specific version of searchArt
func SearchArtByBeacon(beacon Beacon, skip int, limit int) (searchResults []WalterObj, err error) {
	return SearchArt(bson.M{"Beacon": beacon}, skip, limit)
}
<commit_msg>CORS derpin the hell out?<commit_after>package main

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"net/url"

	"github.com/rcrowley/go-tigertonic"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

//curl -H "Content-Type: application/json" -XPUT -d '{"P"}' -f -v http://localhost:3000/beacon/{id}

const (
	dbName = "artroomServer"
	//DBURI for the mongodb
	DBURI = "127.0.0.1"

	waltersAPIPrefix    = "http://api.thewalters.org/v1/objects?apikey=ShxvahaBFNIcfWR7E78xXdssKIlXtUAJk9rDDrrmlvbOlxQKtASCzV4op5aHv2Il&keyword="
	waltersImagePrefix  = "http://static.thewalters.org/images/"
	waltersImagePostfix = "?width=500"
)

var (
	s = Server{}
	//CollectionNames is the shiz
	CollectionNames = []string{"beacon", "art"}
	beaconIndex     = mgo.Index{
		Key:        []string{"MinorID"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
		Name:       "beaconIndex",
		//ExpireAf
	}

	artIndex = mgo.Index{
		Key:        []string{"Beacon", "Title"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
		Name:       "ArtIndex",
		//ExpireAf
	}
	indices = []mgo.Index{beaconIndex, artIndex}
	mux     *tigertonic.TrieServeMux
)

type (
	//Server is the name for the server deal wit it
	Server struct {
		Session *mgo.Session // The main session we'll we be cloning
		DBURI   string       // Where the DB is on the network
		dbName  string       // Name of the MongoDB
	}

	//Beacon is the struct that structures what the data for a beacon will look like
	Beacon struct {
		ProxID  string
		MajorID int
		MinorID int
	}
	//FormResponse is what we get back from the form
	FormResponse struct {
		Date        string
		Author      string
		Title       string
		ProxID      string
		MajorID     int
		MinorID     int
		Description string
	}

	//The structure the walter api gives us more or less
	WalterObj struct {
		ObjectID       int
		Collection     string
		Title          string
		Medium         string
		Description    string
		Images         string
		CuratorComment string
		Beacon         Beacon
		ImageURL       string
	}
	//Walters objects
	Walters struct {
		Items []WalterObj
	}
)

func main() {
	log.Println("Server is warming up...")
	initDB()
	initHandlers()
	defer s.Session.Close()
	server := tigertonic.NewServer("localhost:3000", mux)
	log.Fatal(server.ListenAndServe())
}

func initHandlers() {
	cors := tigertonic.NewCORSBuilder().AddAllowedOrigins("*").AddAllowedHeaders("Access-Control-Allow-Headers", "Origin", "X-Requested-With", "Content-Type", "Accept")
	mux = tigertonic.NewTrieServeMux()
	mux.Handle(
		"POST",
		"/beacon",
		cors.Build(tigertonic.Marshaled(handlePOSTBeacon)),
	)
	//Could use go-metrics to do hot piece of art
	mux.Handle(
		"GET",
		"/beacon/{minorID}",
		cors.Build(tigertonic.Marshaled(handleBeacon)),
	)
}

func handlePOSTBeacon(u *url.URL, h http.Header, formResponse *FormResponse) (status int, responseHeaders http.Header, _ interface{}, err error) {
	log.Printf("We have begun the ritual, %v", h)
	client := &http.Client{}
	req, _ := http.NewRequest("GET", waltersAPIPrefix+formResponse.Title, nil)
	req.Header.Add("Accept", "application/json")
	res, err := client.Do(req)
	if err != nil {
		return 500, h, nil, errors.New("Req didn't go through")
		//		log.Fatalf("Req didn't go through, %v", err)
	}
	defer res.Body.Close()
	var data json.RawMessage
	err = json.NewDecoder(res.Body).Decode(&data)
	if err != nil {
		return 500, h, nil, errors.New("Couldn't decode data...")
		//		log.Fatalf("Can't resolve the datum?%v", err)
	}
	w := Walters{}
	err = json.Unmarshal(data, &w)
	if err != nil {
		return 500, h, nil, errors.New("Couldn't marshall into individual waltOBJ'")
		//		log.Fatalf("Can't unmarshall into individ waltOBJ, %v", err)
	}
	waltersObject := w.Items[0]
	waltersObject.Beacon = Beacon{formResponse.ProxID, formResponse.MajorID, formResponse.MinorID}
	waltersObject.ImageURL = waltersImagePrefix + waltersObject.Images + waltersImagePostfix
	waltersObject.CuratorComment = formResponse.Description
	err = Insert("beacon", waltersObject.Beacon)
	if err != nil {
		//Return a 500
		return 500, h, nil, errors.New("Couldn't insert corresponding beacon.'")
	}

	err = Insert("art", waltersObject)
	if err != nil {
		//Return a 500
		return 500, h, nil, errors.New("Couldn't insert corresponding art piece.'")
	}

	return 200, h, nil, nil
}

func handleBeacon(u *url.URL, h http.Header, _ interface{}) (status int, responseHeaders http.Header, waltersObj *WalterObj, err error) {
	minorID := u.Query().Get("minorID")
	log.Println(minorID)
	beacon, err := SearchBeaconByID(minorID, 0, -1)
	if err != nil {
		//Beacon not found return 404
		return 404, responseHeaders, nil, errors.New("Beacon not found in db")
	}
	for _, i := range beacon {
		arts, error := SearchArtByBeacon(i, 0, -1)
		if error != nil {
			return 404, responseHeaders, nil, errors.New("Beacon not assigned to art piece")
		}
		return 200, responseHeaders, &arts[0], nil

	}
	//	responseHeaders.Add("Accept","application/json")
	return 404, responseHeaders, nil, errors.New("Beacon not found in db")
	//Send a get request to api with keyword param
}

func initDB() {
	s.DBURI = DBURI
	s.dbName = dbName
	s.getSession()
	s.Session.SetSafe(&mgo.Safe{})
	s.Session.SetMode(mgo.Monotonic, true)
	cNames, errors := EnsureIndex(CollectionNames, indices...)
	for k, err := range errors {
		if err != nil {
			log.Fatalf("Indices not taking for %v;%v\n", cNames[k], err)
		}
	}
}

//EnsureIndex ensures that when we store things, we get the expected results
func EnsureIndex(collectionNames []string, indices ...mgo.Index) (s []string, e []error) {
	for j, k := range indices {
		function := func(c *mgo.Collection) error {
			return c.EnsureIndex(k)
		}
		err := withCollection(collectionNames[j], function)
		if err != nil {
			s = append(s, collectionNames[j])
			e = append(e, err)
		}
	}
	return
}

func (s *Server) getSession() *mgo.Session {
	if s.Session == nil {
		var err error
		dialInfo := &mgo.DialInfo{
			Addrs:    []string{s.DBURI},
			Direct:   true,
			FailFast: false,
		}
		s.Session, err = mgo.DialWithInfo(dialInfo)
		if err != nil {
			log.Fatalf("Can't find MongoDB. Is it started? %v\n", err)
		}
	}
	// Returns a copy of the session so we don't waste le resources? Doesn't reuse socket however
	return s.Session.Copy()
}

func withCollection(collection string, fn func(*mgo.Collection) error) error {
	session := s.getSession()
	defer session.Close()
	c := session.DB(s.dbName).C(collection)
	return fn(c)
}

//Insert datum into a specific collection
func Insert(collectionName string, values ...interface{}) error {
	function := func(c *mgo.Collection) error {
		err := c.Insert(values...)
		if err != nil {
			log.Printf("Can't insert document, %v\n", err)
		}
		return err
	}
	return withCollection(collectionName, function)
}

//SearchBeacon searches for a beacon using a passed in struct
func SearchBeacon(q interface{}, skip int, limit int) (searchResults []Beacon, err error) {
	searchResults = []Beacon{}
	query := func(c *mgo.Collection) error {
		function := c.Find(q).Skip(skip).Limit(limit).All(&searchResults)
		if limit < 0 {
			function = c.Find(q).Skip(skip).All(&searchResults)
		}
		return function
	}
	search := func() error {
		return withCollection("beacon", query)
	}
	err = search()
	return
}

//Estimote id
//

//SearchBeaconByID is a
func SearchBeaconByID(beacon string, skip int, limit int) (searchResults []Beacon, err error) {
	if len(beacon) == 20 {
		return SearchBeacon(bson.M{"MinorID": beacon}, skip, limit)
	}
	return nil, errors.New("Not long enough to be a beacon")
}

//SearchArt is a
func SearchArt(q interface{}, skip int, limit int) (searchResults []WalterObj, err error) {
	searchResults = []WalterObj{}
	query := func(c *mgo.Collection) error {
		function := c.Find(q).Skip(skip).Limit(limit).All(&searchResults)
		if limit < 0 {
			function = c.Find(q).Skip(skip).All(&searchResults)
		}
		return function
	}
	search := func() error {
		return withCollection("art", query)
	}
	err = search()
	return
}

//SearchArtByBeacon is a specific version of searchArt
func SearchArtByBeacon(beacon Beacon, skip int, limit int) (searchResults []WalterObj, err error) {
	return SearchArt(bson.M{"Beacon": beacon}, skip, limit)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/jmcvetta/neoism"
)

//DB stock the Database variable
var DB *neoism.Database

//APIGetAllLines return All lines of bus
func APIGetAllLines(c *gin.Context) {
	content, err := GetAllLines()
	if err != nil {
		fmt.Printf("%s\n", err)
		return
	}
	c.JSON(200, content)
}

//APIGetStopsForLine return all stops for lineID
func APIGetStopsForLine(c *gin.Context) {
	lineID := c.Params.ByName("lineID")
	format, get := c.Get("format")
	if get != true {
		return
	}
	fmt.Printf("%s\n", format)
	content, err := GetStopsFromLineID(lineID)
	if err != nil {
		fmt.Printf("%s\n", err)
		return
	}
	c.JSON(200, content)

}

func init() {
	var err error

	protocol := os.Getenv("NEO4J_PROT")
	user := os.Getenv("NEO4J_USER")
	password := os.Getenv("NEO4J_PASSWD")
	host := os.Getenv("NEO4J_HOST")
	port := os.Getenv("NEO4J_PORT")
	DB, err = neoism.Connect(fmt.Sprintf("%s://%s:%s@%s:%s", protocol, user, password, host, port))
	if err != nil {
		return
	}
}

func main() {
	app := gin.Default()

	app.GET("/", APIGetAllLines)
	app.GET("/:lineID", APIGetStopsForLine)
	app.Run(fmt.Sprintf(":%s", os.Getenv("API_PORT")))
	app.NoRoute(func(c *gin.Context) {
		c.JSON(404, gin.H{"code": "404", "message": "Page not found"})
	})
}
<commit_msg>stop json for moment<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/jmcvetta/neoism"
)

//DB stock the Database variable
var DB *neoism.Database

//APIGetAllLines return All lines of bus
func APIGetAllLines(c *gin.Context) {
	content, err := GetAllLines()
	if err != nil {
		fmt.Printf("%s\n", err)
		return
	}
	c.JSON(200, content)
}

//APIGetStopsForLine return all stops for lineID
func APIGetStopsForLine(c *gin.Context) {
	lineID := c.Params.ByName("lineID")

	content, err := GetStopsFromLineID(lineID)
	if err != nil {
		fmt.Printf("%s\n", err)
		return
	}
	c.JSON(200, content)

}

func init() {
	var err error

	protocol := os.Getenv("NEO4J_PROT")
	user := os.Getenv("NEO4J_USER")
	password := os.Getenv("NEO4J_PASSWD")
	host := os.Getenv("NEO4J_HOST")
	port := os.Getenv("NEO4J_PORT")
	DB, err = neoism.Connect(fmt.Sprintf("%s://%s:%s@%s:%s", protocol, user, password, host, port))
	if err != nil {
		return
	}
}

func main() {
	app := gin.Default()

	app.GET("/", APIGetAllLines)
	app.GET("/:lineID", APIGetStopsForLine)
	app.Run(fmt.Sprintf(":%s", os.Getenv("API_PORT")))
	app.NoRoute(func(c *gin.Context) {
		c.JSON(404, gin.H{"code": "404", "message": "Page not found"})
	})
}
<|endoftext|>


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

package main

import (
	"encoding/json"
	"github.com/fsouza/lb"
	"github.com/howeyc/fsnotify"
	"log"
	"os"
	"sync"
)

type jsonRule struct {
	Domain   string
	Backends []string
}

type Rule struct {
	Domain  string
	Backend *lb.LoadBalancer
}

type Server struct {
	rules []Rule
	rmut  sync.RWMutex
}

func NewServer(ruleFile string) (*Server, error) {
	rules, err := loadRules(ruleFile)
	if err != nil {
		return nil, err
	}
	s := Server{rules: rules}
	w, err := fsnotify.NewWatcher()
	if err != nil {
		log.Printf("Warning: fronted is not watching rule file %q. Reason: %s", ruleFile, err)
		return &s, nil
	}
	err = w.Watch(ruleFile)
	if err != nil {
		log.Printf("Warning: fronted is not watching rule file %q. Reason: %s", ruleFile, err)
		return &s, nil
	}
	go func() {
		for {
			select {
			case e := <-w.Event:
				if e.IsModify() {
					if rules, err := loadRules(ruleFile); err == nil {
						s.rmut.Lock()
						s.rules = rules
						s.rmut.Unlock()
					}
				}
			case <-w.Error:
			}
		}
	}()
	return &s, nil
}

func loadRules(file string) ([]Rule, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	var rs []jsonRule
	err = json.NewDecoder(f).Decode(&rs)
	if err != nil {
		return nil, &invalidRuleError{err}
	}
	rules := make([]Rule, len(rs))
	for i, r := range rs {
		balancer, err := lb.NewLoadBalancer(r.Backends...)
		if err != nil {
			return nil, &invalidRuleError{err}
		}
		rules[i] = Rule{Domain: r.Domain, Backend: balancer}
	}
	return rules, nil
}

type invalidRuleError struct {
	err error
}

func (e *invalidRuleError) Error() string {
	return "Invalid rule file: " + e.err.Error()
}

func main() {}
<commit_msg>server: fix typo<commit_after>// Copyright 2013 Francisco Souza. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"encoding/json"
	"github.com/fsouza/lb"
	"github.com/howeyc/fsnotify"
	"log"
	"os"
	"sync"
)

type jsonRule struct {
	Domain   string
	Backends []string
}

type Rule struct {
	Domain  string
	Backend *lb.LoadBalancer
}

type Server struct {
	rules []Rule
	rmut  sync.RWMutex
}

func NewServer(ruleFile string) (*Server, error) {
	rules, err := loadRules(ruleFile)
	if err != nil {
		return nil, err
	}
	s := Server{rules: rules}
	w, err := fsnotify.NewWatcher()
	if err != nil {
		log.Printf("Warning: frontend server is not watching rule file %q. Reason: %s", ruleFile, err)
		return &s, nil
	}
	err = w.Watch(ruleFile)
	if err != nil {
		log.Printf("Warning: frontend server is not watching rule file %q. Reason: %s", ruleFile, err)
		return &s, nil
	}
	go func() {
		for {
			select {
			case e := <-w.Event:
				if e.IsModify() {
					if rules, err := loadRules(ruleFile); err == nil {
						s.rmut.Lock()
						s.rules = rules
						s.rmut.Unlock()
					}
				}
			case <-w.Error:
			}
		}
	}()
	return &s, nil
}

func loadRules(file string) ([]Rule, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	var rs []jsonRule
	err = json.NewDecoder(f).Decode(&rs)
	if err != nil {
		return nil, &invalidRuleError{err}
	}
	rules := make([]Rule, len(rs))
	for i, r := range rs {
		balancer, err := lb.NewLoadBalancer(r.Backends...)
		if err != nil {
			return nil, &invalidRuleError{err}
		}
		rules[i] = Rule{Domain: r.Domain, Backend: balancer}
	}
	return rules, nil
}

type invalidRuleError struct {
	err error
}

func (e *invalidRuleError) Error() string {
	return "Invalid rule file: " + e.err.Error()
}

func main() {}
<|endoftext|>


<commit_before>package main

import (
    "github.com/go-martini/martini"
)

type Point struct {
  X int
  Y int
}

type Car struct {
  Color int
  Point Point
}

func main() {
  m := martini.Classic()
  m.Get("/", Index)

  m.Get("/coords", Coords)
  m.Get("/move/:x/:y", Move) // ToDo: make this post reqeust
  m.Run()
}

func Index() string {
    return "This is index"
}

func Coords() string {
    return "coords"
}

func Move(x int, y int) (Point) {
    return "fake"
}
<commit_msg>faking stuff<commit_after>package main

import (
    "github.com/go-martini/martini"
)

type Point struct {
  X int
  Y int
}

type Car struct {
  Color int
  Point Point
}

func main() {
  m := martini.Classic()
  m.Get("/", Index)

  m.Get("/coords", Coords)
  m.Get("/move/:x/:y", Move) // ToDo: make this post reqeust
  m.Run()
}

func Index() string {
    return "This is index"
}

func Coords() string {
    return "coords"
}

func Move(x int, y int) (string) { // this is fake function for now. ToDo: change it to use actual Point
    return "fake"
}
<|endoftext|>


<commit_before>/*
 * Network packet analysis framework.
 *
 * Copyright (c) 2014, Alessandro Ghedini
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package filter

import "fmt"

func ExampleARP() {
	arp := NewBuilder().
		LD(Half, ABS, 12).
		JEQ(Const, "", "fail", 0x806).
		RET(Const, 0x40000).
		Label("fail").
		RET(Const, 0x0).
		Build()

	fmt.Println(arp)

	// Output:
	// { 0x28,   0,   0, 0x0000000c },
	// { 0x15,   0,   1, 0x00000806 },
	// { 0x06,   0,   0, 0x00040000 },
	// { 0x06,   0,   0, 0x00000000 },
}

func ExampleDNS() {
	dns := NewBuilder().
		LD(Word, IMM, 20).
		LDX(Byte, MSH, 0).
		ADD(Index, 0).
		TAX().
		Label("lb_0").
		LD(Word, IND, 0).
		JEQ(Const, "", "lb_1", 0x07657861).
		LD(Word, IND, 4).
		JEQ(Const, "", "lb_1", 0x6d706c65).
		LD(Word, IND, 8).
		JEQ(Const, "", "lb_1", 0x03636f6d).
		LD(Byte, IND, 12).
		JEQ(Const, "", "lb_1", 0x00).
		RET(Const, 1).
		Label("lb_1").
		RET(Const, 0).
		Build()

	fmt.Println(dns)

	// Output:
	// { 0x00,   0,   0, 0x00000014 },
	// { 0xb1,   0,   0, 0x00000000 },
	// { 0x0c,   0,   0, 0x00000000 },
	// { 0x07,   0,   0, 0x00000000 },
	// { 0x40,   0,   0, 0x00000000 },
	// { 0x15,   0,   7, 0x07657861 },
	// { 0x40,   0,   0, 0x00000004 },
	// { 0x15,   0,   5, 0x6d706c65 },
	// { 0x40,   0,   0, 0x00000008 },
	// { 0x15,   0,   3, 0x03636f6d },
	// { 0x50,   0,   0, 0x0000000c },
	// { 0x15,   0,   1, 0x00000000 },
	// { 0x06,   0,   0, 0x00000001 },
	// { 0x06,   0,   0, 0x00000000 },
}
<commit_msg>filter: convert bpf_builder tests to real tests instead of examples<commit_after>/*
 * Network packet analysis framework.
 *
 * Copyright (c) 2014, Alessandro Ghedini
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package filter

import "testing"

func TestEmpty(t *testing.T) {
	bld := NewBuilder()

	flt := bld.Build()
	if flt.Len() != 0 {
		t.Fatalf("Len mismatch: %d", flt.Len())
	}
	flt.Cleanup()
}

var test_arp = `{ 0x28,   0,   0, 0x0000000c },
{ 0x15,   0,   1, 0x00000806 },
{ 0x06,   0,   0, 0x00040000 },
{ 0x06,   0,   0, 0x00000000 },`

func TestARP(t *testing.T) {
	arp := NewBuilder().
		LD(Half, ABS, 12).
		JEQ(Const, "", "fail", 0x806).
		RET(Const, 0x40000).
		Label("fail").
		RET(Const, 0x0).
		Build()

	if arp.String() != test_arp {
		t.Fatalf("Program mismatch: %s", arp.String())
	}
}

var test_dns = `{ 0x00,   0,   0, 0x00000014 },
{ 0xb1,   0,   0, 0x00000000 },
{ 0x0c,   0,   0, 0x00000000 },
{ 0x07,   0,   0, 0x00000000 },
{ 0x40,   0,   0, 0x00000000 },
{ 0x15,   0,   7, 0x07657861 },
{ 0x40,   0,   0, 0x00000004 },
{ 0x15,   0,   5, 0x6d706c65 },
{ 0x40,   0,   0, 0x00000008 },
{ 0x15,   0,   3, 0x03636f6d },
{ 0x50,   0,   0, 0x0000000c },
{ 0x15,   0,   1, 0x00000000 },
{ 0x06,   0,   0, 0x00000001 },
{ 0x06,   0,   0, 0x00000000 },`

func TestDNS(t *testing.T) {
	dns := NewBuilder().
		LD(Word, IMM, 20).
		LDX(Byte, MSH, 0).
		ADD(Index, 0).
		TAX().
		Label("lb_0").
		LD(Word, IND, 0).
		JEQ(Const, "", "lb_1", 0x07657861).
		LD(Word, IND, 4).
		JEQ(Const, "", "lb_1", 0x6d706c65).
		LD(Word, IND, 8).
		JEQ(Const, "", "lb_1", 0x03636f6d).
		LD(Byte, IND, 12).
		JEQ(Const, "", "lb_1", 0x00).
		RET(Const, 1).
		Label("lb_1").
		RET(Const, 0).
		Build()

	if dns.String() != test_dns {
		t.Fatalf("Program mismatch: %s", dns.String())
	}
}
<|endoftext|>


<commit_before>package rtda

import (
    "log"
    "jvmgo/any"
    rtc "jvmgo/jvm/rtda/class"
)

/*
JVM
  Thread
    pc
    Stack
      Frame
        LocalVars
        OperandStack
*/
type Thread struct {
    pc      int
    stack   *Stack
    jThread *rtc.Obj // java.lang.Thread
    // todo
}

func NewThread(maxStackSize uint, jThread *rtc.Obj) (*Thread) {
    stack := newStack(maxStackSize)
    return &Thread{0, stack, jThread}
}

// getters & setters
func (self *Thread) PC() (int) {
    return self.pc
}
func (self *Thread) SetPC(pc int) {
    self.pc = pc
}
func (self *Thread) JThread() (*rtc.Obj) {
    return self.jThread
}
func (self *Thread) SetJThread(jThread *rtc.Obj) {
    self.jThread = jThread
}

func (self *Thread) IsStackEmpty() (bool) {
    return self.stack.isEmpty()
}

func (self *Thread) CurrentFrame() (*Frame) {
    return self.stack.top()
}
func (self *Thread) TopFrame() (*Frame) {
    return self.stack.top()
}
func (self *Thread) TopNFrame(n uint) (*Frame) {
    return self.stack.topN(n)
}

func (self *Thread) PushFrame(frame *Frame) {
    self.stack.push(frame)
}
func (self *Thread) PopFrame() (*Frame) {
    top := self.stack.pop()
    if top.onPopAction != nil {
        // todo
        top.onPopAction()
    }
    return top
}

func (self *Thread) InvokeMethod(method * rtc.Method) {
    //_logInvoke(self.stack.size, method)
    currentFrame := self.CurrentFrame()
    newFrame := self.NewFrame(method)
    self.PushFrame(newFrame)
    _passArgs(currentFrame.operandStack, newFrame.localVars, method.ActualArgCount())
}
func _passArgs(stack *OperandStack, vars *LocalVars, argCount uint) {
    if argCount > 0 {
        args := stack.popN(argCount)
        for i, j := uint(0), uint(0); i < argCount; i++ {
            arg := args[i]
            args[i] = nil
            vars.Set(i + j, arg)
            if any.IsLongOrDouble(arg) {
                j++
            }
        }
    }
}
func _logInvoke(stackSize uint, method * rtc.Method) {
    if method.IsStatic() {
        log.Printf("invoke method: #%v %v.%v()", stackSize, method.Class().Name(), method.Name())
    } else {
        log.Printf("invoke method: #%v %v#%v()", stackSize, method.Class().Name(), method.Name())
    }
}

// args not passed!
func (self *Thread) InvokeMethod2(method * rtc.Method) (*LocalVars) {
    //_logInvoke(self.stack.size, method)
    if !method.IsVoidReturnType() {
        // insert a garbage frame
        garbageMethod := rtc.NewGarbageMethod()
        garbageFrame := self.NewFrame(garbageMethod)
        self.PushFrame(garbageFrame)
    }

    newFrame := self.NewFrame(method)
    self.PushFrame(newFrame)
    return newFrame.localVars
}

func (self *Thread) NewFrame(method *rtc.Method) (*Frame) {
    return newFrame(self, method)
}
<commit_msg>log method invocation<commit_after>package rtda

import (
    "log"
    "strings"
    "jvmgo/any"
    rtc "jvmgo/jvm/rtda/class"
)

/*
JVM
  Thread
    pc
    Stack
      Frame
        LocalVars
        OperandStack
*/
type Thread struct {
    pc      int
    stack   *Stack
    jThread *rtc.Obj // java.lang.Thread
    // todo
}

func NewThread(maxStackSize uint, jThread *rtc.Obj) (*Thread) {
    stack := newStack(maxStackSize)
    return &Thread{0, stack, jThread}
}

// getters & setters
func (self *Thread) PC() (int) {
    return self.pc
}
func (self *Thread) SetPC(pc int) {
    self.pc = pc
}
func (self *Thread) JThread() (*rtc.Obj) {
    return self.jThread
}
func (self *Thread) SetJThread(jThread *rtc.Obj) {
    self.jThread = jThread
}

func (self *Thread) IsStackEmpty() (bool) {
    return self.stack.isEmpty()
}

func (self *Thread) CurrentFrame() (*Frame) {
    return self.stack.top()
}
func (self *Thread) TopFrame() (*Frame) {
    return self.stack.top()
}
func (self *Thread) TopNFrame(n uint) (*Frame) {
    return self.stack.topN(n)
}

func (self *Thread) PushFrame(frame *Frame) {
    self.stack.push(frame)
}
func (self *Thread) PopFrame() (*Frame) {
    top := self.stack.pop()
    if top.onPopAction != nil {
        // todo
        top.onPopAction()
    }
    return top
}

func (self *Thread) InvokeMethod(method * rtc.Method) {
    //_logInvoke(self.stack.size, method)
    currentFrame := self.CurrentFrame()
    newFrame := self.NewFrame(method)
    self.PushFrame(newFrame)
    _passArgs(currentFrame.operandStack, newFrame.localVars, method.ActualArgCount())
}
func _passArgs(stack *OperandStack, vars *LocalVars, argCount uint) {
    if argCount > 0 {
        args := stack.popN(argCount)
        for i, j := uint(0), uint(0); i < argCount; i++ {
            arg := args[i]
            args[i] = nil
            vars.Set(i + j, arg)
            if any.IsLongOrDouble(arg) {
                j++
            }
        }
    }
}
func _logInvoke(stackSize uint, method * rtc.Method) {
    space := strings.Repeat(" ", int(stackSize))
    if method.IsStatic() {
        log.Printf("invoke method:%v %v.%v()", space, method.Class().Name(), method.Name())
    } else {
        log.Printf("invoke method:%v %v#%v()", space, method.Class().Name(), method.Name())
    }
}

// args not passed!
func (self *Thread) InvokeMethod2(method * rtc.Method) (*LocalVars) {
    //_logInvoke(self.stack.size, method)
    if !method.IsVoidReturnType() {
        // insert a garbage frame
        garbageMethod := rtc.NewGarbageMethod()
        garbageFrame := self.NewFrame(garbageMethod)
        self.PushFrame(garbageFrame)
    }

    newFrame := self.NewFrame(method)
    self.PushFrame(newFrame)
    return newFrame.localVars
}

func (self *Thread) NewFrame(method *rtc.Method) (*Frame) {
    return newFrame(self, method)
}
<|endoftext|>


<commit_before>package redis

import (
	"strings"
)

func (r *Redis) BgRewriteAOF() error {
	if err := r.send_command("BGREWRITEAOF"); err != nil {
		return err
	}
	if err := r.ok_reply(); err != nil {
		return err
	}
	return nil
}

func (r *Redis) BgSave() error {
	if err := r.send_command("BGSAVE"); err != nil {
		return err
	}
	if err := r.ok_reply(); err != nil {
		return err
	}
	return nil
}

func (r *Redis) ClientGetName() (*string, error) {
	if err := r.send_command("CLIENT", "GETNAME"); err != nil {
		return nil, err
	}
	if bulk, err := r.bulk_reply(); err != nil {
		return nil, err
	} else {
		return bulk, nil
	}
}

func (r *Redis) ClientKill(ip, port string) error {
	if err := r.send_command("CLIENT", "KILL", ip+":"+port); err != nil {
		return err
	}
	if err := r.ok_reply(); err != nil {
		return err
	}
	return nil
}

func (r *Redis) ClientList() ([]map[string]string, error) {
	clients := []map[string]string{}
	if err := r.send_command("CLIENT", "LIST"); err != nil {
		return clients, err
	}
	bulk, err := r.bulk_reply()
	if err != nil {
		return clients, err
	}
	if bulk == nil {
		return clients, NilBulkError
	}
	delim := string([]byte{LF})
	for _, line := range strings.Split(strings.Trim(*bulk, delim), delim) {
		m := make(map[string]string)
		for _, field := range strings.Fields(line) {
			sr := strings.Split(field, "=")
			m[sr[0]] = sr[1]
		}
		clients = append(clients, m)
	}
	return clients, nil
}

func (r *Redis) ClientSetName(name string) error {
	if err := r.send_command("CLIENT", "SETNAME", name); err != nil {
		return err
	}
	if err := r.ok_reply(); err != nil {
		return err
	}
	return nil
}

func (r *Redis) ConfigGet(pattern string) (*string, error) {
	if err := r.send_command("CONFIG", "GET", pattern); err != nil {
		return nil, err
	}
	return r.bulk_reply()
}
<commit_msg>simple return ok reply<commit_after>package redis

import (
	"strings"
)

func (r *Redis) BgRewriteAOF() error {
	if err := r.send_command("BGREWRITEAOF"); err != nil {
		return err
	}
	return r.ok_reply()
}

func (r *Redis) BgSave() error {
	if err := r.send_command("BGSAVE"); err != nil {
		return err
	}
	return r.ok_reply()
}

func (r *Redis) ClientGetName() (*string, error) {
	if err := r.send_command("CLIENT", "GETNAME"); err != nil {
		return nil, err
	}
	if bulk, err := r.bulk_reply(); err != nil {
		return nil, err
	} else {
		return bulk, nil
	}
}

func (r *Redis) ClientKill(ip, port string) error {
	if err := r.send_command("CLIENT", "KILL", ip+":"+port); err != nil {
		return err
	}
	return r.ok_reply()
}

func (r *Redis) ClientList() ([]map[string]string, error) {
	clients := []map[string]string{}
	if err := r.send_command("CLIENT", "LIST"); err != nil {
		return clients, err
	}
	bulk, err := r.bulk_reply()
	if err != nil {
		return clients, err
	}
	if bulk == nil {
		return clients, NilBulkError
	}
	delim := string([]byte{LF})
	for _, line := range strings.Split(strings.Trim(*bulk, delim), delim) {
		m := make(map[string]string)
		for _, field := range strings.Fields(line) {
			sr := strings.Split(field, "=")
			m[sr[0]] = sr[1]
		}
		clients = append(clients, m)
	}
	return clients, nil
}

func (r *Redis) ClientSetName(name string) error {
	if err := r.send_command("CLIENT", "SETNAME", name); err != nil {
		return err
	}
	return r.ok_reply()
}

func (r *Redis) ConfigGet(pattern string) (*string, error) {
	if err := r.send_command("CONFIG", "GET", pattern); err != nil {
		return nil, err
	}
	return r.bulk_reply()
}

func (r *Redis) ConfigResetStat() error {
	if err := r.send_command("CONFIG", "RESETSTAT"); err != nil {
		return err
	}
	return r.ok_reply()
}
<|endoftext|>


<commit_before>package k8s

import (
	"context"

	"github.com/kyma-project/kyma/components/console-backend-service/internal/authn"
	"github.com/kyma-project/kyma/components/console-backend-service/internal/domain/k8s/pretty"
	"github.com/kyma-project/kyma/components/console-backend-service/internal/gqlerror"
	authv1 "k8s.io/api/authorization/v1"
	v1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
)

type selfSubjectRulesService struct {
	client v1.AuthorizationV1Interface
}

func newSelfSubjectRulesService(client v1.AuthorizationV1Interface) *selfSubjectRulesService {
	return &selfSubjectRulesService{
		client: client,
	}
}

func (svc *selfSubjectRulesService) Create(ctx context.Context, ssrr []byte) (result *authv1.SelfSubjectRulesReview, err error) {
	if ssrr == nil {
		err := gqlerror.New(err, pretty.SelfSubjectRules)
		return &authv1.SelfSubjectRulesReview{}, err
	}
	u, err := authn.UserInfoForContext(ctx)
	username := u.GetName()
	result = &authv1.SelfSubjectRulesReview{}
	err = svc.client.RESTClient().Post().
		AbsPath("/apis/authorization.k8s.io/v1").
		Resource("selfsubjectrulesreviews").
		SetHeader("Impersonate-User", username).
		Body(ssrr).
		Do().
		Into(result)
	return
}
<commit_msg>Impersonate groups selfsubjectrules (#3952)<commit_after>package k8s

import (
	"context"

	"github.com/kyma-project/kyma/components/console-backend-service/internal/authn"
	"github.com/kyma-project/kyma/components/console-backend-service/internal/domain/k8s/pretty"
	"github.com/kyma-project/kyma/components/console-backend-service/internal/gqlerror"
	authv1 "k8s.io/api/authorization/v1"
	v1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
)

type selfSubjectRulesService struct {
	client v1.AuthorizationV1Interface
}

func newSelfSubjectRulesService(client v1.AuthorizationV1Interface) *selfSubjectRulesService {
	return &selfSubjectRulesService{
		client: client,
	}
}

func (svc *selfSubjectRulesService) Create(ctx context.Context, ssrr []byte) (result *authv1.SelfSubjectRulesReview, err error) {
	if ssrr == nil {
		err := gqlerror.New(err, pretty.SelfSubjectRules)
		return &authv1.SelfSubjectRulesReview{}, err
	}
	u, err := authn.UserInfoForContext(ctx)
	username := u.GetName()
	result = &authv1.SelfSubjectRulesReview{}
	err = svc.client.RESTClient().Post().
		AbsPath("/apis/authorization.k8s.io/v1").
		Resource("selfsubjectrulesreviews").
		SetHeader("Impersonate-User", username).
		SetHeader("Impersonate-Group", u.GetGroups()...).
		Body(ssrr).
		Do().
		Into(result)
	return
}
<|endoftext|>


<commit_before>package auth

import (
	"net/http"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestAuth0ManagerAuthenticate_ValidCreds(t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "POST")
		assert.Equal(t, r.URL.Path, "/oauth/ro")

		var req oauthReq
		Unmarshal(t, r, &req)

		assert.Equal(t, req.Username, "valid username")
		assert.Equal(t, req.Password, "valid password")

		MarshalAndWrite(t, w, nil, 200)
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	valid, err := auth0Manager.Authenticate("valid username", "valid password")
	if err != nil {
		t.Fatal(err)
	}

	assert.Equal(t, valid, true)
}

func TestAuth0ManagerAuthenticate_InvalidCreds(t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "POST")
		assert.Equal(t, r.URL.Path, "/oauth/ro")

		var req oauthReq
		Unmarshal(t, r, &req)

		assert.Equal(t, req.Username, "valid username")
		assert.Equal(t, req.Password, "invalid password")

		MarshalAndWrite(t, w, nil, 401)
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	valid, err := auth0Manager.Authenticate("valid username", "invalid password")
	if err != nil {
		t.Fatal(err)
	}

	assert.Equal(t, valid, false)
}

func TestAuth0ManagerAuthenticate_ValidCredsAreCached(t *testing.T) {
	count := 0

	handler := func(w http.ResponseWriter, r *http.Request) {
		MarshalAndWrite(t, w, nil, 200)
		count++
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	for i := 0; i < 2; i++ {
		valid, err := auth0Manager.Authenticate("valid username", "valid password")
		if err != nil {
			t.Fatal(err)
		}

		assert.Equal(t, valid, true)
	}

	assert.Equal(t, count, 1)
}

func TestAuth0ManagerAuthenticate_NotValidCredsAreChecked(t *testing.T) {
	timeMultiplier = 0
	count := 0

	handler := func(w http.ResponseWriter, r *http.Request) {
		if count == 0 {
			MarshalAndWrite(t, w, nil, 401)
		} else {
			MarshalAndWrite(t, w, nil, 200)
		}

		count++
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	for i, expected := range []bool{false, true} {
		valid, err := auth0Manager.Authenticate("username", "password")
		if err != nil {
			t.Fatal(err)
		}

		if valid != expected {
			t.Errorf("Error on iteration %d: result was %t, expected %t", i, valid, expected)
		}
	}

	assert.Equal(t, count, 2)
}
<commit_msg>test Auth0Manager retries on 429s<commit_after>package auth

import (
	"net/http"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestAuth0ManagerAuthenticate_ValidCreds(t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "POST")
		assert.Equal(t, r.URL.Path, "/oauth/ro")

		var req oauthReq
		Unmarshal(t, r, &req)

		assert.Equal(t, req.Username, "valid username")
		assert.Equal(t, req.Password, "valid password")

		MarshalAndWrite(t, w, nil, 200)
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	valid, err := auth0Manager.Authenticate("valid username", "valid password")
	if err != nil {
		t.Fatal(err)
	}

	assert.Equal(t, valid, true)
}

func TestAuth0ManagerAuthenticate_InvalidCreds(t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "POST")
		assert.Equal(t, r.URL.Path, "/oauth/ro")

		var req oauthReq
		Unmarshal(t, r, &req)

		assert.Equal(t, req.Username, "valid username")
		assert.Equal(t, req.Password, "invalid password")

		MarshalAndWrite(t, w, nil, 401)
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	valid, err := auth0Manager.Authenticate("valid username", "invalid password")
	if err != nil {
		t.Fatal(err)
	}

	assert.Equal(t, valid, false)
}

func TestAuth0ManagerAuthenticate_ValidCredsAreCached(t *testing.T) {
	count := 0

	handler := func(w http.ResponseWriter, r *http.Request) {
		MarshalAndWrite(t, w, nil, 200)
		count++
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	for i := 0; i < 2; i++ {
		valid, err := auth0Manager.Authenticate("valid username", "valid password")
		if err != nil {
			t.Fatal(err)
		}

		assert.Equal(t, valid, true)
	}

	assert.Equal(t, count, 1)
}

func TestAuth0ManagerAuthenticate_NotValidCredsAreChecked(t *testing.T) {
	timeMultiplier = 0
	count := 0

	handler := func(w http.ResponseWriter, r *http.Request) {
		if count == 0 {
			MarshalAndWrite(t, w, nil, 401)
		} else {
			MarshalAndWrite(t, w, nil, 200)
		}

		count++
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	for i, expected := range []bool{false, true} {
		valid, err := auth0Manager.Authenticate("username", "password")
		if err != nil {
			t.Fatal(err)
		}

		if valid != expected {
			t.Errorf("Error on iteration %d: result was %t, expected %t", i, valid, expected)
		}
	}

	assert.Equal(t, count, 2)
}

func TestAuth0ManagerAuthenticate_RetriesOn429(t *testing.T) {
	count := 0

	handler := func(w http.ResponseWriter, r *http.Request) {
		if count < 2 {
			MarshalAndWrite(t, w, nil, 429)
		} else {
			MarshalAndWrite(t, w, nil, 200)
		}

		count++
	}

	auth0Manager, server := newAuth0ManagerAndServer(handler)
	defer server.Close()

	_, err := auth0Manager.Authenticate("", "")
	if err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/md5"
	"flag"
	"fmt"
	"github.com/labstack/echo"
	"github.com/labstack/gommon/log"
	"gopkg.in/yaml.v2"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"time"
)

type CustomContext struct {
	echo.Context
	conf Configuration
}

type Created struct {
	Id string
}

type Configuration struct {
	Server struct {
		Port int
	}
	Storage struct {
		Directory string
	}
}

func get(c echo.Context) error {
	cc := c.(*CustomContext)

	file, err := os.Open(path.Join(cc.conf.Storage.Directory, c.Param("id")))
	if err != nil {
		log.Error(err)
		return err
	}
	data, err := ioutil.ReadAll(file)
	if err != nil {
		log.Error(err)
		return err
	}
	mimeType := http.DetectContentType(data)
	return c.Blob(http.StatusOK, mimeType, data)
}

func post(c echo.Context) error {
	cc := c.(*CustomContext)

	photo, err := c.FormFile("photo")
	if err != nil {
		log.Error(err)
		return err
	}
	src, err := photo.Open()
	if err != nil {
		log.Error(err)
		return err
	}
	defer src.Close()

	data, err := ioutil.ReadAll(src)
	if err != nil {
		log.Error(err)
		return err
	}

	dataHash := fmt.Sprintf("%x", md5.Sum(data))
	filename := fmt.Sprintf("%x", md5.Sum([]byte(dataHash+time.Now().String())))
	dst, err := os.Create(path.Join(cc.conf.Storage.Directory, filename))
	if err != nil {
		log.Error(err)
		return err
	}
	defer dst.Close()

	if _, err := dst.Write(data); err != nil {
		log.Error(err)
		return err
	}

	return c.JSON(http.StatusCreated, Created{filename})
}

func put(c echo.Context) error {
	cc := c.(*CustomContext)

	photo, err := c.FormFile("photo")
	if err != nil {
		log.Error(err)
		return err
	}
	src, err := photo.Open()
	if err != nil {
		log.Error(err)
		return err
	}
	defer src.Close()

	dst, err := os.Create(path.Join(cc.conf.Storage.Directory, c.Param("id")))
	if err != nil {
		log.Error(err)
		return err
	}
	defer dst.Close()

	if _, err = io.Copy(dst, src); err != nil {
		log.Error(err)
		return err
	}

	return c.NoContent(http.StatusOK)
}

func delete(c echo.Context) error {
	cc := c.(*CustomContext)

	if err := os.Remove(path.Join(cc.conf.Storage.Directory, c.Param("id"))); err != nil {
		log.Error(err)
		return err
	}

	return c.NoContent(http.StatusOK)
}

func main() {
	configurationFile, err := ioutil.ReadFile("./application.yml")
	if err != nil {
		log.Warn(err)
	}

	configuration := Configuration{}
	if err := yaml.Unmarshal(configurationFile, &configuration); err != nil {
		log.Fatal(err)
		return
	}

	port := flag.Int("port", configuration.Server.Port, "port number")
	flag.Parse()

	e := echo.New()

	e.Use(func(h echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			cc := &CustomContext{c, configuration}
			return h(cc)
		}
	})

	e.GET("/:id", get)
	e.POST("/", post)
	e.PUT("/:id", put)
	e.DELETE("/:id", delete)

	address := fmt.Sprintf(":%d", *port)
	e.Logger.Debug(e.Start(address))
}
<commit_msg>Add list method<commit_after>package main

import (
	"crypto/md5"
	"flag"
	"fmt"
	"github.com/labstack/echo"
	"github.com/labstack/gommon/log"
	"gopkg.in/yaml.v2"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"time"
)

type CustomContext struct {
	echo.Context
	conf Configuration
}

type Created struct {
	Id string
}

type PhotoList struct {
	 Ids []string
}

type Configuration struct {
	Server struct {
		Port int
	}
	Storage struct {
		Directory string
	}
}

func get(c echo.Context) error {
	cc := c.(*CustomContext)

	file, err := os.Open(path.Join(cc.conf.Storage.Directory, c.Param("id")))
	if err != nil {
		log.Error(err)
		return err
	}
	data, err := ioutil.ReadAll(file)
	if err != nil {
		log.Error(err)
		return err
	}
	mimeType := http.DetectContentType(data)
	return c.Blob(http.StatusOK, mimeType, data)
}

func list(c echo.Context) error {
	cc := c.(*CustomContext)

	files, err := ioutil.ReadDir(cc.conf.Storage.Directory)
	if err != nil {
		log.Error(err)
		return err
	}
	names := []string{}
	for _, file := range files {
		names = append(names, file.Name())
	}

	return c.JSON(http.StatusOK, PhotoList{names})
}

func post(c echo.Context) error {
	cc := c.(*CustomContext)

	photo, err := c.FormFile("photo")
	if err != nil {
		log.Error(err)
		return err
	}
	src, err := photo.Open()
	if err != nil {
		log.Error(err)
		return err
	}
	defer src.Close()

	data, err := ioutil.ReadAll(src)
	if err != nil {
		log.Error(err)
		return err
	}

	dataHash := fmt.Sprintf("%x", md5.Sum(data))
	filename := fmt.Sprintf("%x", md5.Sum([]byte(dataHash+time.Now().String())))
	dst, err := os.Create(path.Join(cc.conf.Storage.Directory, filename))
	if err != nil {
		log.Error(err)
		return err
	}
	defer dst.Close()

	if _, err := dst.Write(data); err != nil {
		log.Error(err)
		return err
	}

	return c.JSON(http.StatusCreated, Created{filename})
}

func put(c echo.Context) error {
	cc := c.(*CustomContext)

	photo, err := c.FormFile("photo")
	if err != nil {
		log.Error(err)
		return err
	}
	src, err := photo.Open()
	if err != nil {
		log.Error(err)
		return err
	}
	defer src.Close()

	dst, err := os.Create(path.Join(cc.conf.Storage.Directory, c.Param("id")))
	if err != nil {
		log.Error(err)
		return err
	}
	defer dst.Close()

	if _, err = io.Copy(dst, src); err != nil {
		log.Error(err)
		return err
	}

	return c.NoContent(http.StatusOK)
}

func delete(c echo.Context) error {
	cc := c.(*CustomContext)

	if err := os.Remove(path.Join(cc.conf.Storage.Directory, c.Param("id"))); err != nil {
		log.Error(err)
		return err
	}

	return c.NoContent(http.StatusOK)
}

func main() {
	configurationFile, err := ioutil.ReadFile("./application.yml")
	if err != nil {
		log.Warn(err)
	}

	configuration := Configuration{}
	if err := yaml.Unmarshal(configurationFile, &configuration); err != nil {
		log.Fatal(err)
		return
	}

	port := flag.Int("port", configuration.Server.Port, "port number")
	flag.Parse()

	e := echo.New()

	e.Use(func(h echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			cc := &CustomContext{c, configuration}
			return h(cc)
		}
	})

	e.GET("/:id", get)
	e.GET("/", list)
	e.POST("/", post)
	e.PUT("/:id", put)
	e.DELETE("/:id", delete)

	address := fmt.Sprintf(":%d", *port)
	e.Logger.Debug(e.Start(address))
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"os/signal"
	"context"
	"syscall"
	"net/http"
	"github.com/gorilla/mux"
	"encoding/json"
	"fmt"
	"sync"
)

var roomIds = []string{
	"kougi201",
	"kougi202",
	"kougi203",
	"kougi204",

	"kougi301",
	"kougi302",
	"kougi303",
	"kougi304",
}

type Status struct {
	Templature float32 `json:"templature"`
	Hot        uint    `json:"hot"`
	Cold       uint    `json:"cold"`
	lock       sync.RWMutex
}

func getRouter() *mux.Router {
	cwd, _ := os.Getwd()
	docroot := http.Dir(cwd + "/static")
	statMap := make(map[string]*Status)
	for id := range roomIds {
		statMap[roomIds[id]] = &Status{
			Templature: 30.0,
			Hot: 0,
			Cold: 0,
			lock: sync.RWMutex{},
		}
	}

	router := mux.NewRouter()
	router.HandleFunc("/api/v1/status", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Cache-Control", "no-store")

		roomId := req.URL.Query().Get("room")
		stat := statMap[roomId]
		if stat == nil {
			w.WriteHeader(500)
			return
		}
		stat.lock.RLock()
		defer stat.lock.RUnlock()

		js, err := json.Marshal(*stat)
		if err != nil {
			w.WriteHeader(500)
			return
		}

		w.WriteHeader(200)
		w.Write(js)
	}).Methods("GET")
	router.HandleFunc("/api/v1/status", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Cache-Control", "no-store")

		roomId := req.URL.Query().Get("room")
		stat := statMap[roomId]
		if stat == nil {
			w.WriteHeader(500)
			return
		}
		stat.lock.Lock()
		defer stat.lock.Unlock()

		switch req.FormValue("vote"){
		case "hot":
			stat.Hot++
		case "cold":
			stat.Cold++
		default:
			w.WriteHeader(400)
			return
		}

		w.WriteHeader(200)
		js, err := json.Marshal(*stat)
		if err != nil {
			w.WriteHeader(500)
			return
		}
		w.Write(js)
	}).Methods("POST")
	router.Handle(`/`, http.FileServer(docroot)).Methods("GET")
	router.Handle(`/{name:.*}`, http.FileServer(docroot)).Methods("GET")

	return router
}

func startHttpServer(ctx context.Context, router *mux.Router) (err error) {
	srv := http.Server{
		Addr: "0.0.0.0:8080",
		Handler: router,
	}
	go func() {
		<-ctx.Done()
		srv.Shutdown(ctx)
	}()
	fmt.Println("start server")
	srv.ListenAndServe()
	return
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
	go func() {
		<-sig
		fmt.Println("signal handled")
		cancel()
	}()

	router := getRouter()
	if err := startHttpServer(ctx, router); err != nil {
		panic(err)
	}
}<commit_msg>rename Status to RoomStatus<commit_after>package main

import (
	"os"
	"os/signal"
	"context"
	"syscall"
	"net/http"
	"github.com/gorilla/mux"
	"encoding/json"
	"fmt"
	"sync"
)

var roomIds = []string{
	"kougi201",
	"kougi202",
	"kougi203",
	"kougi204",

	"kougi301",
	"kougi302",
	"kougi303",
	"kougi304",
}

type RoomStatus struct {
	Templature float32 `json:"templature"`
	Hot        uint    `json:"hot"`
	Cold       uint    `json:"cold"`
	lock       sync.RWMutex
}

func getRouter() *mux.Router {
	cwd, _ := os.Getwd()
	docroot := http.Dir(cwd + "/static")
	statMap := make(map[string]*RoomStatus)
	for id := range roomIds {
		statMap[roomIds[id]] = &RoomStatus{
			Templature: 30.0,
			Hot: 0,
			Cold: 0,
			lock: sync.RWMutex{},
		}
	}

	router := mux.NewRouter()
	router.HandleFunc("/api/v1/status", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Cache-Control", "no-store")

		roomId := req.URL.Query().Get("room")
		stat := statMap[roomId]
		if stat == nil {
			w.WriteHeader(500)
			return
		}
		stat.lock.RLock()
		defer stat.lock.RUnlock()

		js, err := json.Marshal(*stat)
		if err != nil {
			w.WriteHeader(500)
			return
		}

		w.WriteHeader(200)
		w.Write(js)
	}).Methods("GET")
	router.HandleFunc("/api/v1/status", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Cache-Control", "no-store")

		roomId := req.URL.Query().Get("room")
		stat := statMap[roomId]
		if stat == nil {
			w.WriteHeader(500)
			return
		}
		stat.lock.Lock()
		defer stat.lock.Unlock()

		switch req.FormValue("vote"){
		case "hot":
			stat.Hot++
		case "cold":
			stat.Cold++
		default:
			w.WriteHeader(400)
			return
		}

		w.WriteHeader(200)
		js, err := json.Marshal(*stat)
		if err != nil {
			w.WriteHeader(500)
			return
		}
		w.Write(js)
	}).Methods("POST")
	router.Handle(`/`, http.FileServer(docroot)).Methods("GET")
	router.Handle(`/{name:.*}`, http.FileServer(docroot)).Methods("GET")

	return router
}

func startHttpServer(ctx context.Context, router *mux.Router) (err error) {
	srv := http.Server{
		Addr: "0.0.0.0:8080",
		Handler: router,
	}
	go func() {
		<-ctx.Done()
		srv.Shutdown(ctx)
	}()
	fmt.Println("start server")
	srv.ListenAndServe()
	return
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
	go func() {
		<-sig
		fmt.Println("signal handled")
		cancel()
	}()

	router := getRouter()
	if err := startHttpServer(ctx, router); err != nil {
		panic(err)
	}
}<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"strings"
	"sync"
	"time"

	"github.com/hashicorp/memberlist"
	"github.com/relistan/go-director"
	"github.com/newrelic/bosun/discovery"
	"github.com/newrelic/bosun/haproxy"
	"github.com/newrelic/bosun/services_state"
)

func updateMetaData(list *memberlist.Memberlist, metaUpdates chan []byte) {
	for {
		list.LocalNode().Meta = <-metaUpdates // Blocking
		fmt.Printf("Got update: %s\n", string(list.LocalNode().Meta))
		err := list.UpdateNode(10 * time.Second)
		if err != nil {
			fmt.Printf("Error pushing node update!")
		}
	}
}

func announceMembers(list *memberlist.Memberlist, state *services_state.ServicesState) {
	for {
		// Ask for members of the cluster
		for _, member := range list.Members() {
			fmt.Printf("Member: %s %s\n", member.Name, member.Addr)
			fmt.Printf("  Meta:\n    %s\n", string(member.Meta))
		}

		state.Print(list)

		time.Sleep(2 * time.Second)
	}
}

func configureHAproxy(config Config) *haproxy.HAproxy {
	proxy := haproxy.New()
	if len(config.HAproxy.BindIP) > 0 {
		proxy.BindIP = config.HAproxy.BindIP
	}

	if len(config.HAproxy.ReloadCmd) > 0 {
		proxy.ReloadCmd = config.HAproxy.ReloadCmd
	}

	if len(config.HAproxy.VerifyCmd) > 0 {
		proxy.VerifyCmd = config.HAproxy.VerifyCmd
	}

	if len(config.HAproxy.TemplateFile) > 0 {
		proxy.Template = config.HAproxy.TemplateFile
	}

	if len(config.HAproxy.ConfigFile) > 0 {
		proxy.ConfigFile = config.HAproxy.ConfigFile
	}

	return proxy
}

func main() {
	opts := parseCommandLine()
	state := services_state.NewServicesState()
	delegate := NewServicesDelegate(state)

	config := parseConfig("bosun.toml")
	state.ServiceNameMatch = config.Services.NameRegexp

	// Use a LAN config but add our delegate
	mlConfig := memberlist.DefaultLANConfig()
	mlConfig.Delegate = delegate
	mlConfig.Events = delegate

	publishedIP, err := getPublishedIP(config.Bosun.ExcludeIPs)
	exitWithError(err, "Failed to find private IP address")
	mlConfig.AdvertiseAddr = publishedIP

	log.Println("Bosun starting -------------------")
	log.Printf("Cluster Seeds: %s\n", strings.Join(*opts.ClusterIPs, ", "))
	log.Printf("Advertised address: %s\n", publishedIP)
	log.Printf("Service Name Match: %s\n", config.Services.NameMatch)
	log.Printf("Excluded IPs: %v\n", config.Bosun.ExcludeIPs)
	log.Println("----------------------------------")

	list, err := memberlist.Create(mlConfig)
	exitWithError(err, "Failed to create memberlist")

	// Join an existing cluster by specifying at least one known member.
	_, err = list.Join(*opts.ClusterIPs)
	exitWithError(err, "Failed to join cluster")

	metaUpdates := make(chan []byte)
	var wg sync.WaitGroup
	wg.Add(1)

	quitDiscovery := make(chan bool)
	servicesLooper := director.NewTimedLooper(
		director.FOREVER, services_state.ALIVE_SLEEP_INTERVAL, nil,
	)
	tombstoneLooper := director.NewTimedLooper(
		director.FOREVER, services_state.TOMBSTONE_SLEEP_INTERVAL, nil,
	)

	disco := new(discovery.MultiDiscovery)

	for _, method := range config.Bosun.Discovery {
		switch method {
		case "docker":
			disco.Discoverers = append(
				disco.Discoverers, discovery.NewDockerDiscovery("tcp://localhost:2375"),
			)
		default:
		}
	}

	disco.Run(quitDiscovery)

	go announceMembers(list, state)
	go state.BroadcastServices(disco.Services, servicesLooper)
	go state.BroadcastTombstones(disco.Services, tombstoneLooper)
	go updateMetaData(list, metaUpdates)

	if !config.HAproxy.Disable {
		proxy := configureHAproxy(config)
		go proxy.Watch(state)
	}

	serveHttp(list, state)

	time.Sleep(4 * time.Second)
	metaUpdates <- []byte("A message!")

	wg.Wait() // forever... nothing will decrement the wg
}
<commit_msg>Define an ImportComment to work with go-wrapper<commit_after>package main // import "github.com/newrelic/bosun"

import (
	"fmt"
	"log"
	"strings"
	"sync"
	"time"

	"github.com/hashicorp/memberlist"
	"github.com/relistan/go-director"
	"github.com/newrelic/bosun/discovery"
	"github.com/newrelic/bosun/haproxy"
	"github.com/newrelic/bosun/services_state"
)

func updateMetaData(list *memberlist.Memberlist, metaUpdates chan []byte) {
	for {
		list.LocalNode().Meta = <-metaUpdates // Blocking
		fmt.Printf("Got update: %s\n", string(list.LocalNode().Meta))
		err := list.UpdateNode(10 * time.Second)
		if err != nil {
			fmt.Printf("Error pushing node update!")
		}
	}
}

func announceMembers(list *memberlist.Memberlist, state *services_state.ServicesState) {
	for {
		// Ask for members of the cluster
		for _, member := range list.Members() {
			fmt.Printf("Member: %s %s\n", member.Name, member.Addr)
			fmt.Printf("  Meta:\n    %s\n", string(member.Meta))
		}

		state.Print(list)

		time.Sleep(2 * time.Second)
	}
}

func configureHAproxy(config Config) *haproxy.HAproxy {
	proxy := haproxy.New()
	if len(config.HAproxy.BindIP) > 0 {
		proxy.BindIP = config.HAproxy.BindIP
	}

	if len(config.HAproxy.ReloadCmd) > 0 {
		proxy.ReloadCmd = config.HAproxy.ReloadCmd
	}

	if len(config.HAproxy.VerifyCmd) > 0 {
		proxy.VerifyCmd = config.HAproxy.VerifyCmd
	}

	if len(config.HAproxy.TemplateFile) > 0 {
		proxy.Template = config.HAproxy.TemplateFile
	}

	if len(config.HAproxy.ConfigFile) > 0 {
		proxy.ConfigFile = config.HAproxy.ConfigFile
	}

	return proxy
}

func main() {
	opts := parseCommandLine()
	state := services_state.NewServicesState()
	delegate := NewServicesDelegate(state)

	config := parseConfig("bosun.toml")
	state.ServiceNameMatch = config.Services.NameRegexp

	// Use a LAN config but add our delegate
	mlConfig := memberlist.DefaultLANConfig()
	mlConfig.Delegate = delegate
	mlConfig.Events = delegate

	publishedIP, err := getPublishedIP(config.Bosun.ExcludeIPs)
	exitWithError(err, "Failed to find private IP address")
	mlConfig.AdvertiseAddr = publishedIP

	log.Println("Bosun starting -------------------")
	log.Printf("Cluster Seeds: %s\n", strings.Join(*opts.ClusterIPs, ", "))
	log.Printf("Advertised address: %s\n", publishedIP)
	log.Printf("Service Name Match: %s\n", config.Services.NameMatch)
	log.Printf("Excluded IPs: %v\n", config.Bosun.ExcludeIPs)
	log.Println("----------------------------------")

	list, err := memberlist.Create(mlConfig)
	exitWithError(err, "Failed to create memberlist")

	// Join an existing cluster by specifying at least one known member.
	_, err = list.Join(*opts.ClusterIPs)
	exitWithError(err, "Failed to join cluster")

	metaUpdates := make(chan []byte)
	var wg sync.WaitGroup
	wg.Add(1)

	quitDiscovery := make(chan bool)
	servicesLooper := director.NewTimedLooper(
		director.FOREVER, services_state.ALIVE_SLEEP_INTERVAL, nil,
	)
	tombstoneLooper := director.NewTimedLooper(
		director.FOREVER, services_state.TOMBSTONE_SLEEP_INTERVAL, nil,
	)

	disco := new(discovery.MultiDiscovery)

	for _, method := range config.Bosun.Discovery {
		switch method {
		case "docker":
			disco.Discoverers = append(
				disco.Discoverers, discovery.NewDockerDiscovery("tcp://localhost:2375"),
			)
		default:
		}
	}

	disco.Run(quitDiscovery)

	go announceMembers(list, state)
	go state.BroadcastServices(disco.Services, servicesLooper)
	go state.BroadcastTombstones(disco.Services, tombstoneLooper)
	go updateMetaData(list, metaUpdates)

	if !config.HAproxy.Disable {
		proxy := configureHAproxy(config)
		go proxy.Watch(state)
	}

	serveHttp(list, state)

	time.Sleep(4 * time.Second)
	metaUpdates <- []byte("A message!")

	wg.Wait() // forever... nothing will decrement the wg
}
<|endoftext|>


<commit_before>package authenticating

import (
	"encoding/json"
	"errors"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	fb "github.com/huandu/facebook"
	uuid "github.com/satori/go.uuid"
	"github.com/victorspringer/trapAdvisor/database"
	"github.com/victorspringer/trapAdvisor/friendship"
	"github.com/victorspringer/trapAdvisor/persistence"
	"github.com/victorspringer/trapAdvisor/traveller"
	"golang.org/x/oauth2"
)

func (s *service) HandleFacebookLogin(w http.ResponseWriter, r *http.Request) {
	u, err := url.Parse(s.config.Endpoint.AuthURL)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	parameters := url.Values{}
	parameters.Add("client_id", s.config.ClientID)
	parameters.Add("scope", strings.Join(s.config.Scopes, " "))
	parameters.Add("redirect_uri", s.config.RedirectURL)
	parameters.Add("response_type", "code")
	parameters.Add("state", s.state)

	u.RawQuery = parameters.Encode()
	url := u.String()

	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

func (s *service) HandleFacebookCallback(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

	state := r.FormValue("state")
	if state != s.state {
		err := fmt.Errorf("invalid oauth state, expected '%v', got '%v'", s.state, state)
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	if r.FormValue("error") == "access_denied" {
		log.Println("user rejected the facebook app subscription")
		w.WriteHeader(http.StatusOK)

		const callback = `
			<html>
				<script>history.go(-2)</script>
			</html>
		`
		tmpl := template.New("callback")
		var err error
		if tmpl, err = tmpl.Parse(callback); err != nil {
			log.Println(err)
		}
		tmpl.Execute(os.Stdout, callback)
		return
	}

	code := r.FormValue("code")
	token, err := s.config.Exchange(oauth2.NoContext, code)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	client := s.config.Client(oauth2.NoContext, token)

	s.session = &fb.Session{
		Version:    "v2.9",
		HttpClient: client,
	}

	param := fb.Params{"access_token": url.QueryEscape(token.AccessToken)}

	trav, err := s.session.Get("/me", param)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	body, err := json.Marshal(trav)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	var t traveller.Traveller
	if err = json.Unmarshal(body, &t); err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusUnprocessableEntity)
		return
	}

	travRepo := persistence.NewTravellerRepository()

	_, err = travRepo.Find(0)
	if err != nil {
		if err.Error() == "Error 1046: No database selected" {
			database.DB.Close()
			database.DB, err = database.Init(os.Getenv("ENV"))
			if err != nil {
				log.Println(err)
			}
		} else if err.Error() != "sql: no rows in result set" {
			log.Println(err)
		}
	}

	firstLogin := false
	_, err = travRepo.Find(t.ID)
	if err != nil {
		firstLogin = true
	}

	t.SessionToken = fmt.Sprintf("%v", uuid.NewV4())

	if err = travRepo.Store(&t); err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	if firstLogin {
		friends, err := s.session.Get("/me/friends", fb.Params{"access_token": url.QueryEscape(token.AccessToken), "fields": "id"})
		if err != nil {
			log.Println(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		f := friendship.Friendship{}
		f.TravellerID = t.ID
		fRepo := persistence.NewFriendshipRepository()
		idx := 0
		for friends.Get(fmt.Sprintf("data.%v.id", idx)) != nil {
			id, ok := friends.Get(fmt.Sprintf("data.%v.id", idx)).(string)
			if !ok {
				err = errors.New("invalid user id")
				log.Println(err)
				w.WriteHeader(http.StatusInternalServerError)
				return
			}

			fID, err := strconv.Atoi(id)
			if err != nil {
				log.Println(err)
				w.WriteHeader(http.StatusInternalServerError)
				return
			}

			f.FriendID = fID

			if err = fRepo.Store(&f); err != nil {
				log.Println(err)
				w.WriteHeader(http.StatusInternalServerError)
				return
			}

			idx++
		}
	}

	expiration := time.Now().Add(30 * 24 * time.Hour)

	cookieTravellerID := http.Cookie{Name: "travellerID", Value: strconv.Itoa(t.ID), Path: "/", Expires: expiration}
	http.SetCookie(w, &cookieTravellerID)

	cookieSessionToken := http.Cookie{Name: "sessionToken", Value: t.SessionToken, Path: "/", Expires: expiration}
	http.SetCookie(w, &cookieSessionToken)

	w.WriteHeader(http.StatusOK)

	const callback = `
		<html>
			<script>history.back()</script>
		</html>
	`
	tmpl := template.New("callback")
	if tmpl, err = tmpl.Parse(callback); err != nil {
		log.Println(err)
	}
	tmpl.Execute(os.Stdout, callback)
}

func (s *service) HandleFacebookLogout(w http.ResponseWriter, r *http.Request) {
	cookies := []string{"travellerID", "sessionToken"}

	for _, c := range cookies {
		cookie, err := r.Cookie(c)
		if err != nil {
			log.Println(err)
			http.Error(w, http.StatusText(401), 401)
			return
		}

		cookie.Path = "/"
		cookie.MaxAge = -1
		http.SetCookie(w, cookie)
	}

	w.WriteHeader(http.StatusOK)
}

func (s *service) ValidateSession(id int, sessionToken string) error {
	repo := persistence.NewTravellerRepository()

	_, err := repo.Find(0)
	if err != nil {
		if err.Error() == "Error 1046: No database selected" {
			database.DB.Close()
			database.DB, err = database.Init(os.Getenv("ENV"))
			if err != nil {
				log.Println(err)
			}
		} else if err.Error() != "sql: no rows in result set" {
			log.Println(err)
		}
	}

	if err = repo.FindBySessionToken(id, sessionToken); err != nil {
		return err
	}

	return nil
}
<commit_msg>adds redirect on fb rejection callback<commit_after>package authenticating

import (
	"encoding/json"
	"errors"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	fb "github.com/huandu/facebook"
	uuid "github.com/satori/go.uuid"
	"github.com/victorspringer/trapAdvisor/database"
	"github.com/victorspringer/trapAdvisor/friendship"
	"github.com/victorspringer/trapAdvisor/persistence"
	"github.com/victorspringer/trapAdvisor/traveller"
	"golang.org/x/oauth2"
)

func (s *service) HandleFacebookLogin(w http.ResponseWriter, r *http.Request) {
	u, err := url.Parse(s.config.Endpoint.AuthURL)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	parameters := url.Values{}
	parameters.Add("client_id", s.config.ClientID)
	parameters.Add("scope", strings.Join(s.config.Scopes, " "))
	parameters.Add("redirect_uri", s.config.RedirectURL)
	parameters.Add("response_type", "code")
	parameters.Add("state", s.state)

	u.RawQuery = parameters.Encode()
	url := u.String()

	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

func (s *service) HandleFacebookCallback(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	state := r.FormValue("state")
	if state != s.state {
		err := fmt.Errorf("invalid oauth state, expected '%v', got '%v'", s.state, state)
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	if r.FormValue("error") == "access_denied" {
		log.Println("user rejected the facebook app subscription")
		w.WriteHeader(http.StatusOK)

		const callback = `
			<html>
				<script>history.go(-2)</script>
			</html>
		`
		tmpl := template.New("callback")
		var err error
		if tmpl, err = tmpl.Parse(callback); err != nil {
			log.Println(err)
		}
		tmpl.Execute(os.Stdout, callback)
		return
	}

	code := r.FormValue("code")
	token, err := s.config.Exchange(oauth2.NoContext, code)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	client := s.config.Client(oauth2.NoContext, token)

	s.session = &fb.Session{
		Version:    "v2.9",
		HttpClient: client,
	}

	param := fb.Params{"access_token": url.QueryEscape(token.AccessToken)}

	trav, err := s.session.Get("/me", param)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	body, err := json.Marshal(trav)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	var t traveller.Traveller
	if err = json.Unmarshal(body, &t); err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusUnprocessableEntity)
		return
	}

	travRepo := persistence.NewTravellerRepository()

	_, err = travRepo.Find(0)
	if err != nil {
		if err.Error() == "Error 1046: No database selected" {
			database.DB.Close()
			database.DB, err = database.Init(os.Getenv("ENV"))
			if err != nil {
				log.Println(err)
			}
		} else if err.Error() != "sql: no rows in result set" {
			log.Println(err)
		}
	}

	firstLogin := false
	_, err = travRepo.Find(t.ID)
	if err != nil {
		firstLogin = true
	}

	t.SessionToken = fmt.Sprintf("%v", uuid.NewV4())

	if err = travRepo.Store(&t); err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	if firstLogin {
		friends, err := s.session.Get("/me/friends", fb.Params{"access_token": url.QueryEscape(token.AccessToken), "fields": "id"})
		if err != nil {
			log.Println(err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		f := friendship.Friendship{}
		f.TravellerID = t.ID
		fRepo := persistence.NewFriendshipRepository()
		idx := 0
		for friends.Get(fmt.Sprintf("data.%v.id", idx)) != nil {
			id, ok := friends.Get(fmt.Sprintf("data.%v.id", idx)).(string)
			if !ok {
				err = errors.New("invalid user id")
				log.Println(err)
				w.WriteHeader(http.StatusInternalServerError)
				return
			}

			fID, err := strconv.Atoi(id)
			if err != nil {
				log.Println(err)
				w.WriteHeader(http.StatusInternalServerError)
				return
			}

			f.FriendID = fID

			if err = fRepo.Store(&f); err != nil {
				log.Println(err)
				w.WriteHeader(http.StatusInternalServerError)
				return
			}

			idx++
		}
	}

	expiration := time.Now().Add(30 * 24 * time.Hour)

	cookieTravellerID := http.Cookie{Name: "travellerID", Value: strconv.Itoa(t.ID), Path: "/", Expires: expiration}
	http.SetCookie(w, &cookieTravellerID)

	cookieSessionToken := http.Cookie{Name: "sessionToken", Value: t.SessionToken, Path: "/", Expires: expiration}
	http.SetCookie(w, &cookieSessionToken)

	w.WriteHeader(http.StatusOK)

	const callback = `
		<html>
			<script>history.back()</script>
		</html>
	`
	tmpl := template.New("callback")
	if tmpl, err = tmpl.Parse(callback); err != nil {
		log.Println(err)
	}
	tmpl.Execute(os.Stdout, callback)
}

func (s *service) HandleFacebookLogout(w http.ResponseWriter, r *http.Request) {
	cookies := []string{"travellerID", "sessionToken"}

	for _, c := range cookies {
		cookie, err := r.Cookie(c)
		if err != nil {
			log.Println(err)
			http.Error(w, http.StatusText(401), 401)
			return
		}

		cookie.Path = "/"
		cookie.MaxAge = -1
		http.SetCookie(w, cookie)
	}

	w.WriteHeader(http.StatusOK)
}

func (s *service) ValidateSession(id int, sessionToken string) error {
	repo := persistence.NewTravellerRepository()

	_, err := repo.Find(0)
	if err != nil {
		if err.Error() == "Error 1046: No database selected" {
			database.DB.Close()
			database.DB, err = database.Init(os.Getenv("ENV"))
			if err != nil {
				log.Println(err)
			}
		} else if err.Error() != "sql: no rows in result set" {
			log.Println(err)
		}
	}

	if err = repo.FindBySessionToken(id, sessionToken); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package httpow

import (
	"errors"
	"net"
	"net/http"
	"sync"
	"time"
)

// Server traps http.Server, exposes additional fuctionality
type Server struct {
	// IdleTimeout tells how long connection can be idle between requests.
	// Value of http.Server.ReadTimeout taken from the passed server instance
	// will be used as a single request read timeout.
	IdleTimeout time.Duration

	// NewAsActive controls whether new connection can be idle before issuing
	// a request. By default new connections will have IdleTimeout allowing for
	// idle period before issuing a request. However, if this flag is set, new
	// connections will be given ReadTimeout as the request was already initiated.
	NewAsActive bool

	server   *http.Server // wrapped http server
	listener *rtListener

	reqTimeout time.Duration // request timeout

	lock sync.Mutex

	closing bool

	// conns is a map of connections which indicates whether connection is active,
	// i.e. there a request being processed (including header handling)
	conns map[net.Conn]bool
}

// NewServer wraps http.Server, which should be already configured.
func NewServer(server *http.Server) *Server {
	return &Server{server: server, conns: make(map[net.Conn]bool)}
}

// Serve behaves as http.Server.Serve on the wrapped server instance
func (s *Server) Serve(l net.Listener) error {
	if s.IdleTimeout != 0 {
		s.reqTimeout = s.server.ReadTimeout
		// Disable read timeout management by http.Server
		s.server.ReadTimeout = 0
	}

	oldConnState := s.server.ConnState
	newConnState := func(c net.Conn, state http.ConnState) {
		s.updateConnState(c, state)
		// Pass to original handler
		if oldConnState != nil {
			oldConnState(c, state)
		}
	}

	s.server.ConnState = newConnState

	// Wrap with custom listener
	s.listener = &rtListener{
		Listener:    l,
		newAsActive: s.NewAsActive,
		callback:    func(c net.Conn) { newConnState(c, StateData) },
	}

	err := s.server.Serve(s.listener)
	if err == errListenerClosed {
		err = nil
	}
	return err
}

// Close server
func (s *Server) Close() {
	s.lock.Lock()
	defer s.lock.Unlock()

	s.listener.Close()
	s.server.SetKeepAlivesEnabled(false)
	s.closing = true

	// Set a 100ms deadline for all inactive connections (new or idle).
	// If during this period state changes to active, request will be processed
	// with regular request timeout, otherwise connection will be closed.
	deadline := time.Now().Add(100 * time.Millisecond)
	for c, active := range s.conns {
		if !active {
			c.SetReadDeadline(deadline)
		}
	}
}

func (s *Server) getTimeout(state http.ConnState) (timeout time.Duration) {
	switch state {
	case http.StateNew:
		if s.NewAsActive {
			timeout = s.reqTimeout
		} else {
			timeout = s.IdleTimeout
		}

	case http.StateIdle:
		timeout = s.IdleTimeout

	case StateData:
		timeout = s.reqTimeout
	}

	return
}

func (s *Server) updateConnState(c net.Conn, state http.ConnState) {
	s.lock.Lock()
	defer s.lock.Unlock()

	// Update connection map
	switch state {
	case http.StateNew, http.StateIdle:
		s.conns[c] = false
	case http.StateClosed, http.StateHijacked:
		delete(s.conns, c)
		s.listener.wg.Done()
	case StateData:
		s.conns[c] = true
	}

	if state == http.StateIdle {
		if c, ok := c.(*rtConn); ok {
			c.idle()
		}
	}

	// Update timeout if not closing or new request
	if !s.closing || state == StateData {
		if t := s.getTimeout(state); t != 0 {
			c.SetReadDeadline(time.Now().Add(t))
		}
	}
}

type rtListener struct {
	net.Listener

	newAsActive bool             // set new connections as active
	callback    func(c net.Conn) // data callback

	wg     sync.WaitGroup
	mx     sync.Mutex
	closed bool
}

// This error will be proagated to Serve when we delibaretely close the listener
var errListenerClosed = errors.New("listener closed")

func (l *rtListener) Accept() (c net.Conn, err error) {
	l.wg.Add(1)
	defer func() {
		if c == nil {
			l.wg.Done()
		}
	}()

	c, err = l.Listener.Accept()
	if c != nil {
		c = &rtConn{c, l.newAsActive, l.callback, &l.wg}
	}
	if err != nil {
		l.mx.Lock()
		if l.closed {
			err = errListenerClosed
		}
		l.mx.Unlock()
	}
	return
}

func (l *rtListener) Close() (err error) {
	l.mx.Lock()
	l.closed = true
	l.mx.Unlock()
	return l.Listener.Close()
}

const (
	// StateData tells when initial request data (header) was received.
	// This varies from http.StateActive, as the latter is issued after headers
	// are parsed.
	StateData http.ConnState = 100 + iota
)

// rtConn is a net.Conn that sets read deadlines for idle and active state.
// It automatically detects requests as first bytes are read after idle state.
type rtConn struct {
	net.Conn

	active   bool             // are we currently processing a request?
	callback func(c net.Conn) // data callback
	wg       *sync.WaitGroup
}

func (c *rtConn) Read(b []byte) (n int, err error) {
	n, err = c.Conn.Read(b)
	if n > 0 && !c.active {
		c.callback(c)
	}
	return
}

func (c *rtConn) idle() {
	c.active = false
}
<commit_msg>Serve returns channel which can be used to wait for outstadning requests<commit_after>package httpow

import (
	"errors"
	"net"
	"net/http"
	"sync"
	"time"
)

// Server traps http.Server, exposes additional fuctionality
type Server struct {
	// IdleTimeout tells how long connection can be idle between requests.
	// Value of http.Server.ReadTimeout taken from the passed server instance
	// will be used as a single request read timeout.
	IdleTimeout time.Duration

	// NewAsActive controls whether new connection can be idle before issuing
	// a request. By default new connections will have IdleTimeout allowing for
	// idle period before issuing a request. However, if this flag is set, new
	// connections will be given ReadTimeout as the request was already initiated.
	NewAsActive bool

	server   *http.Server // wrapped http server
	listener *rtListener

	reqTimeout time.Duration // request timeout

	lock sync.Mutex

	closing bool

	// conns is a map of connections which indicates whether connection is active,
	// i.e. there a request being processed (including header handling)
	conns map[net.Conn]bool
}

// NewServer wraps http.Server, which should be already configured.
func NewServer(server *http.Server) *Server {
	return &Server{server: server, conns: make(map[net.Conn]bool)}
}

// Serve behaves as http.Server.Serve on the wrapped server instance
func (s *Server) Serve(l net.Listener) (pending <-chan bool, err error) {
	if s.IdleTimeout != 0 {
		s.reqTimeout = s.server.ReadTimeout
		// Disable read timeout management by http.Server
		s.server.ReadTimeout = 0
	}

	oldConnState := s.server.ConnState
	newConnState := func(c net.Conn, state http.ConnState) {
		s.updateConnState(c, state)
		// Pass to original handler
		if oldConnState != nil {
			oldConnState(c, state)
		}
	}

	s.server.ConnState = newConnState

	// Wrap with custom listener
	s.listener = &rtListener{
		Listener:    l,
		newAsActive: s.NewAsActive,
		callback:    func(c net.Conn) { newConnState(c, StateData) },
	}

	err = s.server.Serve(s.listener)
	if err == errListenerClosed {
		err = nil
	}

	// Wait for pending requests
	waiter := make(chan bool)
	pending = waiter
	go func() {
		s.listener.wg.Wait()
		close(waiter)
	}()

	return
}

// Close server
func (s *Server) Close() {
	s.lock.Lock()
	defer s.lock.Unlock()

	s.listener.Close()
	s.server.SetKeepAlivesEnabled(false)
	s.closing = true

	// Set a 100ms deadline for all inactive connections (new or idle).
	// If during this period state changes to active, request will be processed
	// with regular request timeout, otherwise connection will be closed.
	deadline := time.Now().Add(100 * time.Millisecond)
	for c, active := range s.conns {
		if !active {
			c.SetReadDeadline(deadline)
		}
	}
}

func (s *Server) getTimeout(state http.ConnState) (timeout time.Duration) {
	switch state {
	case http.StateNew:
		if s.NewAsActive {
			timeout = s.reqTimeout
		} else {
			timeout = s.IdleTimeout
		}

	case http.StateIdle:
		timeout = s.IdleTimeout

	case StateData:
		timeout = s.reqTimeout
	}

	return
}

func (s *Server) updateConnState(c net.Conn, state http.ConnState) {
	s.lock.Lock()
	defer s.lock.Unlock()

	// Update connection map
	switch state {
	case http.StateNew, http.StateIdle:
		s.conns[c] = false
	case http.StateClosed, http.StateHijacked:
		delete(s.conns, c)
		s.listener.wg.Done()
	case StateData:
		s.conns[c] = true
	}

	if state == http.StateIdle {
		if c, ok := c.(*rtConn); ok {
			c.idle()
		}
	}

	// Update timeout if not closing or new request
	if !s.closing || state == StateData {
		if t := s.getTimeout(state); t != 0 {
			c.SetReadDeadline(time.Now().Add(t))
		}
	}
}

type rtListener struct {
	net.Listener

	newAsActive bool             // set new connections as active
	callback    func(c net.Conn) // data callback

	wg     sync.WaitGroup
	mx     sync.Mutex
	closed bool
}

// This error will be proagated to Serve when we delibaretely close the listener
var errListenerClosed = errors.New("listener closed")

func (l *rtListener) Accept() (c net.Conn, err error) {
	l.wg.Add(1)
	defer func() {
		if c == nil {
			l.wg.Done()
		}
	}()

	c, err = l.Listener.Accept()
	if c != nil {
		c = &rtConn{c, l.newAsActive, l.callback, &l.wg}
	}
	if err != nil {
		l.mx.Lock()
		if l.closed {
			err = errListenerClosed
		}
		l.mx.Unlock()
	}
	return
}

func (l *rtListener) Close() (err error) {
	l.mx.Lock()
	l.closed = true
	l.mx.Unlock()
	return l.Listener.Close()
}

const (
	// StateData tells when initial request data (header) was received.
	// This varies from http.StateActive, as the latter is issued after headers
	// are parsed.
	StateData http.ConnState = 100 + iota
)

// rtConn is a net.Conn that sets read deadlines for idle and active state.
// It automatically detects requests as first bytes are read after idle state.
type rtConn struct {
	net.Conn

	active   bool             // are we currently processing a request?
	callback func(c net.Conn) // data callback
	wg       *sync.WaitGroup
}

func (c *rtConn) Read(b []byte) (n int, err error) {
	n, err = c.Conn.Read(b)
	if n > 0 && !c.active {
		c.callback(c)
	}
	return
}

func (c *rtConn) idle() {
	c.active = false
}
<|endoftext|>