<commit_before>package consul

import (
	"os"
	"os/exec"
	"testing"
	"time"

	"github.com/portworx/kvdb"
	"github.com/portworx/kvdb/test"
	"github.com/stretchr/testify/assert"
)

var (
	cmd *exec.Cmd
)

func TestAll(t *testing.T) {
	// Run the common test suite
	test.Run(New, t, Start, Stop)

	// Run consul specific tests
	err := Start()
	assert.NoError(t, err, "Unable to start kvdb")
	// Wait for kvdb to start
	time.Sleep(5 * time.Second)

	kv, err := New("pwx/test", nil, nil, nil)
	if err != nil {
		t.Fatalf(err.Error())
	}
	createUsingCAS(kv, t)
	err = Stop()
	assert.NoError(t, err, "Unable to stop kvdb")
}

func createUsingCAS(kv kvdb.Kvdb, t *testing.T) {
	defer func() {
		_ = kv.DeleteTree("foo")
	}()
	kvPair := &kvdb.KVPair{Key: "foo/createKey", ModifiedIndex: 0}
	_, err := kv.CompareAndSet(kvPair, kvdb.KVModifiedIndex, []byte("some"))
	assert.NoError(t, err, "CompareAndSet failed on create")

	kvPair, err = kv.Get("foo/createKey")
	assert.NoError(t, err, "Failed in Get")

	kvPair.ModifiedIndex = 0
	_, err = kv.CompareAndSet(kvPair, kvdb.KVModifiedIndex, []byte("some"))
	assert.Error(t, err, "CompareAndSet did not fail on create")
}
func Start() error {
	os.RemoveAll("/tmp/consul")
	os.MkdirAll("/tmp/consul", os.ModeDir)

	//consul agent -server -client=0.0.0.0  -data-dir /opt/consul/data -bind 0.0.0.0 -syslog -bootstrap-expect 1 -advertise 127.0.0.1
	cmd = exec.Command("consul", "agent", "-server", "-advertise", "127.0.0.1", "-bind", "0.0.0.0", "-data-dir", "/tmp/consul", "-syslog", "-bootstrap-expect", "1")
	return cmd.Start()
}

func Stop() error {
	return cmd.Process.Kill()
}
<commit_msg>Modify the consul run command.<commit_after>package consul

import (
	"os"
	"os/exec"
	"testing"
	"time"

	"github.com/portworx/kvdb"
	"github.com/portworx/kvdb/test"
	"github.com/stretchr/testify/assert"
)

var (
	cmd *exec.Cmd
)

func TestAll(t *testing.T) {
	// Run the common test suite
	test.Run(New, t, Start, Stop)

	// Run consul specific tests
	err := Start()
	assert.NoError(t, err, "Unable to start kvdb")
	// Wait for kvdb to start
	time.Sleep(5 * time.Second)

	kv, err := New("pwx/test", nil, nil, nil)
	if err != nil {
		t.Fatalf(err.Error())
	}
	createUsingCAS(kv, t)
	err = Stop()
	assert.NoError(t, err, "Unable to stop kvdb")
}

func createUsingCAS(kv kvdb.Kvdb, t *testing.T) {
	defer func() {
		_ = kv.DeleteTree("foo")
	}()
	kvPair := &kvdb.KVPair{Key: "foo/createKey", ModifiedIndex: 0}
	_, err := kv.CompareAndSet(kvPair, kvdb.KVModifiedIndex, []byte("some"))
	assert.NoError(t, err, "CompareAndSet failed on create")

	kvPair, err = kv.Get("foo/createKey")
	assert.NoError(t, err, "Failed in Get")

	kvPair.ModifiedIndex = 0
	_, err = kv.CompareAndSet(kvPair, kvdb.KVModifiedIndex, []byte("some"))
	assert.Error(t, err, "CompareAndSet did not fail on create")
}
func Start() error {
	os.RemoveAll("/tmp/consul")
	os.MkdirAll("/tmp/consul", os.ModeDir)

	//consul agent -server -client=0.0.0.0  -data-dir /opt/consul/data -bind 0.0.0.0 -syslog -bootstrap-expect 1 -advertise 127.0.0.1
	cmd = exec.Command("consul", "agent", "-server", "-advertise", "127.0.0.1", "-bind", "0.0.0.0", "-data-dir", "/tmp/consul", "-bootstrap-expect", "1")
	return cmd.Start()
}

func Stop() error {
	return cmd.Process.Kill()
}
<|endoftext|>


<commit_before>package websocket

import (
	"net/http"
	"sync"

	log "github.com/Sirupsen/logrus"
)

const (
	//GeneralChannel represents a channel broadcasting to all active connections
	GeneralChannel string = "general"
)

//Hub is broadcasting into and reading from websockets
type Hub interface {
	Broadcast(msg Message, channel string)
	RegisterConnection(writer http.ResponseWriter, req *http.Request, channels []string) (*Connection, error)
	RegisterOnChannels(c *Connection, channels []string)
	RegisterListener(channel string, l ConnListener)
	RegisterOnConnectListener(l OnConnectListener)
}

//OnConnectListener gets notified when a new connection is registered by the hub
type OnConnectListener interface {
	OnConnection(c *Connection)
}

//ConnListener is a Connection listener interface
type ConnListener interface {
	Handle(msg []byte)
	Supports(messageType int) bool
}

//hub maintains a list of active channels with associated websocket connections
type hub struct {
	sync.Mutex
	//channels is a hashmap of hashmaps containing connections
	channels   map[string]map[string]*Connection
	listeners  map[string][]ConnListener
	clisteners []OnConnectListener
	factory    ConnectionFactory
}

//NewHub is a hub constructor
func NewHub() Hub {
	h := hub{
		channels:   make(map[string]map[string]*Connection),
		listeners:  make(map[string][]ConnListener),
		clisteners: []OnConnectListener{},
		factory:    &gorillaFactory{},
	}
	h.channels[GeneralChannel] = make(map[string]*Connection)
	return Hub(&h)
}

func (h *hub) RegisterOnChannels(c *Connection, channels []string) {
	h.Lock()
	defer h.Unlock()
	for _, ch := range channels {
		if _, ok := h.channels[ch]; !ok {
			h.channels[ch] = make(map[string]*Connection)
		}
		h.channels[ch][c.ID] = c
	}
	go h.listen(c)
	go h.callOnConnectListeners(c)
}

func (h *hub) RegisterConnection(writer http.ResponseWriter, req *http.Request, channels []string) (*Connection, error) {
	var (
		err error
		c   *Connection
	)
	if c, err = h.factory.UpgradeConnection(writer, req, channels); err != nil {
		return c, err
	}
	if log.GetLevel() >= log.InfoLevel {
		log.WithFields(log.Fields{"logger": "ws.hub.register", "connection": c.ID, "remote": c.Remote, "channels": channels}).
			Info("Registering a websocket Connection")
	}

	go c.WriteLoop()
	go c.ReadLoop()
	h.RegisterOnChannels(c, channels)

	return c, nil
}

func (h *hub) RegisterListener(ch string, l ConnListener) {
	if log.GetLevel() >= log.InfoLevel {
		log.WithFields(log.Fields{"logger": "ws.hub.listener", "channel": ch}).
			Info("Registering a channel listener")
	}
	h.listeners[ch] = append(h.listeners[ch], l)
}

func (h *hub) RegisterOnConnectListener(l OnConnectListener) {
	if log.GetLevel() >= log.InfoLevel {
		log.WithFields(log.Fields{"logger": "ws.hub.listener"}).
			Info("Registering onConnect listener")
	}
	h.clisteners = append(h.clisteners, l)
}

func (h *hub) Broadcast(msg Message, ch string) {
	for _, c := range h.channels[ch] {
		if log.GetLevel() >= log.DebugLevel {
			log.WithFields(log.Fields{"logger": "ws.hub.broadcast", "remote": c.Remote, "id": c.ID, "channel": ch}).
				Debug("Sending message into websocket")
		}

		if c.GetState() == StateOpen {
			c.Out <- msg
		}
	}
}

func (h *hub) listen(c *Connection) {
	defer h.remove(c)
	for {
		select {
		case msg, ok := <-c.In:
			if !ok {
				log.WithFields(log.Fields{"logger": "ws.hub.listen", "Connection": c.ID}).
					Info("Input channel is closed; aborting read loop")
				return
			}
			h.callListeners(c, msg)
		case <-c.control:
			// the connection was closed
			return
		}
	}
}

func (h *hub) remove(c *Connection) {
	h.Lock()
	defer h.Unlock()
	//delete the connection from broadcast channels
	for _, ch := range c.Channels {
		delete(h.channels[ch], c.ID)
	}
}

func (h *hub) callOnConnectListeners(c *Connection) {
	for _, l := range h.clisteners {
		l.OnConnection(c)
	}
}

func (h *hub) callListeners(c *Connection, msg Message) {
	if log.GetLevel() >= log.DebugLevel {
		if msg.MessageType == TextMessage {
			log.WithFields(log.Fields{"logger": "ws.hub.listen", "connection": c.ID, "msg": string(msg.Payload)}).
				Debug("Calling listeners associated with the connection")
		} else {
			log.WithFields(log.Fields{"logger": "ws.hub.listen", "connection": c.ID}).
				Debug("Calling listeners associated with the connection")
		}
	}
	for _, ch := range c.Channels {
		for _, l := range h.listeners[ch] {
			if l.Supports(msg.MessageType) {
				l.Handle(msg.Payload)
			}
		}
	}
}
<commit_msg>refac(log): improved logging<commit_after>package websocket

import (
	"net/http"
	"sync"

	log "github.com/Sirupsen/logrus"
)

const (
	//GeneralChannel represents a channel broadcasting to all active connections
	GeneralChannel string = "general"
)

//Hub is broadcasting into and reading from websockets
type Hub interface {
	Broadcast(msg Message, channel string)
	RegisterConnection(writer http.ResponseWriter, req *http.Request, channels []string) (*Connection, error)
	RegisterOnChannels(c *Connection, channels []string)
	RegisterListener(channel string, l ConnListener)
	RegisterOnConnectListener(l OnConnectListener)
}

//OnConnectListener gets notified when a new connection is registered by the hub
type OnConnectListener interface {
	OnConnection(c *Connection)
}

//ConnListener is a Connection listener interface
type ConnListener interface {
	Handle(msg []byte)
	Supports(messageType int) bool
}

//hub maintains a list of active channels with associated websocket connections
type hub struct {
	sync.Mutex
	//channels is a hashmap of hashmaps containing connections
	channels   map[string]map[string]*Connection
	listeners  map[string][]ConnListener
	clisteners []OnConnectListener
	factory    ConnectionFactory
}

//NewHub is a hub constructor
func NewHub() Hub {
	h := hub{
		channels:   make(map[string]map[string]*Connection),
		listeners:  make(map[string][]ConnListener),
		clisteners: []OnConnectListener{},
		factory:    &gorillaFactory{},
	}
	h.channels[GeneralChannel] = make(map[string]*Connection)
	return Hub(&h)
}

func (h *hub) RegisterOnChannels(c *Connection, channels []string) {
	h.Lock()
	defer h.Unlock()
	for _, ch := range channels {
		if _, ok := h.channels[ch]; !ok {
			h.channels[ch] = make(map[string]*Connection)
		}
		h.channels[ch][c.ID] = c
	}
	go h.listen(c)
	go h.callOnConnectListeners(c)
}

func (h *hub) RegisterConnection(writer http.ResponseWriter, req *http.Request, channels []string) (*Connection, error) {
	var (
		err error
		c   *Connection
	)
	if c, err = h.factory.UpgradeConnection(writer, req, channels); err != nil {
		return c, err
	}
	if log.GetLevel() >= log.InfoLevel {
		log.WithFields(log.Fields{"logger": "ws.hub.register", "connection": c.ID, "remote": c.Remote, "channels": channels}).
			Info("Registering a websocket Connection")
	}

	go c.WriteLoop()
	go c.ReadLoop()
	h.RegisterOnChannels(c, channels)

	return c, nil
}

func (h *hub) RegisterListener(ch string, l ConnListener) {
	if log.GetLevel() >= log.InfoLevel {
		log.WithFields(log.Fields{"logger": "ws.hub.listener", "channel": ch}).
			Info("Registering a channel listener")
	}
	h.listeners[ch] = append(h.listeners[ch], l)
}

func (h *hub) RegisterOnConnectListener(l OnConnectListener) {
	if log.GetLevel() >= log.InfoLevel {
		log.WithFields(log.Fields{"logger": "ws.hub.listener"}).
			Info("Registering onConnect listener")
	}
	h.clisteners = append(h.clisteners, l)
}

