<commit_before>package birect

import (
	"log"
	"sync"

	"github.com/marcuswestin/go-ws"
)

// Server is used register request handlers (for requests sent from clients),
// and to accept incoming connections from birect clients.
type Server struct {
	jsonReqHandlerMap
	protoReqHandlerMap
	connByWSConnMutex *sync.Mutex
	connByWSConn      map[*ws.Conn]*Conn
	ConnectHandler    func(*Conn)
	DisconnectHandler func(*Conn)
}

// UpgradeRequests will upgrade all incoming HTTP requests that match `pattern`
// to birect connections.
func UpgradeRequests(pattern string) (server *Server) {
	server = &Server{
		make(jsonReqHandlerMap),
		make(protoReqHandlerMap),
		&sync.Mutex{},
		make(map[*ws.Conn]*Conn, 10000),
		func(*Conn) {},
		func(*Conn) {},
	}
	ws.UpgradeRequests(pattern, func(event *ws.Event, wsConn *ws.Conn) {
		log.Println("Server:", event)
		switch event.Type {
		case ws.Connected:
			server.registerConn(wsConn)
		case ws.BinaryMessage:
			if conn := server.getConn(wsConn); conn != nil {
				conn.readAndHandleWireWrapperReader(event)
			}
		case ws.Disconnected:
			server.deregisterConn(wsConn)
		default:
			panic("birect.Server unknown event: " + event.String())
		}
	})
	return server
}

// Internal
///////////

func (s *Server) registerConn(wsConn *ws.Conn) {
	s.connByWSConnMutex.Lock()
	defer s.connByWSConnMutex.Unlock()
	conn := newConn(wsConn, s.jsonReqHandlerMap, s.protoReqHandlerMap)
	s.connByWSConn[wsConn] = conn
	defer s.ConnectHandler(conn)
}
func (s *Server) deregisterConn(wsConn *ws.Conn) {
	s.connByWSConnMutex.Lock()
	defer s.connByWSConnMutex.Unlock()
	conn := s.connByWSConn[wsConn]
	delete(s.connByWSConn, wsConn)
	defer s.DisconnectHandler(conn)
}
func (s *Server) getConn(wsConn *ws.Conn) *Conn {
	s.connByWSConnMutex.Lock()
	defer s.connByWSConnMutex.Unlock()
	return s.connByWSConn[wsConn]
}
<commit_msg>Clarify that Dis/ConnectHandler are optional<commit_after>package birect

import (
	"log"
	"sync"

	"github.com/marcuswestin/go-ws"
)

// Server is used register request handlers (for requests sent from clients),
// and to accept incoming connections from birect clients.
type Server struct {
	jsonReqHandlerMap
	protoReqHandlerMap
	connByWSConnMutex *sync.Mutex
	connByWSConn      map[*ws.Conn]*Conn
	ConnectHandler    func(*Conn)
	DisconnectHandler func(*Conn)
}

// UpgradeRequests will upgrade all incoming HTTP requests that match `pattern`
// to birect connections.
func UpgradeRequests(pattern string) (server *Server) {
	server = &Server{
		make(jsonReqHandlerMap),
		make(protoReqHandlerMap),
		&sync.Mutex{},
		make(map[*ws.Conn]*Conn, 10000),
		func(*Conn) {},
		func(*Conn) {},
	}
	ws.UpgradeRequests(pattern, func(event *ws.Event, wsConn *ws.Conn) {
		log.Println("Server:", event)
		switch event.Type {
		case ws.Connected:
			server.registerConn(wsConn)
		case ws.BinaryMessage:
			if conn := server.getConn(wsConn); conn != nil {
				conn.readAndHandleWireWrapperReader(event)
			}
		case ws.Disconnected:
			server.deregisterConn(wsConn)
		default:
			panic("birect.Server unknown event: " + event.String())
		}
	})
	return server
}

// Internal
///////////

func (s *Server) registerConn(wsConn *ws.Conn) {
	s.connByWSConnMutex.Lock()
	defer s.connByWSConnMutex.Unlock()
	conn := newConn(wsConn, s.jsonReqHandlerMap, s.protoReqHandlerMap)
	s.connByWSConn[wsConn] = conn
	if s.ConnectHandler != nil {
		defer s.ConnectHandler(conn)
	}
}
func (s *Server) deregisterConn(wsConn *ws.Conn) {
	s.connByWSConnMutex.Lock()
	defer s.connByWSConnMutex.Unlock()
	conn := s.connByWSConn[wsConn]
	delete(s.connByWSConn, wsConn)
	if s.DisconnectHandler != nil {
		defer s.DisconnectHandler(conn)
	}
}
func (s *Server) getConn(wsConn *ws.Conn) *Conn {
	s.connByWSConnMutex.Lock()
	defer s.connByWSConnMutex.Unlock()
	return s.connByWSConn[wsConn]
}
<|endoftext|>


<commit_before>package modules

import (
	"log"
	"regexp"
	"strings"
)

type RoutesModule struct {
	BaseModule
	Routes []*Route
}

func NewRoutesModule(node Node) *RoutesModule {
	module := &RoutesModule{
		Routes: make([]*Route, 0),
	}
	module.Init(node)
	return module
}

func (m *RoutesModule) Init(node Node) {
	list := node.(List)
	for i := range list {
		m.Routes = append(m.Routes, NewRoute(list[i]))
	}
}

func (m *RoutesModule) Process(req *Req, res *Res) bool {
	path := req.GetPath()
	log.Println("Routes process path", path)
	for _, route := range m.Routes {
		if route.Match(req) {
			route.Process(req, res)
			break
		}
	}
	return false
}

type Route struct {
	Method    string
	Path      string
	PathRegex *regexp.Regexp
	Chain     Module
}

func NewRoute(node Node) *Route {
	route := &Route{}
	route.Init(node)
	return route
}

func (r *Route) Init(node Node) {
	mp := node.(Map)
	if len(mp) > 1 || len(mp) == 0 {
		panic("Invalid route config, only allow ONE path for each route.")
	}
	key := mp.Keys()[0]
	value := mp[key]
	r.Chain = MakeChain(value.(Map))
	pairs := regexp.MustCompile("\\s+").Split(key, 2)
	r.Method = pairs[0]
	if len(pairs) > 1 {
		r.Path = pairs[1]
	}
	if strings.Index(r.Path, "*") != -1 {
		rstr := strings.Replace(r.Path, "*", "(.*?)", -1)
		log.Println("rstr is:", rstr)
		r.PathRegex = regexp.MustCompile(rstr)
	}
}

func (r *Route) Match(req *Req) bool {
	path := req.GetPath()
	if r.PathRegex != nil {
		matchs := r.PathRegex.FindAllString(path, -1)
		log.Println("path ", path, " matchs ", matchs)
		return len(matchs) > 0
	}
	return path == r.Path
}

func (r *Route) Process(req *Req, res *Res) bool {
	log.Println("Route process")
	return r.Chain.Process(req, res)
}
<commit_msg>fix routes for *<commit_after>package modules

import (
	"log"
	"regexp"
	"strings"
)

type RoutesModule struct {
	BaseModule
	Routes []*Route
}

func NewRoutesModule(node Node) *RoutesModule {
	module := &RoutesModule{
		Routes: make([]*Route, 0),
	}
	module.Init(node)
	return module
}

func (m *RoutesModule) Init(node Node) {
	list := node.(List)
	for i := range list {
		m.Routes = append(m.Routes, NewRoute(list[i]))
	}
}

func (m *RoutesModule) Process(req *Req, res *Res) bool {
	path := req.GetPath()
	log.Println("Routes process path", path)
	for _, route := range m.Routes {
		log.Println("test route", route.Method, route.Path)
		if route.Match(req) {
			log.Println("match")
			if route.Process(req, res) {
				return true
			}
		}
	}
	return false
}

type Route struct {
	Method    string
	Path      string
	PathRegex *regexp.Regexp
	Chain     Module
}

func NewRoute(node Node) *Route {
	route := &Route{}
	route.Init(node)
	return route
}

func (r *Route) Init(node Node) {
	mp := node.(Map)
	if len(mp) > 1 || len(mp) == 0 {
		panic("Invalid route config, only allow ONE path for each route.")
	}
	key := mp.Keys()[0]
	value := mp[key]
	r.Chain = MakeChain(value.(Map))
	if key == "*" {
		key = "* *"
	}
	pairs := regexp.MustCompile("\\s+").Split(key, 2)
	r.Method = pairs[0]
	if len(pairs) > 1 {
		r.Path = pairs[1]
	}
	if strings.Index(r.Path, "*") != -1 {
		rstr := strings.Replace(r.Path, "*", "(.*?)", -1)
		log.Println("rstr is:", rstr)
		r.PathRegex = regexp.MustCompile(rstr)
	}
}

func (r *Route) Match(req *Req) bool {
	path := req.GetPath()
	if r.PathRegex != nil {
		matchs := r.PathRegex.FindAllString(path, -1)
		log.Println("path ", path, " matchs ", matchs)
		return len(matchs) > 0
	}
	return path == r.Path
}

func (r *Route) Process(req *Req, res *Res) bool {
	log.Println("Route process")
	return r.Chain.Process(req, res)
}
<|endoftext|>


<commit_before>//
//  Clone client Model Two
//
//  In the original C example, the client misses updates between snapshot
//  and further updates. Sometimes, it even misses the END message of
//  the snapshot, so it waits for it forever.
//  This Go implementation has some modifications to improve this, but it
//  is still not fully reliable.

package main

import (
	zmq "github.com/pebbe/zmq2"
	"github.com/pebbe/zmq2/examples/kvsimple"

	"fmt"
	"time"
)

func main() {
	snapshot, _ := zmq.NewSocket(zmq.DEALER)
	snapshot.Connect("tcp://localhost:5556")

	subscriber, _ := zmq.NewSocket(zmq.SUB)
	subscriber.SetRcvhwm(100000) // or messages between snapshot and next are lost
	subscriber.SetSubscribe("")
	subscriber.Connect("tcp://localhost:5557")

	time.Sleep(time.Second) // or messages between snapshot and next are lost

	kvmap := make(map[string]*kvsimple.Kvmsg)

	//  Get state snapshot
	sequence := int64(0)
	snapshot.SendMessage("ICANHAZ?")
	for {
		kvmsg, err := kvsimple.RecvKvmsg(snapshot)
		if err != nil {
			fmt.Println(err)
			break //  Interrupted
		}
		if key, _ := kvmsg.GetKey(); key == "KTHXBAI" {
			sequence, _ = kvmsg.GetSequence()
			fmt.Printf("Received snapshot=%d\n", sequence)
			break //  Done
		}
		kvmsg.Store(kvmap)
	}
	snapshot.Close()

	first := true
	//  Now apply pending updates, discard out-of-sequence messages
	for {
		kvmsg, err := kvsimple.RecvKvmsg(subscriber)
		if err != nil {
			fmt.Println(err)
			break //  Interrupted
		}
		if seq, _ := kvmsg.GetSequence(); seq > sequence {
			sequence, _ = kvmsg.GetSequence()
			kvmsg.Store(kvmap)
			if first {
				// Show what the first regular update is after the snapshot,
				// to see if we missed updates.
				first = false
				fmt.Println("Next:", sequence)
			}
		}
	}
}
<commit_msg>Fix example for 0MQv2: clonecli2<commit_after>//
//  Clone client Model Two
//
//  In the original C example, the client misses updates between snapshot
//  and further updates. Sometimes, it even misses the END message of
//  the snapshot, so it waits for it forever.
//  This Go implementation has some modifications to improve this, but it
//  is still not fully reliable.

package main

import (
	zmq "github.com/pebbe/zmq2"
	"github.com/pebbe/zmq2/examples/kvsimple"

	"fmt"
	"time"
)

func main() {
	snapshot, _ := zmq.NewSocket(zmq.DEALER)
	snapshot.Connect("tcp://localhost:5556")

	subscriber, _ := zmq.NewSocket(zmq.SUB)
	subscriber.SetSubscribe("")
	subscriber.Connect("tcp://localhost:5557")

	time.Sleep(time.Second) // or messages between snapshot and next are lost

	kvmap := make(map[string]*kvsimple.Kvmsg)

	//  Get state snapshot
	sequence := int64(0)
	snapshot.SendMessage("ICANHAZ?")
	for {
		kvmsg, err := kvsimple.RecvKvmsg(snapshot)
		if err != nil {
			fmt.Println(err)
			break //  Interrupted
		}
		if key, _ := kvmsg.GetKey(); key == "KTHXBAI" {
			sequence, _ = kvmsg.GetSequence()
			fmt.Printf("Received snapshot=%d\n", sequence)
			break //  Done
		}
		kvmsg.Store(kvmap)
	}
	snapshot.Close()

	first := true
	//  Now apply pending updates, discard out-of-sequence messages
	for {
		kvmsg, err := kvsimple.RecvKvmsg(subscriber)
		if err != nil {
			fmt.Println(err)
			break //  Interrupted
		}
		if seq, _ := kvmsg.GetSequence(); seq > sequence {
			sequence, _ = kvmsg.GetSequence()
			kvmsg.Store(kvmap)
			if first {
				// Show what the first regular update is after the snapshot,
				// to see if we missed updates.
				first = false
				fmt.Println("Next:", sequence)
			}
		}
	}
}
<|endoftext|>


<commit_before>package mstate

import (
	"errors"
	"fmt"
	"labix.org/v2/mgo/bson"
	"launchpad.net/juju-core/charm"
	"strconv"
)

// Service represents the state of a service.
type Service struct {
	st   *State
	name string
}

// serviceDoc represents the internal state of a service in MongoDB.
type serviceDoc struct {
	Name     string `bson:"_id"`
	CharmURL *charm.URL
	Life     Life
}

// Name returns the service name.
func (s *Service) Name() string {
	return s.name
}

// CharmURL returns the charm URL this service is supposed to use.
func (s *Service) CharmURL() (url *charm.URL, err error) {
	sdoc := &serviceDoc{}
	sel := bson.D{{"_id", s.name}, {"life", Alive}}
	err = s.st.services.Find(sel).One(sdoc)
	if err != nil {
		return nil, fmt.Errorf("can't get the charm URL of service %q: %v", s, err)
	}
	return sdoc.CharmURL, nil
}