func (h *hub) Broadcast(msg Message, ch string) {
	for _, c := range h.channels[ch] {
		if c.GetState() == StateOpen {
			if log.GetLevel() >= log.DebugLevel {
				log.WithFields(log.Fields{"logger": "ws.hub.broadcast", "remote": c.Remote, "id": c.ID, "channel": ch}).
					Debug("Sending message into websocket")
			}
			c.Out <- msg
		}
	}
}

func (h *hub) listen(c *Connection) {
	defer h.remove(c)
	for {
		select {
		case msg, ok := <-c.In:
			if !ok {
				log.WithFields(log.Fields{"logger": "ws.hub.listen", "Connection": c.ID}).
					Info("Input channel is closed; aborting read loop")
				return
			}
			h.callListeners(c, msg)
		case <-c.control:
			// the connection was closed
			return
		}
	}
}

func (h *hub) remove(c *Connection) {
	h.Lock()
	defer h.Unlock()
	//delete the connection from broadcast channels
	for _, ch := range c.Channels {
		delete(h.channels[ch], c.ID)
	}
}

func (h *hub) callOnConnectListeners(c *Connection) {
	for _, l := range h.clisteners {
		l.OnConnection(c)
	}
}

func (h *hub) callListeners(c *Connection, msg Message) {
	if log.GetLevel() >= log.DebugLevel {
		if msg.MessageType == TextMessage {
			log.WithFields(log.Fields{"logger": "ws.hub.listen", "connection": c.ID, "msg": string(msg.Payload)}).
				Debug("Calling listeners associated with the connection")
		} else {
			log.WithFields(log.Fields{"logger": "ws.hub.listen", "connection": c.ID}).
				Debug("Calling listeners associated with the connection")
		}
	}
	for _, ch := range c.Channels {
		for _, l := range h.listeners[ch] {
			if l.Supports(msg.MessageType) {
				l.Handle(msg.Payload)
			}
		}
	}
}
<|endoftext|>


<commit_before>// Package hub provides a simple event dispatcher for publish/subscribe pattern.
package hub

import "sync"

// Event is an interface for published events.
type Event interface {
	Kind() int
}

// Hub is an event dispatcher, publishes events to the subscribers
// which are subscribed for a specific event type.
type Hub struct {
	subscribers map[int][]func(Event)
	sync.RWMutex
}

// New returns pointer to a new Hub.
func New() *Hub {
	return &Hub{subscribers: make(map[int][]func(Event))}
}

// Subscribe for the event of specific kind.
// The caller must receive messages from the retured channel.
// Otherwise, the next Publish() will hang.
func (h *Hub) Subscribe(kind int, handler func(Event)) {
	h.Lock()
	h.subscribers[kind] = append(h.subscribers[kind], handler)
	h.Unlock()
}

// Publish an event to the subscribers.
func (h *Hub) Publish(e Event) {
	h.RLock()
	if handlers, ok := h.subscribers[e.Kind()]; ok {
		for _, handler := range handlers {
			handler(e)
		}
	}
	h.RUnlock()
}

// DefaultHub is the default Hub used by Publish and Subscribe.
var DefaultHub = New()

// Subscribe for the event of specific kind in the DefaultHub.
func Subscribe(kind int, handler func(Event)) {
	DefaultHub.Subscribe(kind, handler)
}

// Publish an event to the subscribers in DefaultHub.
func Publish(e Event) {
	DefaultHub.Publish(e)
}
<commit_msg>dont embed mutex<commit_after>// Package hub provides a simple event dispatcher for publish/subscribe pattern.
package hub

import "sync"

// Event is an interface for published events.
type Event interface {
	Kind() int
}

// Hub is an event dispatcher, publishes events to the subscribers
// which are subscribed for a specific event type.
type Hub struct {
	subscribers map[int][]func(Event)
	m           sync.RWMutex
}

// New returns pointer to a new Hub.
func New() *Hub {
	return &Hub{subscribers: make(map[int][]func(Event))}
}

// Subscribe for the event of specific kind.
// The caller must receive messages from the retured channel.
// Otherwise, the next Publish() will hang.
func (h *Hub) Subscribe(kind int, handler func(Event)) {
	h.m.Lock()
	h.subscribers[kind] = append(h.subscribers[kind], handler)
	h.m.Unlock()
}

// Publish an event to the subscribers.
func (h *Hub) Publish(e Event) {
	h.m.RLock()
	if handlers, ok := h.subscribers[e.Kind()]; ok {
		for _, handler := range handlers {
			handler(e)
		}
	}
	h.m.RUnlock()
}

// DefaultHub is the default Hub used by Publish and Subscribe.
var DefaultHub = New()

// Subscribe for the event of specific kind in the DefaultHub.
func Subscribe(kind int, handler func(Event)) {
	DefaultHub.Subscribe(kind, handler)
}

// Publish an event to the subscribers in DefaultHub.
func Publish(e Event) {
	DefaultHub.Publish(e)
}
<|endoftext|>


<commit_before>// Copyright 2013 Travis Keep. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or
// at http://opensource.org/licenses/BSD-3-Clause.

// Package gohue controls hue lights.
package gohue

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
  "net/url"
)

const (
  // Bright represents the brightest setting
  Bright = uint8(255)

  // Dim represents the dimmest setting.
  Dim = uint8(0)
)

const (
  maxu16 = float64(10000.0)
)

// Color represents a particular color and brightness. Programs using Colors
// should typically store and pass them as values, not pointers.
type Color struct {
  x uint16
  y uint16
  bri uint8
}

// NewColor returns a new Color. x and y are the coordinates of the color
// in the color XY space; brightness is the brightness where 255 is brightest
// and 0 is dimmest.
func NewColor(x, y float64, brightness uint8) Color {
  return Color{x: uint16(x * maxu16), y: uint16(y * maxu16), bri: brightness}
}

// X returns the X value of this Color.
func (c Color) X() float64 {
  return float64(c.x) / maxu16
}

// Y returns the Y value of this Color.
func (c Color) Y() float64 {
  return float64(c.y) / maxu16
}

// Brightness returns the brightness of this color.
func (c Color) Brightness() uint8 {
  return c.bri
}

// Blend blends this color with another color returning the blended Color.
// ratio=0 means use only this color; ratio=1 means use only the other color.
func (c Color) Blend(other Color, ratio float64) Color {
  invratio := 1.0 - ratio
  return NewColor(
      c.X() * invratio + other.X() * ratio,
      c.Y() * invratio + other.Y() * ratio,
      uint8(float64(c.bri) * invratio + float64(other.bri) * ratio))
}

// LightProperies represents the properties of a light.
type LightProperties struct {
  // C is the Color. nil means leave the color as-is
  C *Color

  // On is true if light is on or false if it is off. If nil,
  // it means leave the on/off state as is.
  On *bool
}

// Context represents a connection with a hue bridge.
type Context struct {

  // The userId / developer Id. See hue documentation.
  UserId string

  // The private ip address of the hue bridge.
  IpAddress string
}

// Set sets the properties of a light. lightId is the ID of the light to set.
// 0 means all lights.
func (c *Context) Set(lightId int, properties *LightProperties) (response []byte, err error) {
  jsonMap := make(map[string]interface{})
  if properties.C != nil {
    jsonMap["bri"] = properties.C.Brightness()
    jsonMap["xy"] = []float64{properties.C.X(), properties.C.Y()}
  }
  if properties.On != nil {
    jsonMap["on"] = *properties.On
  }
  var reqBuffer []byte
  if reqBuffer, err = json.Marshal(jsonMap); err != nil {
    return
  }
  var url *url.URL
  if url, err = c.lightUrl(lightId); err != nil {
    return
  }
  request := &http.Request{
      Method: "PUT",
      URL: url,
      ContentLength: int64(len(reqBuffer)),
      Body: simpleReadCloser{bytes.NewReader(reqBuffer)},
  }
  var client http.Client
  var resp *http.Response
  if resp, err = client.Do(request); err != nil {
    return
  }
  defer resp.Body.Close()
  var respBuffer bytes.Buffer
  if _, err = respBuffer.ReadFrom(resp.Body); err != nil {
    return
  }
  return respBuffer.Bytes(), nil
}

func (c *Context) lightUrl(id int) (*url.URL, error) {
  if id == 0 {
    return c.allUrl()
  }
  return url.Parse(fmt.Sprintf("http://%s/api/%s/lights/%d/state", c.IpAddress, c.UserId, id))
}

func (c *Context) allUrl() (*url.URL, error) {
  return url.Parse(fmt.Sprintf("http://%s/api/%s/groups/0/action", c.IpAddress, c.UserId))
}

type simpleReadCloser struct {
  io.Reader
}

func (s simpleReadCloser) Close() error {
  return nil
}

<commit_msg>Add TruePtr and FalsePtr<commit_after>// Copyright 2013 Travis Keep. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or
// at http://opensource.org/licenses/BSD-3-Clause.

// Package gohue controls hue lights.
package gohue

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
  "net/url"
)

const (
  // Bright represents the brightest setting
  Bright = uint8(255)

  // Dim represents the dimmest setting.
  Dim = uint8(0)
)

var (
  // Pointer to true
  TruePtr = &trueVal

  // Pointer to false
  FalsePtr = &falseVal
)

var (
  trueVal = true
  falseVal = false
)

const (
  maxu16 = float64(10000.0)
)

// Color represents a particular color and brightness. Programs using Colors
// should typically store and pass them as values, not pointers.
type Color struct {
  x uint16
  y uint16
  bri uint8
}

// NewColor returns a new Color. x and y are the coordinates of the color
// in the color XY space; brightness is the brightness where 255 is brightest
// and 0 is dimmest.
func NewColor(x, y float64, brightness uint8) Color {
  return Color{x: uint16(x * maxu16), y: uint16(y * maxu16), bri: brightness}
}

// X returns the X value of this Color.
func (c Color) X() float64 {
  return float64(c.x) / maxu16
}

// Y returns the Y value of this Color.
func (c Color) Y() float64 {
  return float64(c.y) / maxu16
}

// Brightness returns the brightness of this color.
func (c Color) Brightness() uint8 {
  return c.bri
}

// Blend blends this color with another color returning the blended Color.
// ratio=0 means use only this color; ratio=1 means use only the other color.
func (c Color) Blend(other Color, ratio float64) Color {
  invratio := 1.0 - ratio
  return NewColor(
      c.X() * invratio + other.X() * ratio,
      c.Y() * invratio + other.Y() * ratio,
      uint8(float64(c.bri) * invratio + float64(other.bri) * ratio))
}

// LightProperies represents the properties of a light.
type LightProperties struct {
  // C is the Color. nil means leave the color as-is
  C *Color

  // On is true if light is on or false if it is off. If nil,
  // it means leave the on/off state as is.
  On *bool
}

// Context represents a connection with a hue bridge.
type Context struct {

  // The userId / developer Id. See hue documentation.
  UserId string

  // The private ip address of the hue bridge.
  IpAddress string
}

// Set sets the properties of a light. lightId is the ID of the light to set.
// 0 means all lights.
func (c *Context) Set(lightId int, properties *LightProperties) (response []byte, err error) {
  jsonMap := make(map[string]interface{})
  if properties.C != nil {
    jsonMap["bri"] = properties.C.Brightness()
    jsonMap["xy"] = []float64{properties.C.X(), properties.C.Y()}
  }
  if properties.On != nil {
    jsonMap["on"] = *properties.On
  }
  var reqBuffer []byte
  if reqBuffer, err = json.Marshal(jsonMap); err != nil {
    return
  }
  var url *url.URL
  if url, err = c.lightUrl(lightId); err != nil {
    return
  }
  request := &http.Request{
      Method: "PUT",
      URL: url,
      ContentLength: int64(len(reqBuffer)),
      Body: simpleReadCloser{bytes.NewReader(reqBuffer)},
  }
  var client http.Client
  var resp *http.Response
  if resp, err = client.Do(request); err != nil {
    return
  }
  defer resp.Body.Close()
  var respBuffer bytes.Buffer
  if _, err = respBuffer.ReadFrom(resp.Body); err != nil {
    return
  }
  return respBuffer.Bytes(), nil
}

func (c *Context) lightUrl(id int) (*url.URL, error) {
  if id == 0 {
    return c.allUrl()
  }
  return url.Parse(fmt.Sprintf("http://%s/api/%s/lights/%d/state", c.IpAddress, c.UserId, id))
}

func (c *Context) allUrl() (*url.URL, error) {
  return url.Parse(fmt.Sprintf("http://%s/api/%s/groups/0/action", c.IpAddress, c.UserId))
}