// SetCharmURL changes the charm URL for the service.
func (s *Service) SetCharmURL(url *charm.URL) (err error) {
	change := bson.D{{"$set", bson.D{{"charmurl", url}}}}
	err = s.st.services.Update(bson.D{{"_id", s.name}}, change)
	if err != nil {
		return fmt.Errorf("can't set the charm URL of service %q: %v", s, err)
	}
	return nil
}

// Charm returns the service's charm.
func (s *Service) Charm() (*Charm, error) {
	url, err := s.CharmURL()
	if err != nil {
		return nil, err
	}
	return s.st.Charm(url)
}

// String returns the service name.
func (s *Service) String() string {
	return s.Name()
}

// newUnitName returns the next unit name.
func (s *Service) newUnitName() (string, error) {
	id, err := s.st.sequence(s.Name())
	if err != nil {
		return "", err
	}
	name := s.name + "/" + strconv.Itoa(id)
	return name, nil
}

// addUnit adds the named unit, which is part of unitSet.
func (s *Service) addUnit(name string, principal string) (*Unit, error) {
	udoc := unitDoc{
		Name:      name,
		Service:   s.name,
		Principal: principal,
		Life:      Alive,
	}
	err := s.st.units.Insert(udoc)
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q", s)
	}
	return newUnit(s.st, &udoc), nil
}

// AddUnit adds a new principal unit to the service.
func (s *Service) AddUnit() (unit *Unit, err error) {
	ch, err := s.Charm()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	if ch.Meta().Subordinate {
		return nil, fmt.Errorf("cannot directly add units to subordinate service %q", s)
	}
	name, err := s.newUnitName()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	return s.addUnit(name, "")
}

// AddUnitSubordinateTo adds a new subordinate unit to the service,
// subordinate to principal.
func (s *Service) AddUnitSubordinateTo(principal *Unit) (*Unit, error) {
	ch, err := s.Charm()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	if !ch.Meta().Subordinate {
		return nil, fmt.Errorf("can't add unit of principal service %q as a subordinate of %q", s, principal)
	}
	if !principal.IsPrincipal() {
		return nil, errors.New("a subordinate unit must be added to a principal unit")
	}
	name, err := s.newUnitName()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	return s.addUnit(name, principal.Name())
}

// RemoveUnit removes the given unit from s.
func (s *Service) RemoveUnit(unit *Unit) error {
	sel := bson.D{
		{"_id", unit.Name()},
		{"service", s.name},
		{"life", Alive},
	}
	change := bson.D{{"$set", bson.D{{"life", Dying}}}}
	err := s.st.units.Update(sel, change)
	if err != nil {
		return fmt.Errorf("can't remove unit %q: %v", unit, err)
	}
	return nil
}

func (s *Service) unitDoc(name string) (*unitDoc, error) {
	udoc := &unitDoc{}
	sel := bson.D{
		{"_id", name},
		{"service", s.name},
		{"life", Alive},
	}
	err := s.st.units.Find(sel).One(udoc)
	if err != nil {
		return nil, err
	}
	return udoc, nil
}

// Unit returns the service's unit with name.
func (s *Service) Unit(name string) (*Unit, error) {
	udoc, err := s.unitDoc(name)
	if err != nil {
		return nil, fmt.Errorf("can't get unit %q from service %q: %v", name, s.name, err)
	}
	return newUnit(s.st, udoc), nil
}

// AllUnits returns all units of the service.
func (s *Service) AllUnits() (units []*Unit, err error) {
	docs := []unitDoc{}
	sel := bson.D{{"service", s.name}, {"life", Alive}}
	err = s.st.units.Find(sel).All(&docs)
	if err != nil {
		return nil, fmt.Errorf("can't get all units from service %q: %v", err)
	}
	for i := range docs {
		units = append(units, newUnit(s.st, &docs[i]))
	}
	return units, nil
}
<commit_msg>mstate: don't use global sequencing for units.<commit_after>package mstate

import (
	"errors"
	"fmt"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
	"launchpad.net/juju-core/charm"
	"strconv"
)

// Service represents the state of a service.
type Service struct {
	st   *State
	name string
}

// serviceDoc represents the internal state of a service in MongoDB.
type serviceDoc struct {
	Name     string `bson:"_id"`
	CharmURL *charm.URL
	Life     Life
	UnitSeq  int
}

// Name returns the service name.
func (s *Service) Name() string {
	return s.name
}

// CharmURL returns the charm URL this service is supposed to use.
func (s *Service) CharmURL() (url *charm.URL, err error) {
	sdoc := &serviceDoc{}
	sel := bson.D{{"_id", s.name}, {"life", Alive}}
	err = s.st.services.Find(sel).One(sdoc)
	if err != nil {
		return nil, fmt.Errorf("can't get the charm URL of service %q: %v", s, err)
	}
	return sdoc.CharmURL, nil
}

// SetCharmURL changes the charm URL for the service.
func (s *Service) SetCharmURL(url *charm.URL) (err error) {
	change := bson.D{{"$set", bson.D{{"charmurl", url}}}}
	err = s.st.services.Update(bson.D{{"_id", s.name}}, change)
	if err != nil {
		return fmt.Errorf("can't set the charm URL of service %q: %v", s, err)
	}
	return nil
}

// Charm returns the service's charm.
func (s *Service) Charm() (*Charm, error) {
	url, err := s.CharmURL()
	if err != nil {
		return nil, err
	}
	return s.st.Charm(url)
}

// String returns the service name.
func (s *Service) String() string {
	return s.Name()
}

// newUnitName returns the next unit name.
func (s *Service) newUnitName() (string, error) {
	sel := bson.D{{"_id", s.name}, {"life", Alive}}
	change := mgo.Change{Update: bson.D{{"$inc", bson.D{{"unitseq", 1}}}}}
	result := serviceDoc{}
	_, err := s.st.services.Find(sel).Apply(change, &result)
	if err != nil {
		return "", err
	}
	name := s.name + "/" + strconv.Itoa(result.UnitSeq)
	return name, nil
}

// addUnit adds the named unit, which is part of unitSet.
func (s *Service) addUnit(name string, principal string) (*Unit, error) {
	udoc := unitDoc{
		Name:      name,
		Service:   s.name,
		Principal: principal,
		Life:      Alive,
	}
	err := s.st.units.Insert(udoc)
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q", s)
	}
	return newUnit(s.st, &udoc), nil
}

// AddUnit adds a new principal unit to the service.
func (s *Service) AddUnit() (unit *Unit, err error) {
	ch, err := s.Charm()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	if ch.Meta().Subordinate {
		return nil, fmt.Errorf("cannot directly add units to subordinate service %q", s)
	}
	name, err := s.newUnitName()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	return s.addUnit(name, "")
}

// AddUnitSubordinateTo adds a new subordinate unit to the service,
// subordinate to principal.
func (s *Service) AddUnitSubordinateTo(principal *Unit) (*Unit, error) {
	ch, err := s.Charm()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	if !ch.Meta().Subordinate {
		return nil, fmt.Errorf("can't add unit of principal service %q as a subordinate of %q", s, principal)
	}
	if !principal.IsPrincipal() {
		return nil, errors.New("a subordinate unit must be added to a principal unit")
	}
	name, err := s.newUnitName()
	if err != nil {
		return nil, fmt.Errorf("can't add unit to service %q: %v", err)
	}
	return s.addUnit(name, principal.Name())
}

// RemoveUnit removes the given unit from s.
func (s *Service) RemoveUnit(unit *Unit) error {
	sel := bson.D{
		{"_id", unit.Name()},
		{"service", s.name},
		{"life", Alive},
	}
	change := bson.D{{"$set", bson.D{{"life", Dying}}}}
	err := s.st.units.Update(sel, change)
	if err != nil {
		return fmt.Errorf("can't remove unit %q: %v", unit, err)
	}
	return nil
}

func (s *Service) unitDoc(name string) (*unitDoc, error) {
	udoc := &unitDoc{}
	sel := bson.D{
		{"_id", name},
		{"service", s.name},
		{"life", Alive},
	}
	err := s.st.units.Find(sel).One(udoc)
	if err != nil {
		return nil, err
	}
	return udoc, nil
}

// Unit returns the service's unit with name.
func (s *Service) Unit(name string) (*Unit, error) {
	udoc, err := s.unitDoc(name)
	if err != nil {
		return nil, fmt.Errorf("can't get unit %q from service %q: %v", name, s.name, err)
	}
	return newUnit(s.st, udoc), nil
}

// AllUnits returns all units of the service.
func (s *Service) AllUnits() (units []*Unit, err error) {
	docs := []unitDoc{}
	sel := bson.D{{"service", s.name}, {"life", Alive}}
	err = s.st.units.Find(sel).All(&docs)
	if err != nil {
		return nil, fmt.Errorf("can't get all units from service %q: %v", err)
	}
	for i := range docs {
		units = append(units, newUnit(s.st, &docs[i]))
	}
	return units, nil
}
<|endoftext|>


<commit_before>// This simple test application serve live generated WebM content on webpage
// using HTML5 <video> element.
package main

import (
	"github.com/ziutek/glib"
	"github.com/ziutek/gst"
	"http"
	"fmt"
	"net"
	"io"
	"syscall"
	"log"
)

type Index struct {
	width, height int
}

func (ix *Index) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
	html := `<!doctype html>

			<meta charset='utf-8'>
			<title>Live WebM video</title>

			<video src='/video' width=%d height=%d autoplay></video>

	`

	fmt.Fprintf(wr, html, ix.width, ix.height)
}

type WebM struct {
	pl   *gst.Pipeline
	sink *gst.Element
	conns map[int]net.Conn
}

func (wm *WebM) Play() {
	wm.pl.SetState(gst.STATE_PLAYING)
}

func (wm *WebM) Stop() {
	wm.pl.SetState(gst.STATE_READY)
}

func (wm *WebM) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
	/*wr.Header().Set("Content-Type", "video/webm")
	wr.Header().Set("Transfer-Encoding", "identity")
	wr.WriteHeader(http.StatusOK)
	wr.(http.Flusher).Flush()*/

	// Obtain fd
	conn, _, err := wr.(http.Hijacker).Hijack()
	if err != nil {
		log.Println("http.Hijacker.Hijack:", err)
		return
	}
	file, err := conn.(*net.TCPConn).File()
	if err != nil {
		log.Println("net.TCPConn.File:", err)
		return
	}
	fd, errno := syscall.Dup(file.Fd())
	if errno != 0 {
		log.Println("syscall.Dup:", syscall.Errstr(errno))
		return
	}
	// Send HTTP header
	_, err = io.WriteString(
		file,
		"HTTP/1.1 200 OK\r\n" +
		"Transfer-Encoding: identity\r\n" +
		"Content-Type: video/webm\r\n\r\n",
	)
	if err != nil {
		log.Println("io.WriteString:", err)
		return
	}
	file.Close()

	// Save connection in map (workaround)
	wm.conns[fd] = conn

	// Pass fd to the multifdsink
	wm.sink.Emit("add", fd)
}

// Handler for connection closing
func (wm *WebM) cbClientFdRemoved(fd int) {
	wm.conns[fd].Close()
	syscall.Close(fd)
	wm.conns[fd] = nil, false
}

func NewWebM(width, height, fps int) *WebM {
	wm := new(WebM)
	wm.conns = make(map[int]net.Conn)

	src := gst.ElementFactoryMake("videotestsrc", "Test source")
	src.SetProperty("do-timestamp", true)
	src.SetProperty("pattern", 18) // ball

	enc := gst.ElementFactoryMake("vp8enc", "VP8 encoder")

	mux := gst.ElementFactoryMake("webmmux", "WebM muxer")
	mux.SetProperty("streamable", true)

	wm.sink = gst.ElementFactoryMake("multifdsink", "Multifd sink")
	wm.sink.SetProperty("sync", true)
	wm.sink.SetProperty("recover-policy", 3) // keyframe
	wm.sink.SetProperty("sync-method", 2)    // latest-keyframe

	wm.pl = gst.NewPipeline("WebM generator")
	wm.pl.Add(src, enc, mux, wm.sink)

	filter := gst.NewCapsSimple(
		"video/x-raw-yuv",
		glib.Params{
			"width":     width,
			"height":    height,
			"framerate": &gst.Fraction{fps, 1},
		},
	)
	src.LinkFiltered(enc, filter)
	enc.Link(mux, wm.sink)

	wm.sink.ConnectNoi("client-fd-removed", (*WebM).cbClientFdRemoved, wm)

	return wm
}

func staticHandler(wr http.ResponseWriter, req *http.Request) {
	http.ServeFile(wr, req, req.URL.Path[1:])
}

func main() {
	index := &Index{384, 216}
	wm := NewWebM(index.width, index.height, 25)
	wm.Play()

	http.Handle("/", index)
	http.Handle("/video", wm)
	http.HandleFunc("/images/", staticHandler)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatalln("http.ListenAndServe:", err)
	}
}
<commit_msg>Remove Transfer-Encoding from header of live video<commit_after>// This simple test application serve live generated WebM content on webpage
// using HTML5 <video> element.
package main

import (
	"github.com/ziutek/glib"
	"github.com/ziutek/gst"
	"http"
	"fmt"
	"net"
	"io"
	"syscall"
	"log"
)

type Index struct {
	width, height int
}

func (ix *Index) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
	html := `<!doctype html>

			<meta charset='utf-8'>
			<title>Live WebM video</title>

			<video src='/video' width=%d height=%d autoplay></video>

	`

	fmt.Fprintf(wr, html, ix.width, ix.height)
}

type WebM struct {
	pl   *gst.Pipeline
	sink *gst.Element
	conns map[int]net.Conn
}

func (wm *WebM) Play() {
	wm.pl.SetState(gst.STATE_PLAYING)
}

func (wm *WebM) Stop() {
	wm.pl.SetState(gst.STATE_READY)
}

func (wm *WebM) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
	/*wr.Header().Set("Content-Type", "video/webm")
	wr.Header().Set("Transfer-Encoding", "identity")
	wr.WriteHeader(http.StatusOK)
	wr.(http.Flusher).Flush()*/

	// Obtain fd
	conn, _, err := wr.(http.Hijacker).Hijack()
	if err != nil {
		log.Println("http.Hijacker.Hijack:", err)
		return
	}
	file, err := conn.(*net.TCPConn).File()
	if err != nil {
		log.Println("net.TCPConn.File:", err)
		return
	}
	fd, errno := syscall.Dup(file.Fd())
	if errno != 0 {
		log.Println("syscall.Dup:", syscall.Errstr(errno))
		return
	}
	// Send HTTP header
	_, err = io.WriteString(
		file,
		"HTTP/1.1 200 OK\r\n" +
		"Content-Type: video/webm\r\n\r\n",
	)
	if err != nil {
		log.Println("io.WriteString:", err)
		return
	}
	file.Close()

	// Save connection in map (workaround)
	wm.conns[fd] = conn

	// Pass fd to the multifdsink
	wm.sink.Emit("add", fd)
}

// Handler for connection closing
func (wm *WebM) cbClientFdRemoved(fd int) {
	wm.conns[fd].Close()
	syscall.Close(fd)
	wm.conns[fd] = nil, false
}

func NewWebM(width, height, fps int) *WebM {
	wm := new(WebM)
	wm.conns = make(map[int]net.Conn)

	src := gst.ElementFactoryMake("videotestsrc", "Test source")
	src.SetProperty("do-timestamp", true)
	src.SetProperty("pattern", 18) // ball

	enc := gst.ElementFactoryMake("vp8enc", "VP8 encoder")

	mux := gst.ElementFactoryMake("webmmux", "WebM muxer")
	mux.SetProperty("streamable", true)

	wm.sink = gst.ElementFactoryMake("multifdsink", "Multifd sink")
	wm.sink.SetProperty("sync", true)
	wm.sink.SetProperty("recover-policy", 3) // keyframe
	wm.sink.SetProperty("sync-method", 2)    // latest-keyframe

	wm.pl = gst.NewPipeline("WebM generator")
	wm.pl.Add(src, enc, mux, wm.sink)

	filter := gst.NewCapsSimple(
		"video/x-raw-yuv",
		glib.Params{
			"width":     width,
			"height":    height,
			"framerate": &gst.Fraction{fps, 1},
		},
	)
	src.LinkFiltered(enc, filter)
	enc.Link(mux, wm.sink)

	wm.sink.ConnectNoi("client-fd-removed", (*WebM).cbClientFdRemoved, wm)

	return wm
}

func staticHandler(wr http.ResponseWriter, req *http.Request) {
	http.ServeFile(wr, req, req.URL.Path[1:])
}

func main() {
	index := &Index{384, 216}
	wm := NewWebM(index.width, index.height, 25)
	wm.Play()

	http.Handle("/", index)
	http.Handle("/video", wm)
	http.HandleFunc("/images/", staticHandler)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatalln("http.ListenAndServe:", err)
	}
}
<|endoftext|>


<commit_before>package util

//Version is the application's version
const Version string = "1.0.0"
<commit_msg>Set version to 0.1.0<commit_after>package util

//Version is the application's version
const Version string = "0.1.0"
<|endoftext|>


<commit_before>package rollsum

// librsync rollsum alg

const (
	ROLLSUM_CHAR_OFFSET uint64 = 31
)

/* the Rollsum struct type*/
type Rollsum struct {
	count uint64 /* count of bytes included in sum */
	s1    uint64 /* s1 part of sum */
	s2    uint64 /* s2 part of sum */
}

func (rs *Rollsum) Count() uint64 {
	return rs.cout
}

func (rs *Rollsum) S1() uint64 {
	return rs.s1
}

func (rs *Rollsum) S2() uint64 {
	return rs.s2
}

func (rs *Rollsum) Init() {
	rs.count = 0
	rs.s1 = 0
	rs.s2 = 0
}

// golang: byte is an alias for uint8 and is equivalent to uint8 in all ways.
//         It is used, by convention, to distinguish byte values from 8-bit
//         unsigned integer values.
func (rs *Rollsum) Rotate(out, in byte) {
	rs.s1 += uint64(in)
	rs.s1 -= uint64(out)
	rs.s2 += rs.s1
	rs.s2 -= rs.count * (uint64(out) + ROLLSUM_CHAR_OFFSET)
}

func (rs *Rollsum) Rollin(c byte) {
	rs.s1 += uint64(c) + ROLLSUM_CHAR_OFFSET
	rs.s2 += rs.s1
	rs.count++
}

func (rs *Rollsum) Rollout(c byte) {
	rs.s1 -= uint64(c) + ROLLSUM_CHAR_OFFSET
	rs.s2 -= rs.count * (uint64(c) + ROLLSUM_CHAR_OFFSET)
	rs.count--
}

func (rs *Rollsum) Digest() uint32 {
	return uint32((rs.s2 << 16) | (rs.s1 & 0xffff))
}

/*
librsync rollsum.c

#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1); => {s1+=buf[i]; s2+=s1;}    {s1+=buf[i+1]; s2+=s1;}
#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2); => {s1+=buf[i]; s2+=s1; s1+=buf[i+1]; s2+=s1;}    {s1+=buf[i+2]; s2+=s1; s1+=buf[i+3]; s2+=s1;}
#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4); =>
						{s1+=buf[i]; s2+=s1; s1+=buf[i+1]; s2+=s1;}    {s1+=buf[i+2]; s2+=s1; s1+=buf[i+3]; s2+=s1;}
						{s1+=buf[i+4]; s2+=s1; s1+=buf[i+5]; s2+=s1;}    {s1+=buf[i+6]; s2+=s1; s1+=buf[i+7]; s2+=s1;}
#define DO16(buf)   DO8(buf,0); DO8(buf,8); =>
						{s1+=buf[i]; s2+=s1; s1+=buf[i+1]; s2+=s1;}    {s1+=buf[i+2]; s2+=s1; s1+=buf[i+3]; s2+=s1;
						s1+=buf[i+4]; s2+=s1; s1+=buf[i+5]; s2+=s1;}    {s1+=buf[i+6]; s2+=s1; s1+=buf[i+7]; s2+=s1;}

						{s1+=buf[i+8]; s2+=s1; s1+=buf[i+9]; s2+=s1;}    {s1+=buf[i+10]; s2+=s1; s1+=buf[i+11]; s2+=s1;
						s1+=buf[i+12]; s2+=s1; s1+=buf[i+13]; s2+=s1;}    {s1+=buf[i+14]; s2+=s1; s1+=buf[i+15]; s2+=s1;}
#define OF16(off)  {s1 += 16*off; s2 += 136*off;}

void RollsumUpdate(Rollsum *sum,const unsigned char *buf,unsigned int len) {
    // ANSI C says no overflow for unsigned.
    // zlib's adler 32 goes to extra effort to avoid overflow
    unsigned long s1 = sum->s1;
    unsigned long s2 = sum->s2;

    sum->count+=len;                   // increment sum count
    while (len >= 16) {
        DO16(buf);
        OF16(ROLLSUM_CHAR_OFFSET);
        buf += 16;
        len -= 16;
    }
    while (len != 0) {
        s1 += (*buf++ + ROLLSUM_CHAR_OFFSET);
        s2 += s1;
        len--;
    }
    sum->s1=s1;
    sum->s2=s2;
}
*/

func (rs *Rollsum) Update(p []byte) {
	var (
		s1, s2 uint64
		i      = 0
		l      = len(p)
	)

	rs.count += uint64(l)
	for l >= 16 {
		s1 += uint64(p[i])
		s2 += s1
		s1 += uint64(p[i+1])
		s2 += s1
		s1 += uint64(p[i+2])
		s2 += s1
		s1 += uint64(p[i+3])
		s2 += s1
		s1 += uint64(p[i+4])
		s2 += s1
		s1 += uint64(p[i+5])
		s2 += s1
		s1 += uint64(p[i+6])
		s2 += s1
		s1 += uint64(p[i+7])
		s2 += s1
		s1 += uint64(p[i+8])
		s2 += s1
		s1 += uint64(p[i+9])
		s2 += s1
		s1 += uint64(p[i+10])
		s2 += s1
		s1 += uint64(p[i+11])
		s2 += s1
		s1 += uint64(p[i+12])
		s2 += s1
		s1 += uint64(p[i+13])
		s2 += s1
		s1 += uint64(p[i+14])
		s2 += s1
		s1 += uint64(p[i+15])
		s2 += s1

		s1 += 16 * ROLLSUM_CHAR_OFFSET
		s2 += 136 * ROLLSUM_CHAR_OFFSET
		i += 16
		l -= 16
	}

	for l > 0 {
		s1 += ROLLSUM_CHAR_OFFSET + uint64(p[i])
		s2 += s1
		i++
		l--
	}

	rs.s1 = s1
	rs.s2 = s2
}
<commit_msg>fix spell error<commit_after>package rollsum

// librsync rollsum alg

const (
	ROLLSUM_CHAR_OFFSET uint64 = 31
)

/* the Rollsum struct type*/
type Rollsum struct {
	count uint64 /* count of bytes included in sum */
	s1    uint64 /* s1 part of sum */
	s2    uint64 /* s2 part of sum */
}

func (rs *Rollsum) Count() uint64 {
	return rs.count
}

func (rs *Rollsum) S1() uint64 {
	return rs.s1
}

func (rs *Rollsum) S2() uint64 {
	return rs.s2
}

func (rs *Rollsum) Init() {
	rs.count = 0
	rs.s1 = 0
	rs.s2 = 0
}

// golang: byte is an alias for uint8 and is equivalent to uint8 in all ways.
//         It is used, by convention, to distinguish byte values from 8-bit
//         unsigned integer values.
func (rs *Rollsum) Rotate(out, in byte) {
	rs.s1 += uint64(in)
	rs.s1 -= uint64(out)
	rs.s2 += rs.s1
	rs.s2 -= rs.count * (uint64(out) + ROLLSUM_CHAR_OFFSET)
}

func (rs *Rollsum) Rollin(c byte) {
	rs.s1 += uint64(c) + ROLLSUM_CHAR_OFFSET
	rs.s2 += rs.s1
	rs.count++
}

func (rs *Rollsum) Rollout(c byte) {
	rs.s1 -= uint64(c) + ROLLSUM_CHAR_OFFSET
	rs.s2 -= rs.count * (uint64(c) + ROLLSUM_CHAR_OFFSET)
	rs.count--
}

func (rs *Rollsum) Digest() uint32 {
	return uint32((rs.s2 << 16) | (rs.s1 & 0xffff))
}

/*
librsync rollsum.c

#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1); => {s1+=buf[i]; s2+=s1;}    {s1+=buf[i+1]; s2+=s1;}
#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2); => {s1+=buf[i]; s2+=s1; s1+=buf[i+1]; s2+=s1;}    {s1+=buf[i+2]; s2+=s1; s1+=buf[i+3]; s2+=s1;}
#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4); =>
						{s1+=buf[i]; s2+=s1; s1+=buf[i+1]; s2+=s1;}    {s1+=buf[i+2]; s2+=s1; s1+=buf[i+3]; s2+=s1;}
						{s1+=buf[i+4]; s2+=s1; s1+=buf[i+5]; s2+=s1;}    {s1+=buf[i+6]; s2+=s1; s1+=buf[i+7]; s2+=s1;}
#define DO16(buf)   DO8(buf,0); DO8(buf,8); =>
						{s1+=buf[i]; s2+=s1; s1+=buf[i+1]; s2+=s1;}    {s1+=buf[i+2]; s2+=s1; s1+=buf[i+3]; s2+=s1;
						s1+=buf[i+4]; s2+=s1; s1+=buf[i+5]; s2+=s1;}    {s1+=buf[i+6]; s2+=s1; s1+=buf[i+7]; s2+=s1;}

						{s1+=buf[i+8]; s2+=s1; s1+=buf[i+9]; s2+=s1;}    {s1+=buf[i+10]; s2+=s1; s1+=buf[i+11]; s2+=s1;
						s1+=buf[i+12]; s2+=s1; s1+=buf[i+13]; s2+=s1;}    {s1+=buf[i+14]; s2+=s1; s1+=buf[i+15]; s2+=s1;}
#define OF16(off)  {s1 += 16*off; s2 += 136*off;}

void RollsumUpdate(Rollsum *sum,const unsigned char *buf,unsigned int len) {
    // ANSI C says no overflow for unsigned.
    // zlib's adler 32 goes to extra effort to avoid overflow
    unsigned long s1 = sum->s1;
    unsigned long s2 = sum->s2;

    sum->count+=len;                   // increment sum count
    while (len >= 16) {
        DO16(buf);
        OF16(ROLLSUM_CHAR_OFFSET);
        buf += 16;
        len -= 16;
    }
    while (len != 0) {
        s1 += (*buf++ + ROLLSUM_CHAR_OFFSET);
        s2 += s1;
        len--;
    }
    sum->s1=s1;
    sum->s2=s2;
}
*/

func (rs *Rollsum) Update(p []byte) {
	var (
		s1, s2 uint64
		i      = 0
		l      = len(p)
	)

	rs.count += uint64(l)
	for l >= 16 {
		s1 += uint64(p[i])
		s2 += s1
		s1 += uint64(p[i+1])
		s2 += s1
		s1 += uint64(p[i+2])
		s2 += s1
		s1 += uint64(p[i+3])
		s2 += s1
		s1 += uint64(p[i+4])
		s2 += s1
		s1 += uint64(p[i+5])
		s2 += s1
		s1 += uint64(p[i+6])
		s2 += s1
		s1 += uint64(p[i+7])
		s2 += s1
		s1 += uint64(p[i+8])
		s2 += s1
		s1 += uint64(p[i+9])
		s2 += s1
		s1 += uint64(p[i+10])
		s2 += s1
		s1 += uint64(p[i+11])
		s2 += s1
		s1 += uint64(p[i+12])
		s2 += s1
		s1 += uint64(p[i+13])
		s2 += s1
		s1 += uint64(p[i+14])
		s2 += s1
		s1 += uint64(p[i+15])
		s2 += s1

		s1 += 16 * ROLLSUM_CHAR_OFFSET
		s2 += 136 * ROLLSUM_CHAR_OFFSET
		i += 16
		l -= 16
	}

	for l > 0 {
		s1 += ROLLSUM_CHAR_OFFSET + uint64(p[i])
		s2 += s1
		i++
		l--
	}

	rs.s1 = s1
	rs.s2 = s2
}
<|endoftext|>