type simpleReadCloser struct {
  io.Reader
}

func (s simpleReadCloser) Close() error {
  return nil
}

<|endoftext|>


<commit_before>package main // import "github.com/newrelic/sidecar"

import (
	"fmt"
	"os"
	"os/signal"
	"runtime/pprof"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/armon/go-metrics"
	"github.com/newrelic-forks/memberlist"
	"github.com/relistan/go-director"
	"github.com/newrelic/sidecar/catalog"
	"github.com/newrelic/sidecar/discovery"
	"github.com/newrelic/sidecar/haproxy"
	"github.com/newrelic/sidecar/healthy"
	"github.com/newrelic/sidecar/service"
)

var (
	profilerFile os.File
)

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

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

		state.Print(list)

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

func configureHAproxy(config Config) *haproxy.HAproxy {
	proxy := haproxy.New(config.HAproxy.ConfigFile, config.HAproxy.PidFile)

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

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

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

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

	return proxy
}

func configureDiscovery(config *Config) discovery.Discoverer {
	disco := new(discovery.MultiDiscovery)

	for _, method := range config.Sidecar.Discovery {
		switch method {
		case "docker":
			disco.Discoverers = append(
				disco.Discoverers,
				discovery.NewDockerDiscovery(config.DockerDiscovery.DockerURL),
			)
		case "static":
			disco.Discoverers = append(
				disco.Discoverers,
				discovery.NewStaticDiscovery(config.StaticDiscovery.ConfigFile),
			)
		default:
		}
	}

	return disco
}

func configureMetrics(config *Config) {
	if config.Sidecar.StatsAddr != "" {
		sink, err := metrics.NewStatsdSink(config.Sidecar.StatsAddr)
		exitWithError(err, "Can't configure Statsd")

		metricsConfig := metrics.DefaultConfig("sidecar")
		_, err = metrics.NewGlobal(metricsConfig, sink)
		exitWithError(err, "Can't start metrics")
	}
}

func configureDelegate(state *catalog.ServicesState, opts *CliOpts) *servicesDelegate {
	delegate := NewServicesDelegate(state)
	delegate.Metadata = NodeMetadata{
		ClusterName: *opts.ClusterName,
		State:       "Running",
	}

	return delegate
}

func configureSignalHandler(opts *CliOpts) {
	if !*opts.CpuProfile {
		return
	}

	// Capture CTRL-C and stop the CPU profiler
	sigChannel := make(chan os.Signal, 1)
	signal.Notify(sigChannel, os.Interrupt)
	go func() {
		for sig := range sigChannel {
			log.Printf("Captured %v, stopping profiler and exiting..", sig)
			pprof.StopCPUProfile()
			profilerFile.Close()
			os.Exit(1)
		}
	}()
}

func main() {
	opts := parseCommandLine()
	configureSignalHandler(opts)

	// Default to verbose timestamping
	log.SetFormatter(&log.TextFormatter{FullTimestamp: true})

	// Enable CPU profiling support if requested
	if *opts.CpuProfile {
		profilerFile, err := os.Create("sidecar.cpu.prof")
		exitWithError(err, "Can't write profiling file")
		pprof.StartCPUProfile(profilerFile)
		log.Debug("Profiling!")
	}
	state := catalog.NewServicesState()
	delegate := configureDelegate(state, opts)

	config := parseConfig(*opts.ConfigFile)

	state.ServiceNameMatch = config.Services.NameRegexp

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

	// Set up the push pull interval for Memberlist
	if config.Sidecar.PushPullInterval.Duration == 0 {
		mlConfig.PushPullInterval = catalog.ALIVE_LIFESPAN - 1*time.Second
	} else {
		mlConfig.PushPullInterval = config.Sidecar.PushPullInterval.Duration
	}
	if config.Sidecar.GossipMessages != 0 {
		mlConfig.GossipMessages = config.Sidecar.GossipMessages
	}

	// Figure out our IP address from the CLI or by inspecting
	publishedIP, err := getPublishedIP(config.Sidecar.ExcludeIPs, opts.AdvertiseIP)
	exitWithError(err, "Failed to find private IP address")
	mlConfig.AdvertiseAddr = publishedIP

	log.Println("Sidecar starting -------------------")
	log.Printf("Cluster Name: %s", *opts.ClusterName)
	log.Printf("Config File: %s", *opts.ConfigFile)
	log.Printf("Cluster Seeds: %s", strings.Join(*opts.ClusterIPs, ", "))
	log.Printf("Advertised address: %s", publishedIP)
	log.Printf("Service Name Match: %s", config.Services.NameMatch)
	log.Printf("Excluded IPs: %v", config.Sidecar.ExcludeIPs)
	log.Printf("Push/Pull Interval: %s", config.Sidecar.PushPullInterval.Duration.String())
	log.Printf("Gossip Messages: %d", config.Sidecar.GossipMessages)
	log.Printf("TomeAddr: %s", config.Sidecar.TomeAddr)
	log.Println("----------------------------------")

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

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

	//metaUpdates := make(chan []byte)

	servicesLooper := director.NewTimedLooper(
		director.FOREVER, catalog.ALIVE_SLEEP_INTERVAL, nil,
	)
	tombstoneLooper := director.NewTimedLooper(
		director.FOREVER, catalog.TOMBSTONE_SLEEP_INTERVAL, nil,
	)
	trackingLooper := director.NewTimedLooper(
		director.FOREVER, catalog.ALIVE_SLEEP_INTERVAL, nil,
	)
	discoLooper := director.NewTimedLooper(
		director.FOREVER, discovery.SLEEP_INTERVAL, make(chan error),
	)
	healthWatchLooper := director.NewTimedLooper(
		director.FOREVER, healthy.WATCH_INTERVAL, make(chan error),
	)
	healthLooper := director.NewTimedLooper(
		director.FOREVER, healthy.HEALTH_INTERVAL, make(chan error),
	)

	configureMetrics(&config)

	disco := configureDiscovery(&config)
	go disco.Run(discoLooper)

	nameFunc := func(svc *service.Service) string {
		return state.ServiceName(svc)
	}

	// Configure the monitor and use the public address as the default
	// check address.
	monitor := healthy.NewMonitor(publishedIP, config.Sidecar.TomeAddr)
	monitor.ServiceNameFn = nameFunc

	serviceFunc := func() []service.Service { return monitor.Services() }

	go announceMembers(list, state)
	go state.BroadcastServices(serviceFunc, servicesLooper)
	go state.BroadcastTombstones(serviceFunc, tombstoneLooper)
	go state.TrackNewServices(serviceFunc, trackingLooper)
	go monitor.Watch(disco, healthWatchLooper)
	go monitor.Run(healthLooper)
	//go updateMetaData(list, metaUpdates)

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

	serveHttp(list, state)

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

	select {}
}
<commit_msg>Remove metadata cruft.<commit_after>package main // import "github.com/newrelic/sidecar"

import (
	"os"
	"os/signal"
	"runtime/pprof"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/armon/go-metrics"
	"github.com/newrelic-forks/memberlist"
	"github.com/relistan/go-director"
	"github.com/newrelic/sidecar/catalog"
	"github.com/newrelic/sidecar/discovery"
	"github.com/newrelic/sidecar/haproxy"
	"github.com/newrelic/sidecar/healthy"
	"github.com/newrelic/sidecar/service"
)

var (
	profilerFile os.File
)

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

		state.Print(list)

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

func configureHAproxy(config Config) *haproxy.HAproxy {
	proxy := haproxy.New(config.HAproxy.ConfigFile, config.HAproxy.PidFile)

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

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

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

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

	return proxy
}

func configureDiscovery(config *Config) discovery.Discoverer {
	disco := new(discovery.MultiDiscovery)

	for _, method := range config.Sidecar.Discovery {
		switch method {
		case "docker":
			disco.Discoverers = append(
				disco.Discoverers,
				discovery.NewDockerDiscovery(config.DockerDiscovery.DockerURL),
			)
		case "static":
			disco.Discoverers = append(
				disco.Discoverers,
				discovery.NewStaticDiscovery(config.StaticDiscovery.ConfigFile),
			)
		default:
		}
	}

	return disco
}

func configureMetrics(config *Config) {
	if config.Sidecar.StatsAddr != "" {
		sink, err := metrics.NewStatsdSink(config.Sidecar.StatsAddr)
		exitWithError(err, "Can't configure Statsd")

		metricsConfig := metrics.DefaultConfig("sidecar")
		_, err = metrics.NewGlobal(metricsConfig, sink)
		exitWithError(err, "Can't start metrics")
	}
}

func configureDelegate(state *catalog.ServicesState, opts *CliOpts) *servicesDelegate {
	delegate := NewServicesDelegate(state)
	delegate.Metadata = NodeMetadata{
		ClusterName: *opts.ClusterName,
		State:       "Running",
	}

	return delegate
}

func configureSignalHandler(opts *CliOpts) {
	if !*opts.CpuProfile {
		return
	}

	// Capture CTRL-C and stop the CPU profiler
	sigChannel := make(chan os.Signal, 1)
	signal.Notify(sigChannel, os.Interrupt)
	go func() {
		for sig := range sigChannel {
			log.Printf("Captured %v, stopping profiler and exiting..", sig)
			pprof.StopCPUProfile()
			profilerFile.Close()
			os.Exit(1)
		}
	}()
}

func main() {
	opts := parseCommandLine()
	configureSignalHandler(opts)

	// Default to verbose timestamping
	log.SetFormatter(&log.TextFormatter{FullTimestamp: true})

	// Enable CPU profiling support if requested
	if *opts.CpuProfile {
		profilerFile, err := os.Create("sidecar.cpu.prof")
		exitWithError(err, "Can't write profiling file")
		pprof.StartCPUProfile(profilerFile)
		log.Debug("Profiling!")
	}
	state := catalog.NewServicesState()
	delegate := configureDelegate(state, opts)

	config := parseConfig(*opts.ConfigFile)

	state.ServiceNameMatch = config.Services.NameRegexp

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

	// Set up the push pull interval for Memberlist
	if config.Sidecar.PushPullInterval.Duration == 0 {
		mlConfig.PushPullInterval = catalog.ALIVE_LIFESPAN - 1*time.Second
	} else {
		mlConfig.PushPullInterval = config.Sidecar.PushPullInterval.Duration
	}
	if config.Sidecar.GossipMessages != 0 {
		mlConfig.GossipMessages = config.Sidecar.GossipMessages
	}

	// Figure out our IP address from the CLI or by inspecting
	publishedIP, err := getPublishedIP(config.Sidecar.ExcludeIPs, opts.AdvertiseIP)
	exitWithError(err, "Failed to find private IP address")
	mlConfig.AdvertiseAddr = publishedIP

	log.Println("Sidecar starting -------------------")
	log.Printf("Cluster Name: %s", *opts.ClusterName)
	log.Printf("Config File: %s", *opts.ConfigFile)
	log.Printf("Cluster Seeds: %s", strings.Join(*opts.ClusterIPs, ", "))
	log.Printf("Advertised address: %s", publishedIP)
	log.Printf("Service Name Match: %s", config.Services.NameMatch)
	log.Printf("Excluded IPs: %v", config.Sidecar.ExcludeIPs)
	log.Printf("Push/Pull Interval: %s", config.Sidecar.PushPullInterval.Duration.String())
	log.Printf("Gossip Messages: %d", config.Sidecar.GossipMessages)
	log.Printf("TomeAddr: %s", config.Sidecar.TomeAddr)
	log.Println("----------------------------------")

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

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

	servicesLooper := director.NewTimedLooper(
		director.FOREVER, catalog.ALIVE_SLEEP_INTERVAL, nil,
	)
	tombstoneLooper := director.NewTimedLooper(
		director.FOREVER, catalog.TOMBSTONE_SLEEP_INTERVAL, nil,
	)
	trackingLooper := director.NewTimedLooper(
		director.FOREVER, catalog.ALIVE_SLEEP_INTERVAL, nil,
	)
	discoLooper := director.NewTimedLooper(
		director.FOREVER, discovery.SLEEP_INTERVAL, make(chan error),
	)
	healthWatchLooper := director.NewTimedLooper(
		director.FOREVER, healthy.WATCH_INTERVAL, make(chan error),
	)
	healthLooper := director.NewTimedLooper(
		director.FOREVER, healthy.HEALTH_INTERVAL, make(chan error),
	)

	configureMetrics(&config)

	disco := configureDiscovery(&config)
	go disco.Run(discoLooper)

	nameFunc := func(svc *service.Service) string {
		return state.ServiceName(svc)
	}

	// Configure the monitor and use the public address as the default
	// check address.
	monitor := healthy.NewMonitor(publishedIP, config.Sidecar.TomeAddr)
	monitor.ServiceNameFn = nameFunc

	serviceFunc := func() []service.Service { return monitor.Services() }

	go announceMembers(list, state)
	go state.BroadcastServices(serviceFunc, servicesLooper)
	go state.BroadcastTombstones(serviceFunc, tombstoneLooper)
	go state.TrackNewServices(serviceFunc, trackingLooper)
	go monitor.Watch(disco, healthWatchLooper)
	go monitor.Run(healthLooper)

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

	serveHttp(list, state)

	select {}
}
<|endoftext|>