<commit_before>package gogs

import (
	"io"
	"net/http"

	"github.com/drone/drone/model"
)

const (
	hookEvent       = "X-Gogs-Event"
	hookPush        = "push"
	hookCreated     = "create"
	hookPullRequest = "pull_request"

	actionOpen = "opened"
	actionSync = "synchronize"

	stateOpen = "open"

	refBranch = "branch"
	refTag    = "tag"
)

// parseHook parses a Bitbucket hook from an http.Request request and returns
// Repo and Build detail. If a hook type is unsupported nil values are returned.
func parseHook(r *http.Request) (*model.Repo, *model.Build, error) {
	switch r.Header.Get(hookEvent) {
	case hookPush:
		return parsePushHook(r.Body)
	case hookCreated:
		return parseCreatedHook(r.Body)
	case hookPullRequest:
		return parsePullRequestHook(r.Body)
	}
	return nil, nil, nil
}

// parsePushHook parses a push hook and returns the Repo and Build details.
// If the commit type is unsupported nil values are returned.
func parsePushHook(payload io.Reader) (*model.Repo, *model.Build, error) {
	var (
		repo  *model.Repo
		build *model.Build
	)

	push, err := parsePush(payload)
	if err != nil {
		return nil, nil, err
	}

	// is this even needed?
	if push.RefType == refBranch {
		return nil, nil, nil
	}

	repo = repoFromPush(push)
	build = buildFromPush(push)
	return repo, build, err
}

// parseCreatedHook parses a push hook and returns the Repo and Build details.
// If the commit type is unsupported nil values are returned.
func parseCreatedHook(payload io.Reader) (*model.Repo, *model.Build, error) {
	var (
		repo  *model.Repo
		build *model.Build
	)

	push, err := parsePush(payload)
	if err != nil {
		return nil, nil, err
	}

	if push.RefType != refTag {
		return nil, nil, nil
	}

	repo = repoFromPush(push)
	build = buildFromTag(push)
	return repo, build, err
}

// parsePullRequestHook parses a pull_request hook and returns the Repo and Build details.
func parsePullRequestHook(payload io.Reader) (*model.Repo, *model.Build, error) {
	var (
		repo  *model.Repo
		build *model.Build
	)

	pr, err := parsePullRequest(payload)
	if err != nil {
		return nil, nil, err
	}

	// Don't trigger builds for non-code changes, or if PR is not open
	if pr.Action != actionOpen && pr.Action != actionSync {
		return nil, nil, nil
	}
	if pr.PullRequest.State != stateOpen {
		return nil, nil, nil
	}

	repo = repoFromPullRequest(pr)
	build = buildFromPullRequest(pr)
	return repo, build, err
}
<commit_msg>Fix typo of gogs pull request synchronized action<commit_after>package gogs

import (
	"io"
	"net/http"

	"github.com/drone/drone/model"
)

const (
	hookEvent       = "X-Gogs-Event"
	hookPush        = "push"
	hookCreated     = "create"
	hookPullRequest = "pull_request"

	actionOpen = "opened"
	actionSync = "synchronized"

	stateOpen = "open"

	refBranch = "branch"
	refTag    = "tag"
)

// parseHook parses a Bitbucket hook from an http.Request request and returns
// Repo and Build detail. If a hook type is unsupported nil values are returned.
func parseHook(r *http.Request) (*model.Repo, *model.Build, error) {
	switch r.Header.Get(hookEvent) {
	case hookPush:
		return parsePushHook(r.Body)
	case hookCreated:
		return parseCreatedHook(r.Body)
	case hookPullRequest:
		return parsePullRequestHook(r.Body)
	}
	return nil, nil, nil
}

// parsePushHook parses a push hook and returns the Repo and Build details.
// If the commit type is unsupported nil values are returned.
func parsePushHook(payload io.Reader) (*model.Repo, *model.Build, error) {
	var (
		repo  *model.Repo
		build *model.Build
	)

	push, err := parsePush(payload)
	if err != nil {
		return nil, nil, err
	}

	// is this even needed?
	if push.RefType == refBranch {
		return nil, nil, nil
	}

	repo = repoFromPush(push)
	build = buildFromPush(push)
	return repo, build, err
}

// parseCreatedHook parses a push hook and returns the Repo and Build details.
// If the commit type is unsupported nil values are returned.
func parseCreatedHook(payload io.Reader) (*model.Repo, *model.Build, error) {
	var (
		repo  *model.Repo
		build *model.Build
	)

	push, err := parsePush(payload)
	if err != nil {
		return nil, nil, err
	}

	if push.RefType != refTag {
		return nil, nil, nil
	}

	repo = repoFromPush(push)
	build = buildFromTag(push)
	return repo, build, err
}

// parsePullRequestHook parses a pull_request hook and returns the Repo and Build details.
func parsePullRequestHook(payload io.Reader) (*model.Repo, *model.Build, error) {
	var (
		repo  *model.Repo
		build *model.Build
	)

	pr, err := parsePullRequest(payload)
	if err != nil {
		return nil, nil, err
	}

	// Don't trigger builds for non-code changes, or if PR is not open
	if pr.Action != actionOpen && pr.Action != actionSync {
		return nil, nil, nil
	}
	if pr.PullRequest.State != stateOpen {
		return nil, nil, nil
	}

	repo = repoFromPullRequest(pr)
	build = buildFromPullRequest(pr)
	return repo, build, err
}
<|endoftext|>


<commit_before>package match

import (
	"sync"
)

var segmentsPools [1024]*sync.Pool

func toPowerOfTwo(v int) int {
	v--
	v |= v >> 1
	v |= v >> 2
	v |= v >> 4
	v |= v >> 8
	v |= v >> 16
	v++

	return v
}

const (
	cacheFrom             = 16
	cacheToAndHigher      = 1024
	cacheFromIndex        = 15
	cacheToAndHigherIndex = 1023
)

var (
	segments0 = []int{0}
	segments1 = []int{1}
	segments2 = []int{2}
	segments3 = []int{3}
	segments4 = []int{4}
)

var segmentsByRuneLength [5][]int = [5][]int{
	0: segments0,
	1: segments1,
	2: segments2,
	3: segments3,
	4: segments4,
}

const (
	asciiLo = 0
	asciiHi = 127
)

func init() {
	for i := cacheToAndHigher; i >= cacheFrom; i >>= 1 {
		func(i int) {
			segmentsPools[i-1] = &sync.Pool{New: func() interface{} {
				return make([]int, 0, i)
			}}
		}(i)
	}
}

func getTableIndex(c int) int {
	p := toPowerOfTwo(c)
	switch {
	case p >= cacheToAndHigher:
		return cacheToAndHigherIndex
	case p <= cacheFrom:
		return cacheFromIndex
	default:
		return p - 1
	}
}

func acquireSegments(c int) []int {
	// make []int with less capacity than cacheFrom
	// is faster than acquiring it from pool
	if c < cacheFrom {
		return make([]int, 0, c)
	}

	return segmentsPools[getTableIndex(c)].Get().([]int)[:0]
}

func releaseSegments(s []int) {
	c := cap(s)

	// make []int with less capacity than cacheFrom
	// is faster than acquiring it from pool
	if c < cacheFrom {
		return
	}

	segmentsPools[getTableIndex(cap(s))].Put(s)
}
<commit_msg>try use pool with channel<commit_after>package match

import (
	"sync"
)

type SomePool interface {
	Get() []int
	Put([]int)
}

var segmentsPools [1024]SomePool

//var segmentsPools [1024]*sync.Pool

func toPowerOfTwo(v int) int {
	v--
	v |= v >> 1
	v |= v >> 2
	v |= v >> 4
	v |= v >> 8
	v |= v >> 16
	v++

	return v
}

const (
	cacheFrom             = 16
	cacheToAndHigher      = 1024
	cacheFromIndex        = 15
	cacheToAndHigherIndex = 1023
)

var (
	segments0 = []int{0}
	segments1 = []int{1}
	segments2 = []int{2}
	segments3 = []int{3}
	segments4 = []int{4}
)

var segmentsByRuneLength [5][]int = [5][]int{
	0: segments0,
	1: segments1,
	2: segments2,
	3: segments3,
	4: segments4,
}

const (
	asciiLo = 0
	asciiHi = 127
)

func init() {
	for i := cacheToAndHigher; i >= cacheFrom; i >>= 1 {
		func(i int) {
			//			segmentsPools[i-1] = &sync.Pool{New: func() interface{} {
			//				return make([]int, 0, i)
			//			}}
			segmentsPools[i-1] = newChanPool(func() []int {
				return make([]int, 0, i)
			})
		}(i)
	}
}

func getTableIndex(c int) int {
	p := toPowerOfTwo(c)
	switch {
	case p >= cacheToAndHigher:
		return cacheToAndHigherIndex
	case p <= cacheFrom:
		return cacheFromIndex
	default:
		return p - 1
	}
}

func acquireSegments(c int) []int {
	// make []int with less capacity than cacheFrom
	// is faster than acquiring it from pool
	if c < cacheFrom {
		return make([]int, 0, c)
	}

	//	return segmentsPools[getTableIndex(c)].Get().([]int)[:0]
	return segmentsPools[getTableIndex(c)].Get()
}

func releaseSegments(s []int) {
	c := cap(s)

	// make []int with less capacity than cacheFrom
	// is faster than acquiring it from pool
	if c < cacheFrom {
		return
	}

	segmentsPools[getTableIndex(c)].Put(s)
}

type maker func() []int

type syncPool struct {
	new  maker
	pool sync.Pool
}

func newSyncPool(m maker) *syncPool {
	return &syncPool{
		new: m,
		pool: sync.Pool{New: func() interface{} {
			return m()
		}},
	}
}

func (s *syncPool) Get() []int {
	return s.pool.Get().([]int)[:0]
}

func (s *syncPool) Put(x []int) {
	s.pool.Put(x)
}

type chanPool struct {
	pool  chan []int
	new   maker
	index int
}

func newChanPool(m maker) *chanPool {
	return &chanPool{
		pool: make(chan []int, 32),
		new:  m,
	}
}

func (c *chanPool) Get() []int {
	select {
	case s := <-c.pool:
		return s[:0]
	default:
		// pool is empty
		return c.new()
	}
}

func (c *chanPool) Put(s []int) {
	select {
	case c.pool <- s:
		// ok
	default:
		// pool is full
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/realglobe-Inc/edo/util"
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"github.com/realglobe-Inc/go-lib-rg/file"
	"github.com/realglobe-Inc/go-lib-rg/rglog/level"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

type parameters struct {
	// 画面表示ログ。
	consLv level.Level

	// 追加ログ。
	logType string
	logLv   level.Level

	// ファイルログ。
	idpLogPath string

	// fluentd ログ。
	fluAddr   string
	idpFluTag string

	// サービス検索。
	taExpType string

	// ファイルベースサービス検索。
	taExpPath string

	// Web ベースサービス検索。
	taExpAddr string

	// mongo サービス検索。
	taExpUrl  string
	taExpDb   string
	taExpColl string

	// 公開鍵レジストリ。
	taKeyRegType string

	// ファイルベース公開鍵レジストリ。
	taKeyRegPath string

	// Web ベース公開鍵レジストリ。
	taKeyRegAddr string

	// mongo 公開鍵レジストリ。
	taKeyRegUrl  string
	taKeyRegDb   string
	taKeyRegColl string

	// ユーザー名索引。
	usrNameIdxType string

	// ファイルベースユーザー名索引。
	usrNameIdxPath string

	// mongo ユーザー名索引。
	usrNameIdxUrl  string
	usrNameIdxDb   string
	usrNameIdxColl string

	// ユーザー属性レジストリ。
	usrAttrRegType string

	// ファイルベースユーザー属性レジストリ。
	usrAttrRegPath string

	// mongo ユーザー属性レジストリ。
	usrAttrRegUrl  string
	usrAttrRegDb   string
	usrAttrRegColl string

	// セッション管理。
	sessContType string

	// ファイルベースセッション管理。
	sessContPath string

	// mongo セッション管理。
	sessContUrl  string
	sessContDb   string
	sessContColl string

	// アクセストークン発行用コード管理。
	codeContType string

	// ファイルベースアクセストークン発行用コード管理。
	codeContPath string

	// mongo アクセストークン発行用コード管理。
	codeContUrl  string
	codeContDb   string
	codeContColl string

	// アクセストークン管理。
	accTokenContType string

	// ファイルベースアクセストークン管理。
	accTokenContPath string

	// mongo アクセストークン管理。
	accTokenContUrl  string
	accTokenContDb   string
	accTokenContColl string

	// ソケット。
	idpSocType string

	// UNIX ソケット。
	idpSocPath string

	// TCP ソケット。
	idpSocPort int

	// プロトコル。
	idpProtType string

	// 無通信での認証済みセッションの有効期間。
	maxSessExpiDur time.Duration // デフォルトかつ最大。

	// アクセストークン発行用コードの有効期間。
	codeExpiDur time.Duration

	// アクセストークンの有効期間。
	accTokenExpiDur    time.Duration // デフォルト。
	maxAccTokenExpiDur time.Duration
}

func parseParameters(args ...string) (param *parameters, err error) {

	flags := util.NewFlagSet("edo-id-provider parameters", flag.ExitOnError)
	flags.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage:")
		fmt.Fprintln(os.Stderr, "  "+args[0]+" [{FLAG}...]")
		fmt.Fprintln(os.Stderr, "FLAG:")
		flags.PrintDefaults()
	}

	param = &parameters{}

	flags.Var(level.Var(&param.consLv, level.INFO), "consLv", "Console log level.")
	flags.StringVar(&param.logType, "logType", "", "Extra log type.")
	flags.Var(level.Var(&param.logLv, level.ALL), "logLv", "Extra log level.")
	flags.StringVar(&param.idpLogPath, "idpLogPath", filepath.Join(os.TempDir(), "edo-id-provider.log"), "File log path.")
	flags.StringVar(&param.fluAddr, "fluAddr", "localhost:24224", "fluentd address.")
	flags.StringVar(&param.idpFluTag, "idpFluTag", "edo.id-provider", "fluentd tag.")

	flags.StringVar(&param.taExpType, "taExpType", "web", "TA explorer type.")
	flags.StringVar(&param.taExpPath, "taExpPath", filepath.Join("sandbox", "service-expolorer"), "TA explorer directory.")
	flags.StringVar(&param.taExpAddr, "taExpAddr", "http://localhost:16034", "TA explorer address.")
	flags.StringVar(&param.taExpUrl, "taExpUrl", "localhost", "TA explorer address.")
	flags.StringVar(&param.taExpDb, "taExpDb", "edo", "TA explorer database name.")
	flags.StringVar(&param.taExpColl, "taExpColl", "ta-explorer", "TA explorer collection name.")

	flags.StringVar(&param.taKeyRegType, "taKeyRegType", "web", "TA key provider type.")
	flags.StringVar(&param.taKeyRegPath, "taKeyRegPath", filepath.Join("sandbox", "ta-key-provider"), "TA key provider directory.")
	flags.StringVar(&param.taKeyRegAddr, "taKeyRegAddr", "http://localhost:16033", "TA key provider address.")
	flags.StringVar(&param.taKeyRegUrl, "taKeyRegUrl", "localhost", "TA key provider address.")
	flags.StringVar(&param.taKeyRegDb, "taKeyRegDb", "edo", "TA key provider database name.")
	flags.StringVar(&param.taKeyRegColl, "taKeyRegColl", "ta-key-provider", "TA key provider collection name.")

	flags.StringVar(&param.usrNameIdxType, "usrNameIdxType", "mongo", "Username index type.")
	flags.StringVar(&param.usrNameIdxPath, "usrNameIdxPath", filepath.Join("sandbox", "user-name-index"), "Username index directory.")
	flags.StringVar(&param.usrNameIdxUrl, "usrNameIdxUrl", "localhost", "Username index address.")
	flags.StringVar(&param.usrNameIdxDb, "usrNameIdxDb", "edo", "Username index database name.")
	flags.StringVar(&param.usrNameIdxColl, "usrNameIdxColl", "user-name-index", "Username index collection name.")

	flags.StringVar(&param.usrAttrRegType, "usrAttrRegType", "mongo", "User attribute registry type.")
	flags.StringVar(&param.usrAttrRegPath, "usrAttrRegPath", filepath.Join("sandbox", "user-attribute-registry"), "User attribute registry directory.")
	flags.StringVar(&param.usrAttrRegUrl, "usrAttrRegUrl", "localhost", "User attribute registry address.")
	flags.StringVar(&param.usrAttrRegDb, "usrAttrRegDb", "edo", "User attribute registry database name.")
	flags.StringVar(&param.usrAttrRegColl, "usrAttrRegColl", "user-attribute-registry", "User attribute registry collection name.")

	flags.StringVar(&param.sessContType, "sessContType", "mongo", "Session container lister type.")
	flags.StringVar(&param.sessContPath, "sessContPath", filepath.Join("sandbox", "session-container"), "Session container lister directory.")
	flags.StringVar(&param.sessContUrl, "sessContUrl", "localhost", "Session container lister address.")
	flags.StringVar(&param.sessContDb, "sessContDb", "edo", "Session container lister database name.")
	flags.StringVar(&param.sessContColl, "sessContColl", "session-container", "Session container lister collection name.")

	flags.StringVar(&param.codeContType, "codeContType", "mongo", "Code container lister type.")
	flags.StringVar(&param.codeContPath, "codeContPath", filepath.Join("sandbox", "code-container"), "Code container lister directory.")
	flags.StringVar(&param.codeContUrl, "codeContUrl", "localhost", "Code container lister address.")
	flags.StringVar(&param.codeContDb, "codeContDb", "edo", "Code container lister database name.")
	flags.StringVar(&param.codeContColl, "codeContColl", "code-container", "Code container lister collection name.")

	flags.StringVar(&param.accTokenContType, "accTokenContType", "mongo", "Access token container lister type.")
	flags.StringVar(&param.accTokenContPath, "accTokenContPath", filepath.Join("sandbox", "access-token-container"), "Access token container lister directory.")
	flags.StringVar(&param.accTokenContUrl, "accTokenContUrl", "localhost", "Access token container lister address.")
	flags.StringVar(&param.accTokenContDb, "accTokenContDb", "edo", "Access token container lister database name.")
	flags.StringVar(&param.accTokenContColl, "accTokenContColl", "access-token-container", "Access token container lister collection name.")

	flags.StringVar(&param.idpSocType, "idpSocType", "tcp", "Socket type.")
	flags.StringVar(&param.idpSocPath, "idpSocPath", filepath.Join(os.TempDir(), "edo-id-provider"), "UNIX socket path.")
	flags.IntVar(&param.idpSocPort, "idpSocPort", 8001, "TCP socket port.")

	flags.StringVar(&param.idpProtType, "idpProtType", "http", "Protocol type.")

	flags.DurationVar(&param.maxSessExpiDur, "maxSessExpiDur", 24*time.Hour, "Max session expiration duration.")
	flags.DurationVar(&param.codeExpiDur, "codeExpiDur", 10*time.Minute, "Code expiration duration.")
	flags.DurationVar(&param.accTokenExpiDur, "accTokenExpiDur", 24*time.Hour, "Default access token expiration duration.")
	flags.DurationVar(&param.maxAccTokenExpiDur, "maxAccTokenExpiDur", 30*24*time.Hour, "Max access token expiration duration.")

	var config string
	flags.StringVar(&config, "f", "", "Config file path.")

	// 実行引数を読んで、設定ファイルを指定させてから、
	// 設定ファイルを読んで、また実行引数を読む。
	flags.Parse(args[1:])
	if config != "" {
		if exist, err := file.IsExist(config); err != nil {
			return nil, erro.Wrap(err)
		} else if !exist {
			log.Warn("Config file " + config + " is not exist.")
		} else {
			buff, err := ioutil.ReadFile(config)
			if err != nil {
				return nil, erro.Wrap(err)
			}
			flags.CompleteParse(strings.Fields(string(buff)))
		}
	}
	flags.Parse(args[1:])

	if l := len(flags.Args()); l > 0 {
		log.Warn("Ignore extra parameters ", flags.Args(), ".")
	}

	return param, nil
}
<commit_msg>edo-id-provider のポート変更等<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/realglobe-Inc/edo/util"
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"github.com/realglobe-Inc/go-lib-rg/file"
	"github.com/realglobe-Inc/go-lib-rg/rglog/level"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

type parameters struct {
	// 画面表示ログ。
	consLv level.Level

	// 追加ログ。
	logType string
	logLv   level.Level

	// ファイルログ。
	idpLogPath string

	// fluentd ログ。
	fluAddr   string
	idpFluTag string

	// サービス検索。
	taExpType string

	// ファイルベースサービス検索。
	taExpPath string

	// Web ベースサービス検索。
	taExpAddr string

	// mongo サービス検索。
	taExpUrl  string
	taExpDb   string
	taExpColl string

	// 公開鍵レジストリ。
	taKeyRegType string

	// ファイルベース公開鍵レジストリ。
	taKeyRegPath string

	// Web ベース公開鍵レジストリ。
	taKeyRegAddr string

	// mongo 公開鍵レジストリ。
	taKeyRegUrl  string
	taKeyRegDb   string
	taKeyRegColl string

	// ユーザー名索引。
	usrNameIdxType string

	// ファイルベースユーザー名索引。
	usrNameIdxPath string

	// mongo ユーザー名索引。
	usrNameIdxUrl  string
	usrNameIdxDb   string
	usrNameIdxColl string

	// ユーザー属性レジストリ。
	usrAttrRegType string

	// ファイルベースユーザー属性レジストリ。
	usrAttrRegPath string

	// mongo ユーザー属性レジストリ。
	usrAttrRegUrl  string
	usrAttrRegDb   string
	usrAttrRegColl string

	// セッション管理。
	sessContType string

	// ファイルベースセッション管理。
	sessContPath string

	// mongo セッション管理。
	sessContUrl  string
	sessContDb   string
	sessContColl string

	// アクセストークン発行用コード管理。
	codeContType string

	// ファイルベースアクセストークン発行用コード管理。
	codeContPath string

	// mongo アクセストークン発行用コード管理。
	codeContUrl  string
	codeContDb   string
	codeContColl string

	// アクセストークン管理。
	accTokenContType string

	// ファイルベースアクセストークン管理。
	accTokenContPath string

	// mongo アクセストークン管理。
	accTokenContUrl  string
	accTokenContDb   string
	accTokenContColl string

	// ソケット。
	idpSocType string

	// UNIX ソケット。
	idpSocPath string

	// TCP ソケット。
	idpSocPort int

	// プロトコル。
	idpProtType string

	// 無通信での認証済みセッションの有効期間。
	maxSessExpiDur time.Duration // デフォルトかつ最大。

	// アクセストークン発行用コードの有効期間。
	codeExpiDur time.Duration

	// アクセストークンの有効期間。
	accTokenExpiDur    time.Duration // デフォルト。
	maxAccTokenExpiDur time.Duration
}

func parseParameters(args ...string) (param *parameters, err error) {

	const label = "id-provider"

	flags := util.NewFlagSet("edo-"+label+" parameters", flag.ExitOnError)
	flags.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage:")
		fmt.Fprintln(os.Stderr, "  "+args[0]+" [{FLAG}...]")
		fmt.Fprintln(os.Stderr, "FLAG:")
		flags.PrintDefaults()
	}

	param = &parameters{}

	flags.Var(level.Var(&param.consLv, level.INFO), "consLv", "Console log level.")
	flags.StringVar(&param.logType, "logType", "", "Extra log type.")
	flags.Var(level.Var(&param.logLv, level.ALL), "logLv", "Extra log level.")
	flags.StringVar(&param.idpLogPath, "idpLogPath", filepath.Join(os.TempDir(), "edo-"+label+".log"), "File log path.")
	flags.StringVar(&param.fluAddr, "fluAddr", "localhost:24224", "fluentd address.")
	flags.StringVar(&param.idpFluTag, "idpFluTag", "edo."+label, "fluentd tag.")

	flags.StringVar(&param.taExpType, "taExpType", "web", "TA explorer type.")
	flags.StringVar(&param.taExpPath, "taExpPath", filepath.Join("sandbox", "service-expolorer"), "TA explorer directory.")
	flags.StringVar(&param.taExpAddr, "taExpAddr", "http://localhost:16034", "TA explorer address.")
	flags.StringVar(&param.taExpUrl, "taExpUrl", "localhost", "TA explorer address.")
	flags.StringVar(&param.taExpDb, "taExpDb", "edo", "TA explorer database name.")
	flags.StringVar(&param.taExpColl, "taExpColl", "ta-explorer", "TA explorer collection name.")

	flags.StringVar(&param.taKeyRegType, "taKeyRegType", "web", "TA key provider type.")
	flags.StringVar(&param.taKeyRegPath, "taKeyRegPath", filepath.Join("sandbox", "ta-key-provider"), "TA key provider directory.")
	flags.StringVar(&param.taKeyRegAddr, "taKeyRegAddr", "http://localhost:16033", "TA key provider address.")
	flags.StringVar(&param.taKeyRegUrl, "taKeyRegUrl", "localhost", "TA key provider address.")
	flags.StringVar(&param.taKeyRegDb, "taKeyRegDb", "edo", "TA key provider database name.")
	flags.StringVar(&param.taKeyRegColl, "taKeyRegColl", "ta-key-provider", "TA key provider collection name.")

	flags.StringVar(&param.usrNameIdxType, "usrNameIdxType", "mongo", "Username index type.")
	flags.StringVar(&param.usrNameIdxPath, "usrNameIdxPath", filepath.Join("sandbox", "user-name-index"), "Username index directory.")
	flags.StringVar(&param.usrNameIdxUrl, "usrNameIdxUrl", "localhost", "Username index address.")
	flags.StringVar(&param.usrNameIdxDb, "usrNameIdxDb", "edo", "Username index database name.")
	flags.StringVar(&param.usrNameIdxColl, "usrNameIdxColl", "user-name-index", "Username index collection name.")

	flags.StringVar(&param.usrAttrRegType, "usrAttrRegType", "mongo", "User attribute registry type.")
	flags.StringVar(&param.usrAttrRegPath, "usrAttrRegPath", filepath.Join("sandbox", "user-attribute-registry"), "User attribute registry directory.")
	flags.StringVar(&param.usrAttrRegUrl, "usrAttrRegUrl", "localhost", "User attribute registry address.")
	flags.StringVar(&param.usrAttrRegDb, "usrAttrRegDb", "edo", "User attribute registry database name.")
	flags.StringVar(&param.usrAttrRegColl, "usrAttrRegColl", "user-attribute-registry", "User attribute registry collection name.")

	flags.StringVar(&param.sessContType, "sessContType", "mongo", "Session container lister type.")
	flags.StringVar(&param.sessContPath, "sessContPath", filepath.Join("sandbox", "session-container"), "Session container lister directory.")
	flags.StringVar(&param.sessContUrl, "sessContUrl", "localhost", "Session container lister address.")
	flags.StringVar(&param.sessContDb, "sessContDb", "edo", "Session container lister database name.")
	flags.StringVar(&param.sessContColl, "sessContColl", "session-container", "Session container lister collection name.")

	flags.StringVar(&param.codeContType, "codeContType", "mongo", "Code container lister type.")
	flags.StringVar(&param.codeContPath, "codeContPath", filepath.Join("sandbox", "code-container"), "Code container lister directory.")
	flags.StringVar(&param.codeContUrl, "codeContUrl", "localhost", "Code container lister address.")
	flags.StringVar(&param.codeContDb, "codeContDb", "edo", "Code container lister database name.")
	flags.StringVar(&param.codeContColl, "codeContColl", "code-container", "Code container lister collection name.")

	flags.StringVar(&param.accTokenContType, "accTokenContType", "mongo", "Access token container lister type.")
	flags.StringVar(&param.accTokenContPath, "accTokenContPath", filepath.Join("sandbox", "access-token-container"), "Access token container lister directory.")
	flags.StringVar(&param.accTokenContUrl, "accTokenContUrl", "localhost", "Access token container lister address.")
	flags.StringVar(&param.accTokenContDb, "accTokenContDb", "edo", "Access token container lister database name.")
	flags.StringVar(&param.accTokenContColl, "accTokenContColl", "access-token-container", "Access token container lister collection name.")

	flags.StringVar(&param.idpSocType, "idpSocType", "tcp", "Socket type.")
	flags.StringVar(&param.idpSocPath, "idpSocPath", filepath.Join(os.TempDir(), "edo-"+label), "UNIX socket path.")
	flags.IntVar(&param.idpSocPort, "idpSocPort", 16040, "TCP socket port.")

	flags.StringVar(&param.idpProtType, "idpProtType", "http", "Protocol type.")

	flags.DurationVar(&param.maxSessExpiDur, "maxSessExpiDur", 24*time.Hour, "Max session expiration duration.")
	flags.DurationVar(&param.codeExpiDur, "codeExpiDur", 10*time.Minute, "Code expiration duration.")
	flags.DurationVar(&param.accTokenExpiDur, "accTokenExpiDur", 24*time.Hour, "Default access token expiration duration.")
	flags.DurationVar(&param.maxAccTokenExpiDur, "maxAccTokenExpiDur", 30*24*time.Hour, "Max access token expiration duration.")

	var config string
	flags.StringVar(&config, "f", "", "Config file path.")

	// 実行引数を読んで、設定ファイルを指定させてから、
	// 設定ファイルを読んで、また実行引数を読む。
	flags.Parse(args[1:])
	if config != "" {
		if exist, err := file.IsExist(config); err != nil {
			return nil, erro.Wrap(err)
		} else if !exist {
			log.Warn("Config file " + config + " is not exist.")
		} else {
			buff, err := ioutil.ReadFile(config)
			if err != nil {
				return nil, erro.Wrap(err)
			}
			flags.CompleteParse(strings.Fields(string(buff)))
		}
	}
	flags.Parse(args[1:])

	if l := len(flags.Args()); l > 0 {
		log.Warn("Ignore extra parameters ", flags.Args(), ".")
	}

	return param, nil
}
<|endoftext|>