<commit_before>package flue

// This will convert the TaskGraphStructure into a format suitable for sigmajs
type SigmaNode struct {
	Id    int    // "id": "1",
	Labe  string //"label": "Node 1",
	Color string //"color": "rgb(90,90,90)",
	Size  int    //"size": 100,
	X     int    //"x": 10,
	Y     int    //"y": -10,
	Type  string //"type": "tweetegy"

}

type SigmaEdge struct {
	Id     int
	Source int
	Target int
}

type SigmaStructure struct {
	Edges []SigmaEdge
	Nodes []SigmaNode
}

func GetSigmaTaskStructure(taskGraphStructure *TaskGraphStructure) *SigmaStructure {

}
<commit_msg>Added "constructors" for sigmajs types<commit_after>package flue

// This will convert the TaskGraphStructure into a format suitable for sigmajs
type SigmaNode struct {
	Id    int    // "id": "1",
	Label string //"label": "Node 1",
	Color string //"color": "rgb(90,90,90)",
	Size  int    //"size": 100,
	X     int    //"x": 10,
	Y     int    //"y": -10,
	Type  string //"type": "tweetegy"

}

type SigmaEdge struct {
	Id     int
	Source int
	Target int
}

type SigmaStructure struct {
	Nodes []*SigmaNode
	Edges []*SigmaEdge
}

func NewSigmaStructure() *SigmaStructure {
	return &SigmaStructure{
		make([]*SigmaNode, 2),
		make([]*SigmaEdge, 1),
	}
}
func NewSigmaEdge() *SigmaEdge {
	return &SigmaEdge{
		-1,
		-1,
		-1,
	}
}

func NewSigmaNode() *SigmaNode {
	return &SigmaNode{
		-1,
		"Default Node",
		"rgb(90,90,90)",
		100,
		0,
		0,
		"Def",
	}
}

func GetSigmaTaskStructure(taskGraphStructure *TaskGraphStructure) *SigmaStructure {
	// First parse the taskGraphStructure.Tasks and create the node array
	return nil

}
<|endoftext|>


<commit_before>package proxyconfig

import (
	"errors"
	"fmt"
	"koding/tools/config"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type ProxyMessage struct {
	Action      string `json:"action"`
	DomainName  string `json:"domainName"`
	ServiceName string `json:"serviceName"`
	Username    string `json:"username"`
	Key         string `json:"key"`
	RabbitKey   string `json:"rabbitKey"`
	Host        string `json:"host"`
	HostData    string `json:"hostdata"`
	Uuid        string `json:"uuid"`
}

type ProxyResponse struct {
	Action string `json:"action"`
	Uuid   string `json:"uuid"`
}

type KeyData struct {
	Key          string
	Host         string
	HostData     string
	CurrentIndex int
	RabbitKey    string
}

func NewKeyData(key, host, hostdata, rabbitkey string, currentindex int) *KeyData {
	return &KeyData{
		Key:          key,
		Host:         host,
		HostData:     hostdata,
		CurrentIndex: currentindex,
		RabbitKey:    rabbitkey,
	}
}

type KeyRoutingTable struct {
	Keys map[string][]KeyData `json:"keys"`
}

func NewKeyRoutingTable() *KeyRoutingTable {
	return &KeyRoutingTable{
		Keys: make(map[string][]KeyData),
	}
}

type DomainData struct {
	Username string
	Name     string
	Key      string
	FullUrl  string
}

func NewDomainData(username, name, key, fullurl string) *DomainData {
	return &DomainData{
		Username: name,
		Name:     name,
		Key:      key,
		FullUrl:  fullurl,
	}
}

type DomainRoutingTable struct {
	Domains map[string]DomainData `json:"domains"`
}

func NewDomainRoutingTable() *DomainRoutingTable {
	return &DomainRoutingTable{
		Domains: make(map[string]DomainData),
	}
}

type UserProxy struct {
	Services map[string]KeyRoutingTable
}

type Proxy struct {
	Uuid               string
	RoutingTable       map[string]UserProxy
	DomainRoutingTable DomainRoutingTable
}

func NewProxy(uuid string) *Proxy {
	return &Proxy{
		Uuid:               uuid,
		RoutingTable:       make(map[string]UserProxy),
		DomainRoutingTable: *NewDomainRoutingTable(),
	}
}

func NewUserProxy() *UserProxy {
	return &UserProxy{
		Services: make(map[string]KeyRoutingTable),
	}
}

type ProxyConfiguration struct {
	Session    *mgo.Session
	Collection *mgo.Collection
}

func Connect() (*ProxyConfiguration, error) {
	host := config.Current.Kontrold.Mongo.Host
	session, err := mgo.Dial(host)
	if err != nil {
		return nil, err
	}

	session.SetMode(mgo.Strong, true)

	col := session.DB("kontrol").C("proxies")

	pr := &ProxyConfiguration{
		Session:    session,
		Collection: col,
	}

	return pr, nil
}

func (p *ProxyConfiguration) Add(proxy Proxy) error {
	err := p.Collection.Insert(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) AddProxy(uuid string) error {
	err := p.HasUuid(uuid)
	if err == nil {
		return fmt.Errorf("registering not possible uuid '%s' uuid exists.", uuid)
	}

	proxy := *NewProxy(uuid)
	err = p.Add(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) AddUser(uuid, username string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("adding user is not possible '%s'", err)
	}

	proxy.RoutingTable[username] = *NewUserProxy()

	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}
	return nil

}

func (p *ProxyConfiguration) AddDomain(username, domainname, servicename, key, fullurl, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("adding domain is not possible '%s'", err)
	}

	_, ok := proxy.DomainRoutingTable.Domains[domainname]
	if !ok {
		proxy.DomainRoutingTable.Domains[domainname] = *NewDomainData(username, servicename, key, fullurl)
	}

	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) DeleteDomain(domainname, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("deleting domain not possible '%s'", err)
	}

	_, ok := proxy.DomainRoutingTable.Domains[domainname]
	if !ok {
		return errors.New("deleting domain is not possible. domain name is wrong")
	}

	delete(proxy.DomainRoutingTable.Domains, domainname)
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}

	return nil
}

// Base DELETE crud action
func (p *ProxyConfiguration) Delete(uuid string) error {
	err := p.Collection.Remove(bson.M{"uuid": uuid})
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) DeleteProxy(uuid string) error {
	err := p.HasUuid(uuid)
	if err != nil {
		return fmt.Errorf("deleting not possible '%s'", err)
	}

	err = p.Delete(uuid)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) DeleteServiceName(username, name, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("deleting key not possible '%s'", err)
	}

	_, ok := proxy.RoutingTable[username]
	if !ok {
		return fmt.Errorf("deleting key is not possible. no user %s exists", username)
	}
	user := proxy.RoutingTable[username]

	_, ok = user.Services[name]
	if !ok {
		return errors.New("service name is wrong. deleting service is not possible")
	}

	delete(user.Services, name)

	proxy.RoutingTable[username] = user
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}

	return nil
}

func (p *ProxyConfiguration) DeleteKey(username, name, key, host, hostdata, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("deleting key not possible '%s'", err)
	}

	_, ok := proxy.RoutingTable[username]
	if !ok {
		return fmt.Errorf("deleting key is not possible. no user %s exists", username)
	}
	user := proxy.RoutingTable[username]

	_, ok = user.Services[name]
	if !ok {
		return errors.New("deleting key is not possible. service name is wrong.")
	}

	keyRoutingTable := user.Services[name]
	delete(keyRoutingTable.Keys, key)

	user.Services[name] = keyRoutingTable

	proxy.RoutingTable[username] = user
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}

	return nil
}

func (p *ProxyConfiguration) UpdateProxy(proxy Proxy) error {
	err := p.Collection.Update(bson.M{"uuid": proxy.Uuid}, proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) AddKey(username, name, key, host, hostdata, uuid, rabbitkey string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("adding key is not possible. '%s'", err)
	}

	_, ok := proxy.RoutingTable[username]
	if !ok {
		if username == "koding" {
			err := p.AddUser(uuid, username)
			if err != nil {
				return err
			}
		} else {
			return fmt.Errorf("adding key is not possible. no user %s exists", username)
		}
	}
	user := proxy.RoutingTable[username]

	_, ok = user.Services[name]
	if !ok {
		user.Services[name] = *NewKeyRoutingTable()
	}
	keyRoutingTable := user.Services[name]

	if len(keyRoutingTable.Keys) == 0 { // empty routing table, add it
		keyRoutingTable.Keys[key] = append(keyRoutingTable.Keys[key], *NewKeyData(key, host, hostdata, rabbitkey, 0))
		user.Services[name] = keyRoutingTable
		proxy.RoutingTable[username] = user
		err = p.UpdateProxy(proxy)
		if err != nil {
			return err
		}
		return nil
	}

	_, ok = keyRoutingTable.Keys[key] // new key, add it
	if !ok {
		keyRoutingTable.Keys[key] = append(keyRoutingTable.Keys[key], *NewKeyData(key, host, hostdata, rabbitkey, 0))
		user.Services[name] = keyRoutingTable
		proxy.RoutingTable[username] = user
		err = p.UpdateProxy(proxy)
		if err != nil {
			return err
		}
		return nil
	}

	/* check for existing hostnames, if exist abort. Comment out if you want
	   * add multiple entities for a single key. Useful if you want use
	   * round-robin.
	   for _, value := range keyRoutingTable.Keys[key] {
	       if value.Host == host {
	           return nil
	       }
	   }
	   keyRoutingTable.Keys[key] = append(keyRoutingTable.Keys[key], *NewKeyData(key, host, hostdata, rabbitkey, 0))
	*/

	user.Services[name] = keyRoutingTable
	proxy.RoutingTable[username] = user
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) HasUuid(uuid string) error {
	result := Proxy{}
	err := p.Collection.Find(bson.M{"uuid": uuid}).One(&result)
	if err != nil {
		return fmt.Errorf("no proxy with the uuid %s exist.", uuid)
	}
	return nil
}

func (p *ProxyConfiguration) GetProxy(uuid string) (Proxy, error) {
	result := Proxy{}
	err := p.Collection.Find(bson.M{"uuid": uuid}).One(&result)
	if err != nil {
		return result, fmt.Errorf("no proxy with the uuid %s exist.", uuid)
	}

	return result, nil
}

// func (p *ProxyConfiguration) GetUserProxy(username string) (UserProxy, error) {
// 	result := UserProxy{}
// 	err := p.Collection.Find(bson.M{"uuid": uuid}).One(&result)
// 	if err != nil {
// 		return result, fmt.Errorf("no proxy with the uuid %s exist.", uuid)
// 	}
//
// 	return result, nil
// }
<commit_msg>Small fix<commit_after>package proxyconfig