<commit_before>// go-rst - A reStructuredText parser for Go
// 2014 (c) The go-rst Authors
// MIT Licensed. See LICENSE for details.
package parse

import (
	"fmt"
	"github.com/demizer/go-elog"
	"unicode/utf8"
)

type itemElement int

const (
	itemEOF itemElement = iota
	itemError
	itemTitle
	itemSectionAdornment
	itemParagraph
	itemBlockquote
	itemLiteralBlock
	itemSystemMessage
	itemSpace
	itemBlankLine
)

var elements = [...]string{
	"itemEOF",
	"itemError",
	"itemTitle",
	"itemSectionAdornment",
	"itemParagraph",
	"itemBlockquote",
	"itemLiteralBlock",
	"itemSystemMessage",
	"itemSpace",
	"itemBlankLine",
}

func (t itemElement) String() string { return elements[t] }

var sectionAdornments = []rune{'!', '"', '#', '$', '\'', '%', '&', '(', ')', '*',
	'+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\',
	']', '^', '_', '`', '{', '|', '}', '~'}

const EOF rune = -1

type stateFn func(*lexer) stateFn

type item struct {
	ElementName string
	ElementType itemElement
	Position    Pos
	Line        int
	Value       interface{}
}

type systemMessageLevel int

const (
	levelInfo systemMessageLevel = iota
	levelWarning
	levelError
	levelSevere
)

var systemMessageLevels = [...]string{
	"INFO",
	"WARNING",
	"ERROR",
	"SEVERE",
}

func (s systemMessageLevel) String() string { return systemMessageLevels[s] }

type systemMessage struct {
	level  systemMessageLevel
	line   int
	source string
	items  []item
}

type lexer struct {
	name    string
	input   string
	state   stateFn
	pos     Pos
	start   Pos
	width   Pos
	lastPos Pos
	items   chan item
	line    int
}

func lex(name, input string) *lexer {
	l := &lexer{
		name:  name,
		input: input,
		line: 1,
		items: make(chan item),
	}
	go l.run()
	return l
}

// emit passes an item back to the client.
func (l *lexer) emit(t itemElement) {
	log.Debugf("\tEmit %s!\n", t)
	l.items <- item{ElementType: t, ElementName: fmt.Sprint(t),
		Position: l.start, Line: l.line, Value: l.input[l.start:l.pos]}
	l.start = l.pos

}

func (l *lexer) backup() {
	l.pos -= l.width
}

func (l *lexer) current() rune {
	r, _ := utf8.DecodeRuneInString(l.input[l.pos:])
	return r
}

func (l *lexer) previous() rune {
	l.backup()
	r := l.current()
	l.next()
	return r
}

func (l *lexer) peek() rune {
	r := l.next()
	l.backup()
	return r
}

func (l *lexer) skip() {
	l.start += 1
        l.next()
}

func (l *lexer) advance(to rune) {
	for {
		if l.next() == EOF || to == l.current() {
			break
		}
	}
}

// next returns the next rune in the input.
func (l *lexer) next() rune {
	if int(l.pos) >= len(l.input) {
		log.Debugln("Reached EOF!")
		l.width = 0
		return EOF
	}
	r, w := utf8.DecodeRuneInString(l.input[l.pos:])
	l.width = Pos(w)
	l.pos += l.width
	return r
}

// nextItem returns the next item from the input.
func (l *lexer) nextItem() item {
	item := <-l.items
	l.lastPos = item.Position
	return item

}

func (l *lexer) run() {
	for l.state = lexStart; l.state != nil; {
		l.state = l.state(l)
	}
}

// isWhiteSpace reports whether r is a space character.
func isWhiteSpace(r rune) bool {
	return r == ' ' || r == '\t' || r == '\n' || r == '\r'
}

// isEndOfLine reports whether r is an end-of-line character.
func isEndOfLine(r rune) bool {
	return r == '\r' || r == '\n'
}

func lexStart(l *lexer) stateFn {
	log.Debugln("\nTransition lexStart...")
	for {
		if len(l.input) == 0 {
			log.Debugln("\tEmit EOF!")
			l.emit(itemEOF)
			return nil
		}

		log.Debugf("\tlexStart: %q, Start: %d, Pos: %d, Line: %d\n",
			l.input[l.start:l.pos], l.start, l.pos, l.line)

		switch r := l.current(); {
		case isSectionAdornment(r) && isSectionAdornment(l.peek()) && l.pos == 1:
			log.Debugln("Transition lexSection...")
			return lexSection
		case isEndOfLine(r):
			log.Debugln("\tFound newline!")
			l.line += 1
			if isSectionAdornment(l.peek()) {
				log.Debugln("Transition lexSection...")
				return lexSection
			}
			if l.pos > l.start {
				l.emit(itemParagraph)
			}
			l.ignore()
		}
		if l.next() == EOF {
			break
		}
	}

	// Correctly reached EOF.
	if l.pos > l.start {
		l.emit(itemParagraph)
	}

	l.emit(itemEOF)
	return nil
}

func lexSection(l *lexer) stateFn {
	if len(l.input) > 0 {
		log.Debugf("\tlexSection: %q, Pos: %d\n",
			l.input[l.start:l.pos], l.pos)
	}

	if isEndOfLine(l.peek()) {
		l.emit(itemTitle)
		l.ignore()
	}

Loop:
	for {
		switch r := l.next(); {
		case isSectionAdornment(r):
			if len(l.input) > 0 {
				log.Debugf("\tlexSection: %q, Pos: %d\n",
					l.input[l.start:l.pos], l.pos)
			}
		case isEndOfLine(r):
			l.backup()
			l.emit(itemSectionAdornment)
			l.line += 1
			l.ignore()
			break Loop
		}
	}
	return lexStart
}

func isSectionAdornment(r rune) bool {
	for _, a := range sectionAdornments {
		if a == r {
			return true
		}
	}
	return false
}
<commit_msg>lex.go: Refactor lexStart()<commit_after>// go-rst - A reStructuredText parser for Go
// 2014 (c) The go-rst Authors
// MIT Licensed. See LICENSE for details.
package parse

import (
	"fmt"
	"github.com/demizer/go-elog"
	"unicode/utf8"
)

type itemElement int

const (
	itemEOF itemElement = iota
	itemError
	itemTitle
	itemSectionAdornment
	itemParagraph
	itemBlockquote
	itemLiteralBlock
	itemSystemMessage
	itemSpace
	itemBlankLine
)

var elements = [...]string{
	"itemEOF",
	"itemError",
	"itemTitle",
	"itemSectionAdornment",
	"itemParagraph",
	"itemBlockquote",
	"itemLiteralBlock",
	"itemSystemMessage",
	"itemSpace",
	"itemBlankLine",
}

func (t itemElement) String() string { return elements[t] }

var sectionAdornments = []rune{'!', '"', '#', '$', '\'', '%', '&', '(', ')', '*',
	'+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\',
	']', '^', '_', '`', '{', '|', '}', '~'}

const EOF rune = -1

type stateFn func(*lexer) stateFn

type item struct {
	ElementName string
	ElementType itemElement
	Position    Pos
	Line        int
	Value       interface{}
}

type systemMessageLevel int

const (
	levelInfo systemMessageLevel = iota
	levelWarning
	levelError
	levelSevere
)

var systemMessageLevels = [...]string{
	"INFO",
	"WARNING",
	"ERROR",
	"SEVERE",
}

func (s systemMessageLevel) String() string { return systemMessageLevels[s] }

type systemMessage struct {
	level  systemMessageLevel
	line   int
	source string
	items  []item
}

type lexer struct {
	name    string
	input   string
	state   stateFn
	pos     Pos
	start   Pos
	width   Pos
	lastPos Pos
	items   chan item
	line    int
}

func lex(name, input string) *lexer {
	l := &lexer{
		name:  name,
		input: input,
		line: 1,
		items: make(chan item),
	}
	go l.run()
	return l
}

// emit passes an item back to the client.
func (l *lexer) emit(t itemElement) {
	l.items <- item{ElementType: t, ElementName: fmt.Sprint(t),
		Position: l.start, Line: l.line, Value: l.input[l.start:l.pos]}
	log.Debugf("%s: %q\n", t, l.input[l.start:l.pos])
	l.start = l.pos
}

func (l *lexer) backup() {
	l.pos -= l.width
}

func (l *lexer) current() rune {
	r, _ := utf8.DecodeRuneInString(l.input[l.pos:])
	return r
}

func (l *lexer) previous() rune {
	l.backup()
	r := l.current()
	l.next()
	return r
}

func (l *lexer) peek() rune {
	r := l.next()
	l.backup()
	return r
}

func (l *lexer) skip() {
	l.start += 1
        l.next()
}

func (l *lexer) advance(to rune) {
	for {
		if l.next() == EOF || to == l.current() {
			break
		}
	}
}

func (l *lexer) next() rune {
	if int(l.pos) >= len(l.input) {
		log.Debugln("Reached EOF!")
		l.width = 0
		return EOF
	}
	r, w := utf8.DecodeRuneInString(l.input[l.pos:])
	l.width = Pos(w)
	l.pos += l.width
	return r
}

// nextItem returns the next item from the input.
func (l *lexer) nextItem() item {
	item := <-l.items
	l.lastPos = item.Position
	return item

}

func (l *lexer) run() {
	for l.state = lexStart; l.state != nil; {
		l.state = l.state(l)
	}
}

// isWhiteSpace reports whether r is a space character.
func isWhiteSpace(r rune) bool {
	return r == ' ' || r == '\t' || r == '\n' || r == '\r'
}

// isEndOfLine reports whether r is an end-of-line character.
func isEndOfLine(r rune) bool {
	return r == '\r' || r == '\n'
}

func lexStart(l *lexer) stateFn {
	log.Debugln("\nTransition...")
	for {
		if len(l.input) == 0 {
			l.emit(itemEOF)
			return nil
		}

		if l.pos > l.start {
			log.Debugf("%q, Current: %q, Start: %d, Pos: %d, Line: %d\n",
				l.input[l.start:l.pos], l.current(), l.start, l.pos, l.line)
		}

		isStartOfToken := l.start == l.pos-l.width

		switch r := l.current(); {
		case isStartOfToken:
			if isWhiteSpace(r) {
				lexWhiteSpace(l)
			}
			if isSection(l) {
				return lexSection
			}
			l.next()
		case isEndOfLine(r):
			if l.pos > l.start {
				l.emit(itemParagraph)
			}
			l.line += 1
			l.skip() // Skip the newline
		}
		if l.next() == EOF {
			break
		}
	}

	// Correctly reached EOF.
	if l.pos > l.start {
		l.emit(itemParagraph)
	}

	l.emit(itemEOF)
	return nil
}

func lexSection(l *lexer) stateFn {
	if len(l.input) > 0 {
		log.Debugf("\tlexSection: %q, Pos: %d\n",
			l.input[l.start:l.pos], l.pos)
	}

	if isEndOfLine(l.peek()) {
		l.emit(itemTitle)
		l.ignore()
	}

Loop:
	for {
		switch r := l.next(); {
		case isSectionAdornment(r):
			if len(l.input) > 0 {
				log.Debugf("\tlexSection: %q, Pos: %d\n",
					l.input[l.start:l.pos], l.pos)
			}
		case isEndOfLine(r):
			l.backup()
			l.emit(itemSectionAdornment)
			l.line += 1
			l.ignore()
			break Loop
		}
	}
	return lexStart
}

func isSectionAdornment(r rune) bool {
	for _, a := range sectionAdornments {
		if a == r {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package extractor

import (
	"bytes"
	"io/ioutil"
	"net/url"
	"strings"

	"github.com/dunglas/calavera/schema"
	"github.com/PuerkitoBio/goquery"
	"github.com/russross/blackfriday"
)

type Markdown struct {
}

func (markdown Markdown) Extract(creativeWork *schema.CreativeWork, path string) error {
	markdownContent, err := ioutil.ReadFile(path)
	if nil != err {
		return err
	}

	html := blackfriday.MarkdownCommon(markdownContent)

	doc, err := goquery.NewDocumentFromReader(bytes.NewReader(html))
	if nil != err {
		return err
	}

	doc.Find("a[href]").Each(func(i int, s *goquery.Selection) {
		link, _ := s.Attr("href")
		url, _ := url.Parse(link)

		if !url.IsAbs() {
			s.SetAttr("href", strings.Replace(link, ".md", ".jsonld", 1))
		}
	})

	creativeWork.Name = doc.Find("h1").Text()
	creativeWork.Text, err = doc.Find("body").Html()
	if nil != err {
		return err
	}

	return nil
}
<commit_msg>Sanitize HTML<commit_after>package extractor

import (
	"bytes"
	"io/ioutil"
	"net/url"
	"strings"

	"github.com/dunglas/calavera/schema"
	"github.com/PuerkitoBio/goquery"
	"github.com/microcosm-cc/bluemonday"
	"github.com/russross/blackfriday"
)

type Markdown struct {
}

func (markdown Markdown) Extract(creativeWork *schema.CreativeWork, path string) error {
	markdownContent, err := ioutil.ReadFile(path)
	if nil != err {
		return err
	}

	unsafe := blackfriday.MarkdownCommon(markdownContent)
	html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)

	doc, err := goquery.NewDocumentFromReader(bytes.NewReader(html))
	if nil != err {
		return err
	}

	doc.Find("a[href]").Each(func(i int, s *goquery.Selection) {
		link, _ := s.Attr("href")
		url, _ := url.Parse(link)

		if !url.IsAbs() {
			s.SetAttr("href", strings.Replace(link, ".md", ".jsonld", 1))
		}
	})

	creativeWork.Name = doc.Find("h1").Text()
	creativeWork.Text, err = doc.Find("body").Html()
	if nil != err {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"syscall"
	"time"
)

type Service struct {
	Name       string `json:"name"`
	BridgeName string
	BridgeIP   string `json:"bridge-ip"`
	NginxConf  string `json:"nginx-config"`
	Pid        int
	Containers []Container
	NginxUpStream
}

type Container struct {
	Name        string
	ServiceName string `json:"service-name"`
	Command     string `json:"command"`
	Pid         int
	IP          string
	StartTime   time.Time
	VEth        string
}

type NginxUpStream struct {
	LoadBalanceType string
	Servers         []string
	UpStreamConfig  string `json:"nginx-upstream"`
}

var services map[string]Service
var containers []Container

const (
	bridgeNameBase = "brocker"
	vethNameBase   = "veth"
)

func (c *Container) setName() {
	value := fmt.Sprintf("%s%s%s", c.Name, c.StartTime, c.Command)
	sha := sha1.New()
	sha.Write([]byte(value))
	c.Name = hex.EncodeToString(sha.Sum(nil))[:8]
}

func (s *Service) reload() {
	if err := execInContainter(fmt.Sprintf("/usr/sbin/nginx -s reload -c %s", s.NginxConf), s.Pid); err != nil {
		fmt.Println("Cannot reload nginx: ", err)
		return
	}
}

func (n *NginxUpStream) writeConfig() {
	if _, err := os.Stat(n.UpStreamConfig); os.IsNotExist(err) {
		fmt.Println("Cannot update config", err)
		return
	}

	var buffer bytes.Buffer
	buffer.WriteString("upstream myapp1 {\n")
	buffer.WriteString(n.LoadBalanceType)
	buffer.WriteString(";\n")
	for _, s := range n.Servers {
		buffer.WriteString(fmt.Sprintf("server %s;\n", s))
	}
	buffer.WriteString("\n}")

	if err := ioutil.WriteFile(n.UpStreamConfig, buffer.Bytes(), 0644); err != nil {
		fmt.Println(err)
		return
	}
}

func init() {
	services = make(map[string]Service)
}

func main() {
	http.HandleFunc("/api/v1/service/add", service_add)
	http.HandleFunc("/api/v1/container/run", container_run)
	http.HandleFunc("/api/v1/container/list", container_list)
	http.HandleFunc("/api/v1/container/exec", container_exec)
	err := http.ListenAndServe(":3000", nil)
	if err != nil {
		fmt.Println(err)
	}
}

func service_add(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Invalid Request!", http.StatusMethodNotAllowed)
		return
	}

	var s Service
	if err := json.NewDecoder(r.Body).Decode(&s); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if _, ok := services[s.Name]; ok {
		http.Error(w, "Service already exists", http.StatusInternalServerError)
		return
	}

	if _, err := os.Stat(s.NginxConf); os.IsNotExist(err) {
		http.Error(w, fmt.Sprintf("Cannot open %s\n%s", s.NginxConf, err.Error()), http.StatusInternalServerError)
		return
	}

	s.BridgeName = fmt.Sprintf("%s%d", bridgeNameBase, len(services)+1)

	s.LoadBalanceType = "least_conn"
	if err := service_create_network(s); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	path, err := exec.LookPath("nginx")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	c := Container{
		Name:        fmt.Sprintf("%s-nginx", s.Name),
		ServiceName: s.Name,
		Command:     fmt.Sprintf("%s -c %s", path, s.NginxConf),
	}

	go run(c, true)

	w.WriteHeader(http.StatusCreated)
}

func container_run(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Invalid Request!", http.StatusMethodNotAllowed)
		return
	}

	var c Container
	if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if _, ok := services[c.ServiceName]; ok == false {
		http.Error(w, "Service does not exists", http.StatusInternalServerError)
		return
	}

	go run(c, false)

	w.WriteHeader(http.StatusCreated)
}

func container_list(w http.ResponseWriter, r *http.Request) {
	if err := json.NewEncoder(w).Encode(containers); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func container_exec(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Invalid Request!", http.StatusMethodNotAllowed)
		return
	}

	data := struct {
		Name string `json:"name"`
	}{}
	if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	for _, c := range containers {
		if c.Name == data.Name {
			w.Write([]byte(fmt.Sprintf("%d", c.Pid)))
			return
		}
	}
}

func service_create_network(s Service) error {
	create_bridge := strings.Split(fmt.Sprintf("/sbin/ip link add name %s type bridge", s.BridgeName), " ")
	set_bridge_up := strings.Split(fmt.Sprintf("/sbin/ip link set %s up", s.BridgeName), " ")
	set_bridge_ip := strings.Split(fmt.Sprintf("/sbin/ifconfig %s %s", s.BridgeName, s.BridgeIP), " ")

	if err := exec.Command(create_bridge[0], create_bridge[1:]...).Run(); err != nil {
		return err
	}

	if err := exec.Command(set_bridge_up[0], set_bridge_up[1:]...).Run(); err != nil {
		return err
	}

	if err := exec.Command(set_bridge_ip[0], set_bridge_ip[1:]...).Run(); err != nil {
		return err
	}

	services[s.Name] = s
	return nil
}

func run(c Container, isNginx bool) {
	fmt.Println("running parent")
	s := services[c.ServiceName]
	runcmd := "/home/yup/p/containers/brocker-run/brocker-run"

	cmd := &exec.Cmd{
		Path: runcmd,
		Args: append([]string{runcmd}, c.Command),
	}
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWPID |
			syscall.CLONE_NEWNS |
			syscall.CLONE_NEWNET,
	}

	if err := cmd.Start(); err != nil {
		fmt.Println(err)
	}

	c.Pid = cmd.Process.Pid
	c.VEth = fmt.Sprintf("%s%d", vethNameBase, len(containers))
	link := strings.Split(fmt.Sprintf("/sbin/ip link add name %s type veth peer name veth1 netns %d", c.VEth, c.Pid), " ")
	if err := exec.Command(link[0], link[1:]...).Run(); err != nil {
		fmt.Println(err)
		return
	}

	uplink := strings.Split(fmt.Sprintf("/sbin/ifconfig %s up", c.VEth), " ")
	if err := exec.Command(uplink[0], uplink[1:]...).Run(); err != nil {
		fmt.Println(err)
		return
	}

	bridge := strings.Split(fmt.Sprintf("/sbin/ip link set %s master %s", c.VEth, s.BridgeName), " ")
	if err := exec.Command(bridge[0], bridge[1:]...).Run(); err != nil {
		fmt.Println(err)
		return
	}

	bridgeip := net.ParseIP(s.BridgeIP)
	lastOctet := bridgeip[15] + byte(len(s.Containers)+1)
	ip := net.IPv4(bridgeip[12], bridgeip[13], bridgeip[14], lastOctet)
	c.IP = ip.String()

	if err := execInContainter(fmt.Sprintf("/sbin/ifconfig veth1 %s", ip.String()), c.Pid); err != nil {
		fmt.Println(err)
		return
	}

	c.StartTime = time.Now()
	c.setName()
	containers = append(containers, c)

	s.Containers = append(s.Containers, c)
	if isNginx {
		s.Pid = c.Pid
	} else {
		s.Servers = append(s.Servers, fmt.Sprintf("%s:8080", c.IP))
		s.writeConfig()
		s.reload()
	}
	services[c.ServiceName] = s

	fmt.Println(cmd.Process.Pid)

	cmd.Wait()
}

func execInContainter(cmd string, pid int) error {
	command := strings.Split(fmt.Sprintf("nsenter --target %d --pid --net --mount %s", pid, cmd), " ")
	if err := exec.Command(command[0], command[1:]...).Run(); err != nil {
		return err
	}

	return nil
}
<commit_msg>Now starts mounting<commit_after>package main

import (
	"bytes"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"syscall"
	"time"
)

type Service struct {
	Name       string `json:"name"`
	BridgeName string
	BridgeIP   string `json:"bridge-ip"`
	NginxConf  string `json:"nginx-config"`
	Pid        int
	Containers []Container
	NginxUpStream
}

type Container struct {
	Name        string
	ServiceName string `json:"service-name"`
	Command     string `json:"command"`
	Pid         int
	IP          string
	StartTime   time.Time
	VEth        string
}

type NginxUpStream struct {
	LoadBalanceType string
	Servers         []string
	UpStreamConfig  string `json:"nginx-upstream"`
}

var services map[string]Service
var containers []Container

const (
	bridgeNameBase = "brocker"
	vethNameBase   = "veth"
	MOUNT_LOC      = "/app"
	CONTAIN_DIR    = "/container"
)

func (c *Container) setName() {
	value := fmt.Sprintf("%s%s%s", c.Name, c.StartTime, c.Command)
	sha := sha1.New()
	sha.Write([]byte(value))
	c.Name = hex.EncodeToString(sha.Sum(nil))[:8]
}

func (s *Service) reload() {
	if err := execInContainter(fmt.Sprintf("/usr/sbin/nginx -s reload -c %s", s.NginxConf), s.Pid); err != nil {
		fmt.Println("Cannot reload nginx: ", err)
		return
	}
}

func (n *NginxUpStream) writeConfig() {
	if _, err := os.Stat(n.UpStreamConfig); os.IsNotExist(err) {
		fmt.Println("Cannot update config", err)
		return
	}

	var buffer bytes.Buffer
	buffer.WriteString("upstream myapp1 {\n")
	buffer.WriteString(n.LoadBalanceType)
	buffer.WriteString(";\n")
	for _, s := range n.Servers {
		buffer.WriteString(fmt.Sprintf("server %s;\n", s))
	}
	buffer.WriteString("\n}")

	if err := ioutil.WriteFile(n.UpStreamConfig, buffer.Bytes(), 0644); err != nil {
		fmt.Println(err)
		return
	}
}

func init() {
	services = make(map[string]Service)
}

func main() {
	http.HandleFunc("/api/v1/service/add", service_add)
	http.HandleFunc("/api/v1/container/run", container_run)
	http.HandleFunc("/api/v1/container/list", container_list)
	http.HandleFunc("/api/v1/container/exec", container_exec)
	err := http.ListenAndServe(":3000", nil)
	if err != nil {
		fmt.Println(err)
	}
}

func service_add(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Invalid Request!", http.StatusMethodNotAllowed)
		return
	}

	var s Service
	if err := json.NewDecoder(r.Body).Decode(&s); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if _, ok := services[s.Name]; ok {
		http.Error(w, "Service already exists", http.StatusInternalServerError)
		return
	}

	if _, err := os.Stat(s.NginxConf); os.IsNotExist(err) {
		http.Error(w, fmt.Sprintf("Cannot open %s\n%s", s.NginxConf, err.Error()), http.StatusInternalServerError)
		return
	}

	s.BridgeName = fmt.Sprintf("%s%d", bridgeNameBase, len(services)+1)

	s.LoadBalanceType = "least_conn"
	if err := service_create_network(s); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	path, err := exec.LookPath("nginx")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	c := Container{
		Name:        fmt.Sprintf("%s-nginx", s.Name),
		ServiceName: s.Name,
		Command:     fmt.Sprintf("%s -c %s", path, s.NginxConf),
	}

	go run(c, true)

	w.WriteHeader(http.StatusCreated)
}

func container_run(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Invalid Request!", http.StatusMethodNotAllowed)
		return
	}

	var c Container
	if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if _, ok := services[c.ServiceName]; ok == false {
		http.Error(w, "Service does not exists", http.StatusInternalServerError)
		return
	}

	go run(c, false)

	w.WriteHeader(http.StatusCreated)
}

func container_list(w http.ResponseWriter, r *http.Request) {
	if err := json.NewEncoder(w).Encode(containers); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func container_exec(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Invalid Request!", http.StatusMethodNotAllowed)
		return
	}

	data := struct {
		Name string `json:"name"`
	}{}
	if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	for _, c := range containers {
		if c.Name == data.Name {
			w.Write([]byte(fmt.Sprintf("%d", c.Pid)))
			return
		}
	}
}

func service_create_network(s Service) error {
	create_bridge := strings.Split(fmt.Sprintf("/sbin/ip link add name %s type bridge", s.BridgeName), " ")
	set_bridge_up := strings.Split(fmt.Sprintf("/sbin/ip link set %s up", s.BridgeName), " ")
	set_bridge_ip := strings.Split(fmt.Sprintf("/sbin/ifconfig %s %s", s.BridgeName, s.BridgeIP), " ")

	if err := exec.Command(create_bridge[0], create_bridge[1:]...).Run(); err != nil {
		return err
	}

	if err := exec.Command(set_bridge_up[0], set_bridge_up[1:]...).Run(); err != nil {
		return err
	}

	if err := exec.Command(set_bridge_ip[0], set_bridge_ip[1:]...).Run(); err != nil {
		return err
	}

	services[s.Name] = s
	return nil
}