import (
	"errors"
	"fmt"
	"koding/tools/config"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type ProxyMessage struct {
	Action      string `json:"action"`
	DomainName  string `json:"domainName"`
	ServiceName string `json:"serviceName"`
	Username    string `json:"username"`
	Key         string `json:"key"`
	RabbitKey   string `json:"rabbitKey"`
	Host        string `json:"host"`
	HostData    string `json:"hostdata"`
	Uuid        string `json:"uuid"`
}

type ProxyResponse struct {
	Action string `json:"action"`
	Uuid   string `json:"uuid"`
}

type KeyData struct {
	Key          string
	Host         string
	HostData     string
	CurrentIndex int
	RabbitKey    string
}

func NewKeyData(key, host, hostdata, rabbitkey string, currentindex int) *KeyData {
	return &KeyData{
		Key:          key,
		Host:         host,
		HostData:     hostdata,
		CurrentIndex: currentindex,
		RabbitKey:    rabbitkey,
	}
}

type KeyRoutingTable struct {
	Keys map[string][]KeyData `json:"keys"`
}

func NewKeyRoutingTable() *KeyRoutingTable {
	return &KeyRoutingTable{
		Keys: make(map[string][]KeyData),
	}
}

type DomainData struct {
	Username string
	Name     string
	Key      string
	FullUrl  string
}

func NewDomainData(username, name, key, fullurl string) *DomainData {
	return &DomainData{
		Username: username,
		Name:     name,
		Key:      key,
		FullUrl:  fullurl,
	}
}

type DomainRoutingTable struct {
	Domains map[string]DomainData `json:"domains"`
}

func NewDomainRoutingTable() *DomainRoutingTable {
	return &DomainRoutingTable{
		Domains: make(map[string]DomainData),
	}
}

type UserProxy struct {
	Services map[string]KeyRoutingTable
}

type Proxy struct {
	Uuid               string
	RoutingTable       map[string]UserProxy
	DomainRoutingTable DomainRoutingTable
}

func NewProxy(uuid string) *Proxy {
	return &Proxy{
		Uuid:               uuid,
		RoutingTable:       make(map[string]UserProxy),
		DomainRoutingTable: *NewDomainRoutingTable(),
	}
}

func NewUserProxy() *UserProxy {
	return &UserProxy{
		Services: make(map[string]KeyRoutingTable),
	}
}

type ProxyConfiguration struct {
	Session    *mgo.Session
	Collection *mgo.Collection
}

func Connect() (*ProxyConfiguration, error) {
	host := config.Current.Kontrold.Mongo.Host
	session, err := mgo.Dial(host)
	if err != nil {
		return nil, err
	}

	session.SetMode(mgo.Strong, true)

	col := session.DB("kontrol").C("proxies")

	pr := &ProxyConfiguration{
		Session:    session,
		Collection: col,
	}

	return pr, nil
}

func (p *ProxyConfiguration) Add(proxy Proxy) error {
	err := p.Collection.Insert(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) AddProxy(uuid string) error {
	err := p.HasUuid(uuid)
	if err == nil {
		return fmt.Errorf("registering not possible uuid '%s' uuid exists.", uuid)
	}

	proxy := *NewProxy(uuid)
	err = p.Add(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) AddUser(uuid, username string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("adding user is not possible '%s'", err)
	}

	proxy.RoutingTable[username] = *NewUserProxy()

	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}
	return nil

}

func (p *ProxyConfiguration) AddDomain(username, domainname, servicename, key, fullurl, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("adding domain is not possible '%s'", err)
	}

	_, ok := proxy.DomainRoutingTable.Domains[domainname]
	if !ok {
		proxy.DomainRoutingTable.Domains[domainname] = *NewDomainData(username, servicename, key, fullurl)
	}

	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) DeleteDomain(domainname, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("deleting domain not possible '%s'", err)
	}

	_, ok := proxy.DomainRoutingTable.Domains[domainname]
	if !ok {
		return errors.New("deleting domain is not possible. domain name is wrong")
	}

	delete(proxy.DomainRoutingTable.Domains, domainname)
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}

	return nil
}

// Base DELETE crud action
func (p *ProxyConfiguration) Delete(uuid string) error {
	err := p.Collection.Remove(bson.M{"uuid": uuid})
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) DeleteProxy(uuid string) error {
	err := p.HasUuid(uuid)
	if err != nil {
		return fmt.Errorf("deleting not possible '%s'", err)
	}

	err = p.Delete(uuid)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) DeleteServiceName(username, name, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("deleting key not possible '%s'", err)
	}

	_, ok := proxy.RoutingTable[username]
	if !ok {
		return fmt.Errorf("deleting key is not possible. no user %s exists", username)
	}
	user := proxy.RoutingTable[username]

	_, ok = user.Services[name]
	if !ok {
		return errors.New("service name is wrong. deleting service is not possible")
	}

	delete(user.Services, name)

	proxy.RoutingTable[username] = user
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}

	return nil
}

func (p *ProxyConfiguration) DeleteKey(username, name, key, host, hostdata, uuid string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("deleting key not possible '%s'", err)
	}

	_, ok := proxy.RoutingTable[username]
	if !ok {
		return fmt.Errorf("deleting key is not possible. no user %s exists", username)
	}
	user := proxy.RoutingTable[username]

	_, ok = user.Services[name]
	if !ok {
		return errors.New("deleting key is not possible. service name is wrong.")
	}

	keyRoutingTable := user.Services[name]
	delete(keyRoutingTable.Keys, key)

	user.Services[name] = keyRoutingTable

	proxy.RoutingTable[username] = user
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}

	return nil
}

func (p *ProxyConfiguration) UpdateProxy(proxy Proxy) error {
	err := p.Collection.Update(bson.M{"uuid": proxy.Uuid}, proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) AddKey(username, name, key, host, hostdata, uuid, rabbitkey string) error {
	proxy, err := p.GetProxy(uuid)
	if err != nil {
		return fmt.Errorf("adding key is not possible. '%s'", err)
	}

	_, ok := proxy.RoutingTable[username]
	if !ok {
		if username == "koding" {
			err := p.AddUser(uuid, username)
			if err != nil {
				return err
			}
		} else {
			return fmt.Errorf("adding key is not possible. no user %s exists", username)
		}
	}
	user := proxy.RoutingTable[username]

	_, ok = user.Services[name]
	if !ok {
		user.Services[name] = *NewKeyRoutingTable()
	}
	keyRoutingTable := user.Services[name]

	if len(keyRoutingTable.Keys) == 0 { // empty routing table, add it
		keyRoutingTable.Keys[key] = append(keyRoutingTable.Keys[key], *NewKeyData(key, host, hostdata, rabbitkey, 0))
		user.Services[name] = keyRoutingTable
		proxy.RoutingTable[username] = user
		err = p.UpdateProxy(proxy)
		if err != nil {
			return err
		}
		return nil
	}

	_, ok = keyRoutingTable.Keys[key] // new key, add it
	if !ok {
		keyRoutingTable.Keys[key] = append(keyRoutingTable.Keys[key], *NewKeyData(key, host, hostdata, rabbitkey, 0))
		user.Services[name] = keyRoutingTable
		proxy.RoutingTable[username] = user
		err = p.UpdateProxy(proxy)
		if err != nil {
			return err
		}
		return nil
	}

	/* check for existing hostnames, if exist abort. Comment out if you want
	   * add multiple entities for a single key. Useful if you want use
	   * round-robin.
	   for _, value := range keyRoutingTable.Keys[key] {
	       if value.Host == host {
	           return nil
	       }
	   }
	   keyRoutingTable.Keys[key] = append(keyRoutingTable.Keys[key], *NewKeyData(key, host, hostdata, rabbitkey, 0))
	*/

	user.Services[name] = keyRoutingTable
	proxy.RoutingTable[username] = user
	err = p.UpdateProxy(proxy)
	if err != nil {
		return err
	}
	return nil
}

func (p *ProxyConfiguration) HasUuid(uuid string) error {
	result := Proxy{}
	err := p.Collection.Find(bson.M{"uuid": uuid}).One(&result)
	if err != nil {
		return fmt.Errorf("no proxy with the uuid %s exist.", uuid)
	}
	return nil
}

func (p *ProxyConfiguration) GetProxy(uuid string) (Proxy, error) {
	result := Proxy{}
	err := p.Collection.Find(bson.M{"uuid": uuid}).One(&result)
	if err != nil {
		return result, fmt.Errorf("no proxy with the uuid %s exist.", uuid)
	}

	return result, nil
}

// func (p *ProxyConfiguration) GetUserProxy(username string) (UserProxy, error) {
// 	result := UserProxy{}
// 	err := p.Collection.Find(bson.M{"uuid": uuid}).One(&result)
// 	if err != nil {
// 		return result, fmt.Errorf("no proxy with the uuid %s exist.", uuid)
// 	}
//
// 	return result, nil
// }
<|endoftext|>


<commit_before>package realtimehelper

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"socialapi/config"
)

func PushMessage(channelId int64, eventName string, body interface{}) error {
	request := map[string]interface{}{
		"eventName": eventName,
		"body":      body,
	}

	payload, err := json.Marshal(request)
	if err != nil {
		return err
	}

	buf := bytes.NewBuffer(payload)
	client := &http.Client{}

	endpoint := fmt.Sprintf("%s/api/gatekeeper/channel/%d/push", config.MustGet().CustomDomain.Public, channelId)
	res, err := client.Post(endpoint, "application/json", buf)
	if err != nil {
		return err
	}

	if res.StatusCode != 200 {
		return fmt.Errorf(res.Status)
	}

	return nil
}
<commit_msg>realtime: add updateinstance request helper<commit_after>package realtimehelper

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"socialapi/config"
)

func PushMessage(channelId int64, eventName string, body interface{}) error {
	endpoint := fmt.Sprintf("%s/api/gatekeeper/channel/%d/push", config.MustGet().CustomDomain.Public, channelId)

	return doRequest(endpoint, eventName, body)
}

func UpdateInstance(token string, eventName string, body interface{}) error {
	endpoint := fmt.Sprintf("%s/api/gatekeeper/message/%s/update", config.MustGet().CustomDomain.Public, token)

	return doRequest(endpoint, eventName, body)
}