func run(c Container, isNginx bool) {
	fmt.Println("running parent")
	s := services[c.ServiceName]
	runcmd := "/home/yup/p/containers/brocker-run/brocker-run"

	cmd := &exec.Cmd{
		Path: runcmd,
		Args: append([]string{runcmd}, c.Command),
	}
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWPID |
			syscall.CLONE_NEWNS |
			syscall.CLONE_NEWNET,
	}

	if err := cmd.Start(); err != nil {
		fmt.Println(err)
	}

	c.Pid = cmd.Process.Pid
	c.VEth = fmt.Sprintf("%s%d", vethNameBase, len(containers))
	link := strings.Split(fmt.Sprintf("/sbin/ip link add name %s type veth peer name veth1 netns %d", c.VEth, c.Pid), " ")
	if err := exec.Command(link[0], link[1:]...).Run(); err != nil {
		fmt.Println(err)
		return
	}

	uplink := strings.Split(fmt.Sprintf("/sbin/ifconfig %s up", c.VEth), " ")
	if err := exec.Command(uplink[0], uplink[1:]...).Run(); err != nil {
		fmt.Println(err)
		return
	}

	bridge := strings.Split(fmt.Sprintf("/sbin/ip link set %s master %s", c.VEth, s.BridgeName), " ")
	if err := exec.Command(bridge[0], bridge[1:]...).Run(); err != nil {
		fmt.Println(err)
		return
	}

	bridgeip := net.ParseIP(s.BridgeIP)
	lastOctet := bridgeip[15] + byte(len(s.Containers)+1)
	ip := net.IPv4(bridgeip[12], bridgeip[13], bridgeip[14], lastOctet)
	c.IP = ip.String()

	if err := execInContainter(fmt.Sprintf("/sbin/ifconfig veth1 %s", ip.String()), c.Pid); err != nil {
		fmt.Println(err)
		return
	}

	/*
		Allows the use of CLONE_NEWNS on ubuntu boxes. util-linux <= 2.27 have issues
		with systemd making / shared across all namespaces
	*/
	if err := execInContainter("/bin/mount --make-private -o remount /", c.Pid); err != nil {
		fmt.Println(err)
		return
	}

	if err := os.Mkdir(fmt.Sprintf("%s/%s", CONTAIN_DIR, c.Name), 0644); err != nil {
		fmt.Println(err)
		return
	}

	if err := execInContainter(fmt.Sprintf("/bin/mount --bind %s/%s %s", CONTAIN_DIR, c.Name, MOUNT_LOC), c.Pid); err != nil {
		fmt.Println(err)
		return
	}

	c.StartTime = time.Now()
	c.setName()
	containers = append(containers, c)

	s.Containers = append(s.Containers, c)
	if isNginx {
		s.Pid = c.Pid
	} else {
		s.Servers = append(s.Servers, fmt.Sprintf("%s:8080", c.IP))
		s.writeConfig()
		s.reload()
	}
	services[c.ServiceName] = s

	fmt.Println(cmd.Process.Pid)

	cmd.Wait()
}

func execInContainter(cmd string, pid int) error {
	command := strings.Split(fmt.Sprintf("nsenter --target %d --pid --net --mount %s", pid, cmd), " ")
	if err := exec.Command(command[0], command[1:]...).Run(); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package fbtron

import (
  "testing"
)

func TestSetStat(t *testing.T) {
  p := new(Player)
  p.SetStat("test", 1.0)
  if v:= p.GetStat("test"); v != 1.0 {
    t.Errorf("Failure to set/get a stat: expected 1.0, got %f", v)
  }
}

func TestWinsPerDraft(t *testing.T) {
  p := new(Player)
  p.Num_seasons = 10
  if v := p.WinsPerDraft(); v != 0.0 {
    t.Errorf("Failure to get WinsPerDraft: expected 0.0, got %f", v)
  }

  p.Total_wins = 15
  if v := p.WinsPerDraft(); v != 1.5 {
    t.Errorf("Failure to get WinsPerDraft: expected 1.5, got %f", v)
  }

  p.ResetWins()
  if v := p.WinsPerDraft(); v != 0.0 {
    t.Errorf("Failure to get WinsPerDraft: expected 0.0, got %f", v)
  }
}

func TestBuildPlayersFromCsv(t *testing.T) {
  var players []*Player

  // Pass empty file, expect empty array
  players = BuildPlayersFromCsv("testdata/players_csv_empty.csv", "")
  if len(players) > 0 {
    t.Errorf("BuildPlayersFromCsv: expected empty array, got %s", players)
  }

  // Pass file with just a header, expect empty array
  players = BuildPlayersFromCsv("testdata/players_csv_headeronly.csv", "")
  if len(players) > 0 {
    t.Errorf("BuildPlayersFromCsv: expected empty array, got %s", players)
  }

  // Pass broken csv, expect empty array
  players = BuildPlayersFromCsv("testdata/players_csv_broken.csv", "")
  if len(players) > 0 {
    t.Errorf("BuildPlayersFromCsv: expected empty array, got %s", players)
  }

  // Pass csv with a header and a record, expect one-player array back
  players = BuildPlayersFromCsv("testdata/players_csv_ok.csv", "SP")
  if len(players) != 5 {
    t.Errorf("BuildPlayersFromCsv: expected 5 players, got %d:\n%s",
             len(players), players)
  } else {
    if v := players[0].GetName(); v != "Foo Bar" {
      t.Errorf("BuildPlayerFromCsvRecord: expected name Foo Bar, got '%s'", v)
    }
    if v := players[0].GetStat("R"); v != 100 {
      t.Errorf("BuildPlayerFromCsv: expected R=100, got %f", v)
    }
    if v := players[0].GetStat("RBI"); v != 200 {
      t.Errorf("BuildPlayerFromCsv: expected RBI=200, got %f", v)
    }
    if v := players[0].positions; len(v) != 1 || v[0] != "SP" {
      t.Errorf("BuildPlayerFromCsv: expected position SP, got %s", v)
    }
  }
}

func TestBuildPlayerFromCsvRecord(t *testing.T) {
  var player *Player

  // Pass empty arrays, expect nil
  player = BuildPlayerFromCsvRecord([]string {}, []string {}, "")
  if (player != nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected nil, got %s",
             player)
  }

  // Pass header array but empty data, expect nil
  player = BuildPlayerFromCsvRecord(
      []string {"Firstname", "Lastname", "R", "RBI"},
      []string {},
      "")
  if (player != nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected nil, got %s",
             player)
  }

  // Pass data but empty header, expect nil
  player = BuildPlayerFromCsvRecord(
      []string {},
      []string {"Foo", "Bar", "100", "200"},
      "")
  if (player != nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected nil, got %s",
             player)
  }

  // Pass data and header, expect Player
  player = BuildPlayerFromCsvRecord(
      []string {"Firstname", "Lastname", "R", "RBI"},
      []string {"Foo", "Bar", "100", "200"},
      "SP")
  if (player == nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected Player, got nil")
  }
  if v := player.GetName(); v != "Foo Bar" {
    t.Errorf("BuildPlayerFromCsvRecord: expected name Foo Bar, got '%s'", v)
  }
  if v := player.GetStat("R"); v != 100 {
    t.Errorf("BuildPlayerFromCsvRecord: expected R=100, got %f", v)
  }
  if v := player.GetStat("RBI"); v != 200 {
    t.Errorf("BuildPlayerFromCsvRecord: expected RBI=200, got %f", v)
  }
  if v := player.positions; len(v) != 1 || v[0] != "SP" {
    t.Errorf("BuildPlayerFromCsvRecord: expected position SP, got %s", v)
  }

  // TODO: Player with same position as default
  // TODO: Empty string as default
}
<commit_msg>Fix test capitalization<commit_after>package fbtron

import (
  "testing"
)

func TestSetStat(t *testing.T) {
  p := new(Player)
  p.SetStat("test", 1.0)
  if v:= p.GetStat("test"); v != 1.0 {
    t.Errorf("Failure to set/get a stat: expected 1.0, got %f", v)
  }
}

func TestWinsPerDraft(t *testing.T) {
  p := new(Player)
  p.Num_seasons = 10
  if v := p.WinsPerDraft(); v != 0.0 {
    t.Errorf("Failure to get WinsPerDraft: expected 0.0, got %f", v)
  }

  p.Total_wins = 15
  if v := p.WinsPerDraft(); v != 1.5 {
    t.Errorf("Failure to get WinsPerDraft: expected 1.5, got %f", v)
  }

  p.ResetWins()
  if v := p.WinsPerDraft(); v != 0.0 {
    t.Errorf("Failure to get WinsPerDraft: expected 0.0, got %f", v)
  }
}

func TestBuildPlayersFromCsv(t *testing.T) {
  var players []*Player

  // Pass empty file, expect empty array
  players = BuildPlayersFromCsv("testdata/players_csv_empty.csv", "")
  if len(players) > 0 {
    t.Errorf("BuildPlayersFromCsv: expected empty array, got %s", players)
  }

  // Pass file with just a header, expect empty array
  players = BuildPlayersFromCsv("testdata/players_csv_headeronly.csv", "")
  if len(players) > 0 {
    t.Errorf("BuildPlayersFromCsv: expected empty array, got %s", players)
  }

  // Pass broken csv, expect empty array
  players = BuildPlayersFromCsv("testdata/players_csv_broken.csv", "")
  if len(players) > 0 {
    t.Errorf("BuildPlayersFromCsv: expected empty array, got %s", players)
  }

  // Pass csv with a header and a record, expect one-player array back
  players = BuildPlayersFromCsv("testdata/players_csv_ok.csv", "SP")
  if len(players) != 5 {
    t.Errorf("BuildPlayersFromCsv: expected 5 players, got %d:\n%s",
             len(players), players)
  } else {
    if v := players[0].GetName(); v != "Foo Bar" {
      t.Errorf("BuildPlayerFromCsvRecord: expected name Foo Bar, got '%s'", v)
    }
    if v := players[0].GetStat("R"); v != 100 {
      t.Errorf("BuildPlayerFromCsv: expected R=100, got %f", v)
    }
    if v := players[0].GetStat("RBI"); v != 200 {
      t.Errorf("BuildPlayerFromCsv: expected RBI=200, got %f", v)
    }
    if v := players[0].positions; len(v) != 1 || v[0] != "SP" {
      t.Errorf("BuildPlayerFromCsv: expected position SP, got %s", v)
    }
  }
}

func TestBuildPlayerFromCsvRecord(t *testing.T) {
  var player *Player

  // Pass empty arrays, expect nil
  player = BuildPlayerFromCsvRecord([]string {}, []string {}, "")
  if (player != nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected nil, got %s",
             player)
  }

  // Pass header array but empty data, expect nil
  player = BuildPlayerFromCsvRecord(
      []string {"firstname", "lastname", "R", "RBI"},
      []string {},
      "")
  if (player != nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected nil, got %s",
             player)
  }

  // Pass data but empty header, expect nil
  player = BuildPlayerFromCsvRecord(
      []string {},
      []string {"Foo", "Bar", "100", "200"},
      "")
  if (player != nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected nil, got %s",
             player)
  }

  // Pass data and header, expect Player
  player = BuildPlayerFromCsvRecord(
      []string {"firstname", "lastname", "R", "RBI"},
      []string {"Foo", "Bar", "100", "200"},
      "SP")
  if (player == nil) {
    t.Errorf("BuildPlayerFromCsvRecord: expected Player, got nil")
  }
  if v := player.GetName(); v != "Foo Bar" {
    t.Errorf("BuildPlayerFromCsvRecord: expected name Foo Bar, got '%s'", v)
  }
  if v := player.GetStat("R"); v != 100 {
    t.Errorf("BuildPlayerFromCsvRecord: expected R=100, got %f", v)
  }
  if v := player.GetStat("RBI"); v != 200 {
    t.Errorf("BuildPlayerFromCsvRecord: expected RBI=200, got %f", v)
  }
  if v := player.positions; len(v) != 1 || v[0] != "SP" {
    t.Errorf("BuildPlayerFromCsvRecord: expected position SP, got %s", v)
  }

  // TODO: Player with same position as default
  // TODO: Empty string as default
}
<|endoftext|>


<commit_before>package secretcrypt

import (
	"bytes"
	"testing"
)

func passthrough(plaintext string) {
	crypted, err := Encrypt("testphrase", []byte(plaintext))
	if err != nil {
		panic(err)
	}

	plain, err := Decrypt("testphrase", crypted)
	if err != nil {
		panic(err)
	}

	if !bytes.Equal(plain, []byte(plain)) {
		panic("expected correct plaintext")
	}
}

func TestEncryptDecryptDoesNotCorrupt(t *testing.T) {
	passthrough("test")
	passthrough("")
	passthrough("t")
}
<commit_msg>Fix test bug, improve test edge case coverage.<commit_after>package secretcrypt

import (
	"bytes"
	"testing"
	"math/rand"
)

func passthrough(passphrase string, plaintext []byte) {
	crypted, err := Encrypt(passphrase, plaintext)
	if err != nil {
		panic(err)
	}

	plainResult, err := Decrypt(passphrase, crypted)
	if err != nil {
		panic(err)
	}

	if !bytes.Equal(plainResult, plaintext) {
		panic("expected correct plaintext")
	}
}

func TestEncryptDecryptDoesNotCorrupt(t *testing.T) {
	rand.NewSource(0)
	rSource := rand.NewSource(0)
	r := rand.New(rSource)

	// Choose a small number of sizes for performance reasons. Because key stretching happens on every
	// call, we're slow.
	plaintextLens := []int{0, 5, 64000, 128000}
	for i := 0; i < len(plaintextLens); i++ {
		b := make([]byte, plaintextLens[i])

		r.Read(b)
		passthrough("testphrase", b)
	}
}
<|endoftext|>