func doRequest(endpoint, eventName string, body interface{}) error {
	request := map[string]interface{}{
		"eventName": eventName,
		"body":      body,
	}

	payload, err := json.Marshal(request)
	if err != nil {
		return err
	}

	buf := bytes.NewBuffer(payload)
	client := &http.Client{}

	res, err := client.Post(endpoint, "application/json", buf)
	if err != nil {
		return err
	}

	if res.StatusCode != 200 {
		return fmt.Errorf(res.Status)
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	mapset "github.com/deckarep/golang-set"
)

func main() {
	// initialiazing with some data. can also initialize with empty
	s1 := mapset.NewSetFromSlice([]interface{}{"Delhi", "Gurgaon"})

	// adding more values
	s1.Add("Noida")
	// adding duplicate values
	s1.Add("Noida")

	// convert to slice
	fmt.Println(s1.ToSlice()) // duplicates will be removed

	// check for existance of a value
	fmt.Println(s1.Contains("Delhi"))
	fmt.Println(s1.Contains("XYZ"))
}
<commit_msg>sets example using github.com/deckarep/golang-set<commit_after>package main

import (
	"fmt"
	mapset "github.com/deckarep/golang-set"
)

func main() {
	// initialiazing with some data. can also initialize with empty
	s1 := mapset.NewSetFromSlice([]interface{}{"Delhi", "Gurgaon"})

	// adding more values
	s1.Add("Noida")
	// adding duplicate values
	s1.Add("Noida")

	// convert to slice
	fmt.Println(s1.ToSlice()) // duplicates will be removed

	// check for existance of a value
	fmt.Println(s1.Contains("Delhi"))
	fmt.Println(s1.Contains("XYZ"))
}<|endoftext|>


<commit_before>package hashset

type MyHashSet struct{}

func Constructor() *MyHashSet {
	return &MyHashSet{}
}

func (this *MyHashSet) Add(key int) {
}

func (this *MyHashSet) Contains(key int) bool {
	return false
}

func (this *MyHashSet) Remove(key int) {
}
<commit_msg>solve 705 use cheated 1d array<commit_after>package hashset

type MyHashSet struct {
	// cheated with 1d array
	store [1000001]bool
}

func Constructor() *MyHashSet {
	return &MyHashSet{}
}

func (this *MyHashSet) Add(key int) {
	this.store[key] = true
}

func (this *MyHashSet) Contains(key int) bool {
	return this.store[key]
}

func (this *MyHashSet) Remove(key int) {
	this.store[key] = false
}
<|endoftext|>


<commit_before>package echo

import (
	"encoding/json"
	"encoding/xml"
	"io"
	"mime"
	"net/http"
	"os"
	"path/filepath"
	"time"

	"github.com/webx-top/echo/engine"
	"github.com/webx-top/echo/logger"

	"bytes"

	netContext "golang.org/x/net/context"
)

type (
	// Context represents context for the current request. It holds request and
	// response objects, path parameters, data and registered handler.
	Context interface {
		netContext.Context
		Request() engine.Request
		Response() engine.Response
		Path() string
		P(int) string
		Param(string) string

		// ParamNames returns path parameter names.
		ParamNames() []string

		// Queries returns the query parameters as map. It is an alias for `engine.URL#Query()`.
		Queries() map[string][]string
		QueryValues(string) []string
		Query(string) string

		Form(string) string
		FormValues(string) []string

		// Forms returns the form parameters as map. It is an alias for `engine.Request#Form().All()`.
		Forms() map[string][]string

		Set(string, interface{})
		Get(string) interface{}
		Bind(interface{}) error
		Render(int, string, interface{}) error
		HTML(int, string) error
		String(int, string) error
		JSON(int, interface{}) error
		JSONBlob(int, []byte) error
		JSONP(int, string, interface{}) error
		XML(int, interface{}) error
		XMLBlob(int, []byte) error
		File(string) error
		Attachment(io.ReadSeeker, string) error
		NoContent(int) error
		Redirect(int, string) error
		Error(err error)
		Handle(Context) error
		Logger() logger.Logger
		Object() *context

		// ServeContent sends static content from `io.Reader` and handles caching
		// via `If-Modified-Since` request header. It automatically sets `Content-Type`
		// and `Last-Modified` response headers.
		ServeContent(io.ReadSeeker, string, time.Time) error

		SetFunc(string, interface{})
		GetFunc(string) interface{}
		Funcs() map[string]interface{}
		Reset(engine.Request, engine.Response)
		Fetch(string, interface{}) ([]byte, error)
		SetRenderer(Renderer)
	}

	context struct {
		netContext netContext.Context
		request    engine.Request
		response   engine.Response
		path       string
		pnames     []string
		pvalues    []string
		store      store
		handler    Handler
		echo       *Echo
		funcs      map[string]interface{}
		renderer   Renderer
	}

	store map[string]interface{}
)

const (
	indexPage = "index.html"
)

// NewContext creates a Context object.
func NewContext(req engine.Request, res engine.Response, e *Echo) Context {
	return &context{
		request:  req,
		response: res,
		echo:     e,
		pvalues:  make([]string, *e.maxParam),
		store:    make(store),
		handler:  notFoundHandler,
		funcs:    make(map[string]interface{}),
	}
}

func (c *context) NetContext() netContext.Context {
	return c.netContext
}

func (c *context) SetNetContext(ctx netContext.Context) {
	c.netContext = ctx
}

func (c *context) Deadline() (deadline time.Time, ok bool) {
	return c.netContext.Deadline()
}

func (c *context) Done() <-chan struct{} {
	return c.netContext.Done()
}

func (c *context) Err() error {
	return c.netContext.Err()
}

func (c *context) Value(key interface{}) interface{} {
	return c.netContext.Value(key)
}

func (c *context) Handle(ctx Context) error {
	return c.handler.Handle(ctx)
}

// Request returns *http.Request.
func (c *context) Request() engine.Request {
	return c.request
}

// Response returns *Response.
func (c *context) Response() engine.Response {
	return c.response
}

// Path returns the registered path for the handler.
func (c *context) Path() string {
	return c.path
}

// P returns path parameter by index.
func (c *context) P(i int) (value string) {
	l := len(c.pnames)
	if i < l {
		value = c.pvalues[i]
	}
	return
}

// Param returns path parameter by name.
func (c *context) Param(name string) (value string) {
	l := len(c.pnames)
	for i, n := range c.pnames {
		if n == name && i < l {
			value = c.pvalues[i]
			break
		}
	}
	return
}

func (c *context) ParamNames() []string {
	return c.pnames
}

// Query returns query parameter by name.
func (c *context) Query(name string) string {
	return c.request.URL().QueryValue(name)
}

func (c *context) QueryValues(name string) []string {
	return c.request.URL().QueryValues(name)
}

func (c *context) Queries() map[string][]string {
	return c.request.URL().Query()
}

// Form returns form parameter by name.
func (c *context) Form(name string) string {
	return c.request.FormValue(name)
}

func (c *context) FormValues(name string) []string {
	return c.request.Form().Gets(name)
}

func (c *context) Forms() map[string][]string {
	return c.request.Form().All()
}

// Get retrieves data from the context.
func (c *context) Get(key string) interface{} {
	return c.store[key]
}

// Set saves data in the context.
func (c *context) Set(key string, val interface{}) {
	if c.store == nil {
		c.store = make(store)
	}
	c.store[key] = val
}

// Bind binds the request body into specified type `i`. The default binder does
// it based on Content-Type header.
func (c *context) Bind(i interface{}) error {
	return c.echo.binder.Bind(i, c)
}

// Render renders a template with data and sends a text/html response with status
// code. Templates can be registered using `Echo.SetRenderer()`.
func (c *context) Render(code int, name string, data interface{}) (err error) {
	b, err := c.Fetch(name, data)
	if err != nil {
		return
	}
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write(b)
	return
}

// HTML sends an HTTP response with status code.
func (c *context) HTML(code int, html string) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write([]byte(html))
	return
}

// String sends a string response with status code.
func (c *context) String(code int, s string) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextPlainCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write([]byte(s))
	return
}

// JSON sends a JSON response with status code.
func (c *context) JSON(code int, i interface{}) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = json.MarshalIndent(i, "", "  ")
	} else {
		b, err = json.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.JSONBlob(code, b)
}

// JSONBlob sends a JSON blob response with status code.
func (c *context) JSONBlob(code int, b []byte) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationJSONCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write(b)
	return
}

// JSONP sends a JSONP response with status code. It uses `callback` to construct
// the JSONP payload.
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.response.Header().Set(HeaderContentType, MIMEApplicationJavaScriptCharsetUTF8)
	c.response.WriteHeader(code)

	if _, err = c.response.Write([]byte(callback + "(")); err != nil {
		return
	}
	if _, err = c.response.Write(b); err != nil {
		return
	}
	_, err = c.response.Write([]byte(");"))
	return
}

// XML sends an XML response with status code.
func (c *context) XML(code int, i interface{}) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = xml.MarshalIndent(i, "", "  ")
	} else {
		b, err = xml.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.XMLBlob(code, b)
}

// XMLBlob sends a XML blob response with status code.
func (c *context) XMLBlob(code int, b []byte) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationXMLCharsetUTF8)
	c.response.WriteHeader(code)
	if _, err = c.response.Write([]byte(xml.Header)); err != nil {
		return
	}
	_, err = c.response.Write(b)
	return
}

func (c *context) File(file string) error {
	f, err := os.Open(file)
	if err != nil {
		return ErrNotFound
	}
	defer f.Close()

	fi, _ := f.Stat()
	if fi.IsDir() {
		file = filepath.Join(file, "index.html")
		f, err = os.Open(file)
		if err != nil {
			return ErrNotFound
		}
		fi, _ = f.Stat()
	}
	return c.ServeContent(f, fi.Name(), fi.ModTime())
}

func (c *context) Attachment(r io.ReadSeeker, name string) (err error) {
	c.response.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	c.response.Header().Set(HeaderContentDisposition, "attachment; filename="+name)
	c.response.WriteHeader(http.StatusOK)
	_, err = io.Copy(c.response, r)
	return
}

// NoContent sends a response with no body and a status code.
func (c *context) NoContent(code int) error {
	c.response.WriteHeader(code)
	return nil
}

// Redirect redirects the request with status code.
func (c *context) Redirect(code int, url string) error {
	if code < http.StatusMultipleChoices || code > http.StatusTemporaryRedirect {
		return ErrInvalidRedirectCode
	}
	c.response.Redirect(url, code)
	return nil
}

// Error invokes the registered HTTP error handler. Generally used by middleware.
func (c *context) Error(err error) {
	c.echo.httpErrorHandler(err, c)
}

// Logger returns the `Logger` instance.
func (c *context) Logger() logger.Logger {
	return c.echo.logger
}

// Object returns the `context` object.
func (c *context) Object() *context {
	return c
}

func (c *context) ServeContent(content io.ReadSeeker, name string, modtime time.Time) error {
	rq := c.Request()
	rs := c.Response()

	if t, err := time.Parse(http.TimeFormat, rq.Header().Get(HeaderIfModifiedSince)); err == nil && modtime.Before(t.Add(1*time.Second)) {
		rs.Header().Del(HeaderContentType)
		rs.Header().Del(HeaderContentLength)
		return c.NoContent(http.StatusNotModified)
	}

	rs.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	rs.Header().Set(HeaderLastModified, modtime.UTC().Format(http.TimeFormat))
	rs.WriteHeader(http.StatusOK)
	_, err := io.Copy(rs, content)
	return err
}

// ContentTypeByExtension returns the MIME type associated with the file based on
// its extension. It returns `application/octet-stream` incase MIME type is not
// found.
func ContentTypeByExtension(name string) (t string) {
	if t = mime.TypeByExtension(filepath.Ext(name)); t == "" {
		t = MIMEOctetStream
	}
	return
}

// Echo returns the `Echo` instance.
func (c *context) Echo() *Echo {
	return c.echo
}

func (c *context) Reset(req engine.Request, res engine.Response) {
	c.netContext = nil
	c.request = req
	c.response = res
	c.store = nil
	c.funcs = make(map[string]interface{})
	c.renderer = nil
	c.handler = notFoundHandler
}

func (c *context) GetFunc(key string) interface{} {
	return c.funcs[key]
}

func (c *context) SetFunc(key string, val interface{}) {
	c.funcs[key] = val
}

func (c *context) Funcs() map[string]interface{} {
	return c.funcs
}

func (c *context) Fetch(name string, data interface{}) (b []byte, err error) {
	if c.renderer == nil {
		if c.echo.renderer == nil {
			return nil, ErrRendererNotRegistered
		}
		c.renderer = c.echo.renderer
	}
	buf := new(bytes.Buffer)
	err = c.renderer.Render(buf, name, data, c)
	if err != nil {
		return
	}
	b = buf.Bytes()
	return
}

// SetRenderer registers an HTML template renderer.
func (c *context) SetRenderer(r Renderer) {
	c.renderer = r
}
<commit_msg>update<commit_after>package echo

import (
	"encoding/json"
	"encoding/xml"
	"io"
	"mime"
	"net/http"
	"os"
	"path/filepath"
	"time"

	"github.com/webx-top/echo/engine"
	"github.com/webx-top/echo/logger"

	"bytes"

	netContext "golang.org/x/net/context"
)

type (
	// Context represents context for the current request. It holds request and
	// response objects, path parameters, data and registered handler.
	Context interface {
		netContext.Context
		Request() engine.Request
		Response() engine.Response
		Path() string
		P(int) string
		Param(string) string

		// ParamNames returns path parameter names.
		ParamNames() []string

		// Queries returns the query parameters as map. It is an alias for `engine.URL#Query()`.
		Queries() map[string][]string
		QueryValues(string) []string
		Query(string) string

		Form(string) string
		FormValues(string) []string

		// Forms returns the form parameters as map. It is an alias for `engine.Request#Form().All()`.
		Forms() map[string][]string

		Set(string, interface{})
		Get(string) interface{}
		Bind(interface{}) error
		Render(int, string, interface{}) error
		HTML(int, string) error
		String(int, string) error
		JSON(int, interface{}) error
		JSONBlob(int, []byte) error
		JSONP(int, string, interface{}) error
		XML(int, interface{}) error
		XMLBlob(int, []byte) error
		File(string) error
		Attachment(io.ReadSeeker, string) error
		NoContent(int) error
		Redirect(int, string) error
		Error(err error)
		Handle(Context) error
		Logger() logger.Logger
		Object() *context

		// ServeContent sends static content from `io.Reader` and handles caching
		// via `If-Modified-Since` request header. It automatically sets `Content-Type`
		// and `Last-Modified` response headers.
		ServeContent(io.ReadSeeker, string, time.Time) error

		SetFunc(string, interface{})
		GetFunc(string) interface{}
		ResetFuncs(map[string]interface{})
		Funcs() map[string]interface{}
		Reset(engine.Request, engine.Response)
		Fetch(string, interface{}) ([]byte, error)
		SetRenderer(Renderer)
	}

	context struct {
		netContext netContext.Context
		request    engine.Request
		response   engine.Response
		path       string
		pnames     []string
		pvalues    []string
		store      store
		handler    Handler
		echo       *Echo
		funcs      map[string]interface{}
		renderer   Renderer
	}

	store map[string]interface{}
)

const (
	indexPage = "index.html"
)

// NewContext creates a Context object.
func NewContext(req engine.Request, res engine.Response, e *Echo) Context {
	return &context{
		request:  req,
		response: res,
		echo:     e,
		pvalues:  make([]string, *e.maxParam),
		store:    make(store),
		handler:  notFoundHandler,
		funcs:    make(map[string]interface{}),
	}
}

func (c *context) NetContext() netContext.Context {
	return c.netContext
}

func (c *context) SetNetContext(ctx netContext.Context) {
	c.netContext = ctx
}

func (c *context) Deadline() (deadline time.Time, ok bool) {
	return c.netContext.Deadline()
}

func (c *context) Done() <-chan struct{} {
	return c.netContext.Done()
}

func (c *context) Err() error {
	return c.netContext.Err()
}

func (c *context) Value(key interface{}) interface{} {
	return c.netContext.Value(key)
}

func (c *context) Handle(ctx Context) error {
	return c.handler.Handle(ctx)
}

// Request returns *http.Request.
func (c *context) Request() engine.Request {
	return c.request
}

// Response returns *Response.
func (c *context) Response() engine.Response {
	return c.response
}

// Path returns the registered path for the handler.
func (c *context) Path() string {
	return c.path
}

// P returns path parameter by index.
func (c *context) P(i int) (value string) {
	l := len(c.pnames)
	if i < l {
		value = c.pvalues[i]
	}
	return
}

// Param returns path parameter by name.
func (c *context) Param(name string) (value string) {
	l := len(c.pnames)
	for i, n := range c.pnames {
		if n == name && i < l {
			value = c.pvalues[i]
			break
		}
	}
	return
}

func (c *context) ParamNames() []string {
	return c.pnames
}

// Query returns query parameter by name.
func (c *context) Query(name string) string {
	return c.request.URL().QueryValue(name)
}

func (c *context) QueryValues(name string) []string {
	return c.request.URL().QueryValues(name)
}

func (c *context) Queries() map[string][]string {
	return c.request.URL().Query()
}

// Form returns form parameter by name.
func (c *context) Form(name string) string {
	return c.request.FormValue(name)
}

func (c *context) FormValues(name string) []string {
	return c.request.Form().Gets(name)
}

func (c *context) Forms() map[string][]string {
	return c.request.Form().All()
}

// Get retrieves data from the context.
func (c *context) Get(key string) interface{} {
	return c.store[key]
}

// Set saves data in the context.
func (c *context) Set(key string, val interface{}) {
	if c.store == nil {
		c.store = make(store)
	}
	c.store[key] = val
}

// Bind binds the request body into specified type `i`. The default binder does
// it based on Content-Type header.
func (c *context) Bind(i interface{}) error {
	return c.echo.binder.Bind(i, c)
}

// Render renders a template with data and sends a text/html response with status
// code. Templates can be registered using `Echo.SetRenderer()`.
func (c *context) Render(code int, name string, data interface{}) (err error) {
	b, err := c.Fetch(name, data)
	if err != nil {
		return
	}
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write(b)
	return
}

// HTML sends an HTTP response with status code.
func (c *context) HTML(code int, html string) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextHTMLCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write([]byte(html))
	return
}

// String sends a string response with status code.
func (c *context) String(code int, s string) (err error) {
	c.response.Header().Set(HeaderContentType, MIMETextPlainCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write([]byte(s))
	return
}

// JSON sends a JSON response with status code.
func (c *context) JSON(code int, i interface{}) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = json.MarshalIndent(i, "", "  ")
	} else {
		b, err = json.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.JSONBlob(code, b)
}

// JSONBlob sends a JSON blob response with status code.
func (c *context) JSONBlob(code int, b []byte) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationJSONCharsetUTF8)
	c.response.WriteHeader(code)
	_, err = c.response.Write(b)
	return
}

// JSONP sends a JSONP response with status code. It uses `callback` to construct
// the JSONP payload.
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
	b, err := json.Marshal(i)
	if err != nil {
		return err
	}
	c.response.Header().Set(HeaderContentType, MIMEApplicationJavaScriptCharsetUTF8)
	c.response.WriteHeader(code)

	if _, err = c.response.Write([]byte(callback + "(")); err != nil {
		return
	}
	if _, err = c.response.Write(b); err != nil {
		return
	}
	_, err = c.response.Write([]byte(");"))
	return
}

// XML sends an XML response with status code.
func (c *context) XML(code int, i interface{}) (err error) {
	var b []byte
	if c.echo.Debug() {
		b, err = xml.MarshalIndent(i, "", "  ")
	} else {
		b, err = xml.Marshal(i)
	}
	if err != nil {
		return err
	}
	return c.XMLBlob(code, b)
}

// XMLBlob sends a XML blob response with status code.
func (c *context) XMLBlob(code int, b []byte) (err error) {
	c.response.Header().Set(HeaderContentType, MIMEApplicationXMLCharsetUTF8)
	c.response.WriteHeader(code)
	if _, err = c.response.Write([]byte(xml.Header)); err != nil {
		return
	}
	_, err = c.response.Write(b)
	return
}

func (c *context) File(file string) error {
	f, err := os.Open(file)
	if err != nil {
		return ErrNotFound
	}
	defer f.Close()

	fi, _ := f.Stat()
	if fi.IsDir() {
		file = filepath.Join(file, "index.html")
		f, err = os.Open(file)
		if err != nil {
			return ErrNotFound
		}
		fi, _ = f.Stat()
	}
	return c.ServeContent(f, fi.Name(), fi.ModTime())
}

func (c *context) Attachment(r io.ReadSeeker, name string) (err error) {
	c.response.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	c.response.Header().Set(HeaderContentDisposition, "attachment; filename="+name)
	c.response.WriteHeader(http.StatusOK)
	_, err = io.Copy(c.response, r)
	return
}

// NoContent sends a response with no body and a status code.
func (c *context) NoContent(code int) error {
	c.response.WriteHeader(code)
	return nil
}

// Redirect redirects the request with status code.
func (c *context) Redirect(code int, url string) error {
	if code < http.StatusMultipleChoices || code > http.StatusTemporaryRedirect {
		return ErrInvalidRedirectCode
	}
	c.response.Redirect(url, code)
	return nil
}

// Error invokes the registered HTTP error handler. Generally used by middleware.
func (c *context) Error(err error) {
	c.echo.httpErrorHandler(err, c)
}

// Logger returns the `Logger` instance.
func (c *context) Logger() logger.Logger {
	return c.echo.logger
}

// Object returns the `context` object.
func (c *context) Object() *context {
	return c
}

func (c *context) ServeContent(content io.ReadSeeker, name string, modtime time.Time) error {
	rq := c.Request()
	rs := c.Response()

	if t, err := time.Parse(http.TimeFormat, rq.Header().Get(HeaderIfModifiedSince)); err == nil && modtime.Before(t.Add(1*time.Second)) {
		rs.Header().Del(HeaderContentType)
		rs.Header().Del(HeaderContentLength)
		return c.NoContent(http.StatusNotModified)
	}

	rs.Header().Set(HeaderContentType, ContentTypeByExtension(name))
	rs.Header().Set(HeaderLastModified, modtime.UTC().Format(http.TimeFormat))
	rs.WriteHeader(http.StatusOK)
	_, err := io.Copy(rs, content)
	return err
}

// ContentTypeByExtension returns the MIME type associated with the file based on
// its extension. It returns `application/octet-stream` incase MIME type is not
// found.
func ContentTypeByExtension(name string) (t string) {
	if t = mime.TypeByExtension(filepath.Ext(name)); t == "" {
		t = MIMEOctetStream
	}
	return
}

// Echo returns the `Echo` instance.
func (c *context) Echo() *Echo {
	return c.echo
}

func (c *context) Reset(req engine.Request, res engine.Response) {
	c.netContext = nil
	c.request = req
	c.response = res
	c.store = nil
	c.funcs = make(map[string]interface{})
	c.renderer = nil
	c.handler = notFoundHandler
}

func (c *context) GetFunc(key string) interface{} {
	return c.funcs[key]
}

func (c *context) SetFunc(key string, val interface{}) {
	c.funcs[key] = val
}

func (c *context) ResetFuncs(funcs map[string]interface{}) {
	c.funcs = funcs
}

func (c *context) Funcs() map[string]interface{} {
	return c.funcs
}

func (c *context) Fetch(name string, data interface{}) (b []byte, err error) {
	if c.renderer == nil {
		if c.echo.renderer == nil {
			return nil, ErrRendererNotRegistered
		}
		c.renderer = c.echo.renderer
	}
	buf := new(bytes.Buffer)
	err = c.renderer.Render(buf, name, data, c)
	if err != nil {
		return
	}
	b = buf.Bytes()
	return
}

// SetRenderer registers an HTML template renderer.
func (c *context) SetRenderer(r Renderer) {
	c.renderer = r
}
<|endoftext|>


<commit_before>package golf

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"net/http"
	"strings"
	"time"
)

// Context is a wrapper of http.Request and http.ResponseWriter.
type Context struct {
	// http.Request
	Request *http.Request

	// http.ResponseWriter
	Response http.ResponseWriter

	// URL Parameter
	Params Parameter

	// HTTP status code
	statusCode int

	// The application
	App *Application

	// Session instance for the current context.
	Session Session

	// Indicating if the response is already sent.
	IsSent bool

	// Indicating loader of the template
	templateLoader string
}

// NewContext creates a Golf.Context instance.
func NewContext(req *http.Request, res http.ResponseWriter, app *Application) *Context {
	ctx := new(Context)
	ctx.Request = req
	ctx.Response = res
	ctx.App = app
	ctx.statusCode = 200
	//	ctx.Header["Content-Type"] = "text/html;charset=UTF-8"
	ctx.Request.ParseForm()
	ctx.IsSent = false
	return ctx
}

func (ctx *Context) reset() {
	ctx.statusCode = 200
	ctx.IsSent = false
}

func (ctx *Context) generateSession() Session {
	s, err := ctx.App.SessionManager.NewSession()
	if err != nil {
		return nil
	}
	// Session lifetime should be configurable.
	ctx.SetCookie("sid", s.SessionID(), 3600)
	return s
}

func (ctx *Context) retrieveSession() {
	var s Session
	sid, err := ctx.Cookie("sid")
	if err != nil {
		s = ctx.generateSession()
	} else {
		s, err = ctx.App.SessionManager.Session(sid)
		if err != nil {
			s = ctx.generateSession()
		}
	}
	ctx.Session = s
}

// SendStatus takes an integer and sets the response status to the integer given.
func (ctx *Context) SendStatus(statusCode int) {
	ctx.statusCode = statusCode
	ctx.Response.WriteHeader(statusCode)
}

// StatusCode returns the status code that golf has sent.
func (ctx *Context) StatusCode() int {
	return ctx.statusCode
}

// SetHeader sets the header entries associated with key to the single element value. It replaces any existing values associated with key.
func (ctx *Context) SetHeader(key, value string) {
	ctx.Response.Header().Set(key, value)
}

// AddHeader adds the key, value pair to the header. It appends to any existing values associated with key.
func (ctx *Context) AddHeader(key, value string) {
	ctx.Response.Header().Add(key, value)
}

// Header gets the first value associated with the given key. If there are no values associated with the key, Get returns "".
func (ctx *Context) Header(key string) string {
	return ctx.Request.Header.Get(key)
}

// Query method retrieves the form data, return empty string if not found.
func (ctx *Context) Query(key string, index ...int) (string, error) {
	if val, ok := ctx.Request.Form[key]; ok {
		if len(index) == 1 {
			return val[index[0]], nil
		}
		return val[0], nil
	}
	return "", errors.New("Query key not found.")
}

// Param method retrieves the parameters from url
// If the url is /:id/, then id can be retrieved by calling `ctx.Param(id)`
func (ctx *Context) Param(key string) string {
	val, _ := ctx.Params.ByName(key)
	return val
}

// Redirect method sets the response as a 301 redirection.
// If you need a 302 redirection, please do it by setting the Header manually.
func (ctx *Context) Redirect(url string) {
	ctx.SetHeader("Location", url)
	ctx.SendStatus(301)
}

// Cookie returns the value of the cookie by indicating the key.
func (ctx *Context) Cookie(key string) (string, error) {
	c, err := ctx.Request.Cookie(key)
	if err != nil {
		return "", err
	}
	return c.Value, nil
}

// SetCookie set cookies for the request. If expire is 0, create a session cookie.
func (ctx *Context) SetCookie(key string, value string, expire int) {
	now := time.Now()
	cookie := &http.Cookie{
		Name:   key,
		Value:  value,
		Path:   "/",
		MaxAge: expire,
	}
	if expire != 0 {
		expireTime := now.Add(time.Duration(expire) * time.Second)
		cookie.Expires = expireTime
	}
	http.SetCookie(ctx.Response, cookie)
}

// JSON Sends a JSON response.
func (ctx *Context) JSON(obj interface{}) {
	json, err := json.Marshal(obj)
	if err != nil {
		panic(err)
	}
	ctx.SetHeader("Content-Type", "application/json")
	ctx.Send(json)
}

// Send the response immediately. Set `ctx.IsSent` to `true` to make
// sure that the response won't be sent twice.
func (ctx *Context) Send(body interface{}) {
	if ctx.IsSent {
		return
	}
	switch body.(type) {
	case []byte:
		ctx.Response.Write(body.([]byte))
	case string:
		ctx.Response.Write([]byte(body.(string)))
	case *bytes.Buffer:
		ctx.Response.Write(body.(*bytes.Buffer).Bytes())
	default:
		panic(fmt.Errorf("Body type not supported."))
	}
	ctx.IsSent = true
}

func (ctx *Context) requestHeader(key string) string {
	if values, _ := ctx.Request.Header[key]; len(values) > 0 {
		return values[0]
	}
	return ""
}

// ClientIP implements a best effort algorithm to return the real client IP, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
// This method is taken from https://github.com/gin-gonic/gin
func (ctx *Context) ClientIP() string {
	clientIP := strings.TrimSpace(ctx.requestHeader("X-Real-Ip"))
	if len(clientIP) > 0 {
		return clientIP
	}
	clientIP = ctx.requestHeader("X-Forwarded-For")
	if index := strings.IndexByte(clientIP, ','); index >= 0 {
		clientIP = clientIP[0:index]
	}
	clientIP = strings.TrimSpace(clientIP)
	if len(clientIP) > 0 {
		return clientIP
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(ctx.Request.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

// Abort method returns an HTTP Error by indicating the status code, the corresponding
// handler inside `App.errorHandler` will be called, if user has not set
// the corresponding error handler, the defaultErrorHandler will be called.
func (ctx *Context) Abort(statusCode int, data ...map[string]interface{}) {
	ctx.App.handleError(ctx, statusCode, data...)
}

// Loader method sets the template loader for this context. This should be done before calling
// `ctx.Render`.
func (ctx *Context) Loader(name string) *Context {
	ctx.templateLoader = name
	return ctx
}

func (ctx *Context) getRawXSRFToken() string {
	token, err := ctx.Cookie("_xsrf")
	if err != nil {
		return ""
	}
	return token
}

func (ctx *Context) checkXSRFToken() bool {
	token := ctx.Request.FormValue("xsrf_token")
	if token == "" {
		return false
	}
	_, tokenA, _ := decodeXSRFToken(token)
	_, tokenB, _ := decodeXSRFToken(ctx.getRawXSRFToken())
	return compareToken(tokenA, tokenB)
}

func (ctx *Context) xsrfToken() string {
	maskedToken := ctx.getRawXSRFToken()
	if maskedToken == "" {
		maskedToken = newXSRFToken()
		ctx.SetCookie("_xsrf", maskedToken, 3600)
	}
	_, tokenBytes, err := decodeXSRFToken(maskedToken)
	if err != nil {
		maskedToken = newXSRFToken()
		ctx.SetCookie("_xsrf", maskedToken, 3600)
		_, tokenBytes, _ = decodeXSRFToken(maskedToken)
	}
	maskBytes := randomBytes(4)
	maskedTokenBytes := append(maskBytes, websocketMask(maskBytes, tokenBytes)...)
	return hex.EncodeToString(maskedTokenBytes)
}

// Render a template file using the built-in Go template engine.
func (ctx *Context) Render(file string, data ...map[string]interface{}) {
	if ctx.templateLoader == "" {
		panic(fmt.Errorf("Template loader has not been set."))
	}
	var renderData map[string]interface{}
	if len(data) == 0 {
		renderData = make(map[string]interface{})
	} else {
		renderData = data[0]
	}
	renderData["xsrf_token"] = ctx.xsrfToken()
	content, err := ctx.App.View.Render(ctx.templateLoader, file, renderData)
	if err != nil {
		panic(err)
	}
	ctx.Send(content)
}

// RenderFromString renders a input string.
func (ctx *Context) RenderFromString(tplSrc string, data ...map[string]interface{}) {
	var renderData map[string]interface{}
	if len(data) == 0 {
		renderData = make(map[string]interface{})
	} else {
		renderData = data[0]
	}
	renderData["xsrf_token"] = ctx.xsrfToken()
	content, e := ctx.App.View.RenderFromString(ctx.templateLoader, tplSrc, renderData)
	if e != nil {
		panic(e)
	}
	ctx.Send(content)
}
<commit_msg>[fix] Parse Form when creating a new Context.<commit_after>package golf

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"net/http"
	"strings"
	"time"
)

// Context is a wrapper of http.Request and http.ResponseWriter.
type Context struct {
	// http.Request
	Request *http.Request

	// http.ResponseWriter
	Response http.ResponseWriter

	// URL Parameter
	Params Parameter

	// HTTP status code
	statusCode int

	// The application
	App *Application

	// Session instance for the current context.
	Session Session

	// Indicating if the response is already sent.
	IsSent bool

	// Indicating loader of the template
	templateLoader string
}

// NewContext creates a Golf.Context instance.
func NewContext(req *http.Request, res http.ResponseWriter, app *Application) *Context {
	ctx := new(Context)
	ctx.Request = req
	ctx.Request.ParseForm()
	ctx.Response = res
	ctx.App = app
	ctx.statusCode = 200
	//	ctx.Header["Content-Type"] = "text/html;charset=UTF-8"
	ctx.Request.ParseForm()
	ctx.IsSent = false
	return ctx
}

func (ctx *Context) reset() {
	ctx.statusCode = 200
	ctx.IsSent = false
}

func (ctx *Context) generateSession() Session {
	s, err := ctx.App.SessionManager.NewSession()
	if err != nil {
		return nil
	}
	// Session lifetime should be configurable.
	ctx.SetCookie("sid", s.SessionID(), 3600)
	return s
}

func (ctx *Context) retrieveSession() {
	var s Session
	sid, err := ctx.Cookie("sid")
	if err != nil {
		s = ctx.generateSession()
	} else {
		s, err = ctx.App.SessionManager.Session(sid)
		if err != nil {
			s = ctx.generateSession()
		}
	}
	ctx.Session = s
}

// SendStatus takes an integer and sets the response status to the integer given.
func (ctx *Context) SendStatus(statusCode int) {
	ctx.statusCode = statusCode
	ctx.Response.WriteHeader(statusCode)
}

// StatusCode returns the status code that golf has sent.
func (ctx *Context) StatusCode() int {
	return ctx.statusCode
}

// SetHeader sets the header entries associated with key to the single element value. It replaces any existing values associated with key.
func (ctx *Context) SetHeader(key, value string) {
	ctx.Response.Header().Set(key, value)
}

// AddHeader adds the key, value pair to the header. It appends to any existing values associated with key.
func (ctx *Context) AddHeader(key, value string) {
	ctx.Response.Header().Add(key, value)
}

// Header gets the first value associated with the given key. If there are no values associated with the key, Get returns "".
func (ctx *Context) Header(key string) string {
	return ctx.Request.Header.Get(key)
}

// Query method retrieves the form data, return empty string if not found.
func (ctx *Context) Query(key string, index ...int) (string, error) {
	if val, ok := ctx.Request.Form[key]; ok {
		if len(index) == 1 {
			return val[index[0]], nil
		}
		return val[0], nil
	}
	return "", errors.New("Query key not found.")
}

// Param method retrieves the parameters from url
// If the url is /:id/, then id can be retrieved by calling `ctx.Param(id)`
func (ctx *Context) Param(key string) string {
	val, _ := ctx.Params.ByName(key)
	return val
}

// Redirect method sets the response as a 301 redirection.
// If you need a 302 redirection, please do it by setting the Header manually.
func (ctx *Context) Redirect(url string) {
	ctx.SetHeader("Location", url)
	ctx.SendStatus(301)
}

// Cookie returns the value of the cookie by indicating the key.
func (ctx *Context) Cookie(key string) (string, error) {
	c, err := ctx.Request.Cookie(key)
	if err != nil {
		return "", err
	}
	return c.Value, nil
}

// SetCookie set cookies for the request. If expire is 0, create a session cookie.
func (ctx *Context) SetCookie(key string, value string, expire int) {
	now := time.Now()
	cookie := &http.Cookie{
		Name:   key,
		Value:  value,
		Path:   "/",
		MaxAge: expire,
	}
	if expire != 0 {
		expireTime := now.Add(time.Duration(expire) * time.Second)
		cookie.Expires = expireTime
	}
	http.SetCookie(ctx.Response, cookie)
}

// JSON Sends a JSON response.
func (ctx *Context) JSON(obj interface{}) {
	json, err := json.Marshal(obj)
	if err != nil {
		panic(err)
	}
	ctx.SetHeader("Content-Type", "application/json")
	ctx.Send(json)
}

// Send the response immediately. Set `ctx.IsSent` to `true` to make
// sure that the response won't be sent twice.
func (ctx *Context) Send(body interface{}) {
	if ctx.IsSent {
		return
	}
	switch body.(type) {
	case []byte:
		ctx.Response.Write(body.([]byte))
	case string:
		ctx.Response.Write([]byte(body.(string)))
	case *bytes.Buffer:
		ctx.Response.Write(body.(*bytes.Buffer).Bytes())
	default:
		panic(fmt.Errorf("Body type not supported."))
	}
	ctx.IsSent = true
}

func (ctx *Context) requestHeader(key string) string {
	if values, _ := ctx.Request.Header[key]; len(values) > 0 {
		return values[0]
	}
	return ""
}

// ClientIP implements a best effort algorithm to return the real client IP, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
// This method is taken from https://github.com/gin-gonic/gin
func (ctx *Context) ClientIP() string {
	clientIP := strings.TrimSpace(ctx.requestHeader("X-Real-Ip"))
	if len(clientIP) > 0 {
		return clientIP
	}
	clientIP = ctx.requestHeader("X-Forwarded-For")
	if index := strings.IndexByte(clientIP, ','); index >= 0 {
		clientIP = clientIP[0:index]
	}
	clientIP = strings.TrimSpace(clientIP)
	if len(clientIP) > 0 {
		return clientIP
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(ctx.Request.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

// Abort method returns an HTTP Error by indicating the status code, the corresponding
// handler inside `App.errorHandler` will be called, if user has not set
// the corresponding error handler, the defaultErrorHandler will be called.
func (ctx *Context) Abort(statusCode int, data ...map[string]interface{}) {
	ctx.App.handleError(ctx, statusCode, data...)
}

// Loader method sets the template loader for this context. This should be done before calling
// `ctx.Render`.
func (ctx *Context) Loader(name string) *Context {
	ctx.templateLoader = name
	return ctx
}

func (ctx *Context) getRawXSRFToken() string {
	token, err := ctx.Cookie("_xsrf")
	if err != nil {
		return ""
	}
	return token
}

func (ctx *Context) checkXSRFToken() bool {
	token := ctx.Request.FormValue("xsrf_token")
	if token == "" {
		return false
	}
	_, tokenA, _ := decodeXSRFToken(token)
	_, tokenB, _ := decodeXSRFToken(ctx.getRawXSRFToken())
	return compareToken(tokenA, tokenB)
}

func (ctx *Context) xsrfToken() string {
	maskedToken := ctx.getRawXSRFToken()
	if maskedToken == "" {
		maskedToken = newXSRFToken()
		ctx.SetCookie("_xsrf", maskedToken, 3600)
	}
	_, tokenBytes, err := decodeXSRFToken(maskedToken)
	if err != nil {
		maskedToken = newXSRFToken()
		ctx.SetCookie("_xsrf", maskedToken, 3600)
		_, tokenBytes, _ = decodeXSRFToken(maskedToken)
	}
	maskBytes := randomBytes(4)
	maskedTokenBytes := append(maskBytes, websocketMask(maskBytes, tokenBytes)...)
	return hex.EncodeToString(maskedTokenBytes)
}

// Render a template file using the built-in Go template engine.
func (ctx *Context) Render(file string, data ...map[string]interface{}) {
	if ctx.templateLoader == "" {
		panic(fmt.Errorf("Template loader has not been set."))
	}
	var renderData map[string]interface{}
	if len(data) == 0 {
		renderData = make(map[string]interface{})
	} else {
		renderData = data[0]
	}
	renderData["xsrf_token"] = ctx.xsrfToken()
	content, err := ctx.App.View.Render(ctx.templateLoader, file, renderData)
	if err != nil {
		panic(err)
	}
	ctx.Send(content)
}

// RenderFromString renders a input string.
func (ctx *Context) RenderFromString(tplSrc string, data ...map[string]interface{}) {
	var renderData map[string]interface{}
	if len(data) == 0 {
		renderData = make(map[string]interface{})
	} else {
		renderData = data[0]
	}
	renderData["xsrf_token"] = ctx.xsrfToken()
	content, e := ctx.App.View.RenderFromString(ctx.templateLoader, tplSrc, renderData)
	if e != nil {
		panic(e)
	}
	ctx.Send(content)
}
<|endoftext|>