<commit_before>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

type Entry struct {
	ChainID string   `json:"chainid"`
	ExtIDs  [][]byte `json:"extids"`
	Content []byte   `json:"content"`
}

func (e *Entry) Hash() []byte {
	a, err := e.MarshalBinary()
	if err != nil {
		return make([]byte, 32)
	}
	return sha52(a)
}

func (e *Entry) MarshalBinary() ([]byte, error) {
	buf := new(bytes.Buffer)
	ids, err := e.MarshalExtIDsBinary()
	if err != nil {
		return buf.Bytes(), err
	}

	// Header

	// 1 byte Version
	buf.Write([]byte{0})

	// 32 byte chainid
	if p, err := hex.DecodeString(e.ChainID); err != nil {
		return buf.Bytes(), err
	} else {
		buf.Write(p)
	}

	// 2 byte size of extids
	if err := binary.Write(buf, binary.BigEndian, int16(len(ids))); err != nil {
		return buf.Bytes(), err
	}

	// Body

	// ExtIDs
	buf.Write(ids)

	// Content
	buf.Write(e.Content)

	return buf.Bytes(), nil
}

func (e *Entry) MarshalExtIDsBinary() ([]byte, error) {
	buf := new(bytes.Buffer)

	for _, v := range e.ExtIDs {
		// 2 byte length of extid
		binary.Write(buf, binary.BigEndian, int16(len(v)))
		// extid
		buf.Write(v)
	}

	return buf.Bytes(), nil
}

func (e *Entry) MarshalJSON() ([]byte, error) {
	type js struct {
		ChainID string   `json:"chainid"`
		ExtIDs  []string `json:"extids"`
		Content string   `json:"content"`
	}

	j := new(js)

	j.ChainID = e.ChainID

	for _, id := range e.ExtIDs {
		j.ExtIDs = append(j.ExtIDs, hex.EncodeToString(id))
	}

	j.Content = hex.EncodeToString(e.Content)

	return json.Marshal(j)
}

func (e *Entry) String() string {
	var s string
	s += fmt.Sprintln("ChainID:", e.ChainID)
	for _, id := range e.ExtIDs {
		s += fmt.Sprintln("ExtID:", string(id))
	}
	s += fmt.Sprintln("Content:")
	s += fmt.Sprintln(string(e.Content))
	return s
}

func (e *Entry) UnmarshalJSON(data []byte) error {
	type js struct {
		ChainID   string   `json:"chainid"`
		ChainName []string `json:"chainname"`
		ExtIDs    []string `json:"extids"`
		Content   string   `json:"content"`
	}

	j := new(js)
	if err := json.Unmarshal(data, j); err != nil {
		return err
	}

	e.ChainID = j.ChainID

	if e.ChainID == "" {
		n := new(Entry)
		for _, v := range j.ChainName {
			if p, err := hex.DecodeString(v); err != nil {
				return fmt.Errorf("Could not decode ChainName %s: %s", v, err)
			} else {
				n.ExtIDs = append(n.ExtIDs, p)
			}
		}
		m := NewChain(n)
		e.ChainID = m.ChainID
	}

	for _, v := range j.ExtIDs {
		if p, err := hex.DecodeString(v); err != nil {
			return fmt.Errorf("Could not decode ExtID %s: %s", v, err)
		} else {
			e.ExtIDs = append(e.ExtIDs, p)
		}
	}

	p, err := hex.DecodeString(j.Content)
	if err != nil {
		return fmt.Errorf("Could not decode Content %s: %s", j.Content, err)
	}
	e.Content = p

	return nil
}

// ComposeEntryCommit creates a JSON2Request to commit a new Entry via the
// factomd web api. The request includes the marshaled MessageRequest with the
// Entry Credit Signature.
func ComposeEntryCommit(e *Entry, ec *ECAddress) (*JSON2Request, error) {
	buf := new(bytes.Buffer)

	// 1 byte version
	buf.Write([]byte{0})

	// 6 byte milliTimestamp (truncated unix time)
	buf.Write(milliTime())

	// 32 byte Entry Hash
	buf.Write(e.Hash())

	// 1 byte number of entry credits to pay
	if c, err := entryCost(e); err != nil {
		return nil, err
	} else {
		buf.WriteByte(byte(c))
	}

	// 32 byte Entry Credit Address Public Key + 64 byte Signature
	sig := ec.Sign(buf.Bytes())
	buf.Write(ec.PubBytes())
	buf.Write(sig[:])

	params := entryRequest{Entry: hex.EncodeToString(buf.Bytes())}
	req := NewJSON2Request("commit-entry", apiCounter(), params)

	return req, nil
}

// ComposeEntryReveal creates a JSON2Request to reveal the Entry via the factomd
// web api.
func ComposeEntryReveal(e *Entry) (*JSON2Request, error) {
	p, err := e.MarshalBinary()
	if err != nil {
		return nil, err
	}

	params := entryRequest{Entry: hex.EncodeToString(p)}
	req := NewJSON2Request("reveal-entry", apiCounter(), params)

	return req, nil
}

// CommitEntry sends the signed Entry Hash and the Entry Credit public key to
// the factom network. Once the payment is verified and the network is commited
// to publishing the Entry it may be published with a call to RevealEntry.
func CommitEntry(e *Entry, ec *ECAddress) (string, error) {
	type commitResponse struct {
		Message string `json:"message"`
		TxID    string `json:"txid"`
	}

	req, err := ComposeEntryReveal(e)
	if err != nil {
		return "", err
	}

	resp, err := walletRequest(req)
	if err != nil {
		return "", err
	}
	if resp.Error != nil {
		return "", resp.Error
	}
	r := new(commitResponse)
	if err := json.Unmarshal(resp.JSONResult(), r); err != nil {
		return "", err
	}

	return r.TxID, nil
}

func RevealEntry(e *Entry) error {
	req, err := ComposeEntryReveal(e)
	if err != nil {
		return err
	}

	resp, err := factomdRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}
<commit_msg>Fixed commitEntry<commit_after>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

type Entry struct {
	ChainID string   `json:"chainid"`
	ExtIDs  [][]byte `json:"extids"`
	Content []byte   `json:"content"`
}

func (e *Entry) Hash() []byte {
	a, err := e.MarshalBinary()
	if err != nil {
		return make([]byte, 32)
	}
	return sha52(a)
}

func (e *Entry) MarshalBinary() ([]byte, error) {
	buf := new(bytes.Buffer)
	ids, err := e.MarshalExtIDsBinary()
	if err != nil {
		return buf.Bytes(), err
	}

	// Header

	// 1 byte Version
	buf.Write([]byte{0})

	// 32 byte chainid
	if p, err := hex.DecodeString(e.ChainID); err != nil {
		return buf.Bytes(), err
	} else {
		buf.Write(p)
	}

	// 2 byte size of extids
	if err := binary.Write(buf, binary.BigEndian, int16(len(ids))); err != nil {
		return buf.Bytes(), err
	}

	// Body

	// ExtIDs
	buf.Write(ids)

	// Content
	buf.Write(e.Content)

	return buf.Bytes(), nil
}

func (e *Entry) MarshalExtIDsBinary() ([]byte, error) {
	buf := new(bytes.Buffer)

	for _, v := range e.ExtIDs {
		// 2 byte length of extid
		binary.Write(buf, binary.BigEndian, int16(len(v)))
		// extid
		buf.Write(v)
	}

	return buf.Bytes(), nil
}

func (e *Entry) MarshalJSON() ([]byte, error) {
	type js struct {
		ChainID string   `json:"chainid"`
		ExtIDs  []string `json:"extids"`
		Content string   `json:"content"`
	}

	j := new(js)

	j.ChainID = e.ChainID

	for _, id := range e.ExtIDs {
		j.ExtIDs = append(j.ExtIDs, hex.EncodeToString(id))
	}

	j.Content = hex.EncodeToString(e.Content)

	return json.Marshal(j)
}

func (e *Entry) String() string {
	var s string
	s += fmt.Sprintln("ChainID:", e.ChainID)
	for _, id := range e.ExtIDs {
		s += fmt.Sprintln("ExtID:", string(id))
	}
	s += fmt.Sprintln("Content:")
	s += fmt.Sprintln(string(e.Content))
	return s
}

func (e *Entry) UnmarshalJSON(data []byte) error {
	type js struct {
		ChainID   string   `json:"chainid"`
		ChainName []string `json:"chainname"`
		ExtIDs    []string `json:"extids"`
		Content   string   `json:"content"`
	}

	j := new(js)
	if err := json.Unmarshal(data, j); err != nil {
		return err
	}

	e.ChainID = j.ChainID

	if e.ChainID == "" {
		n := new(Entry)
		for _, v := range j.ChainName {
			if p, err := hex.DecodeString(v); err != nil {
				return fmt.Errorf("Could not decode ChainName %s: %s", v, err)
			} else {
				n.ExtIDs = append(n.ExtIDs, p)
			}
		}
		m := NewChain(n)
		e.ChainID = m.ChainID
	}

	for _, v := range j.ExtIDs {
		if p, err := hex.DecodeString(v); err != nil {
			return fmt.Errorf("Could not decode ExtID %s: %s", v, err)
		} else {
			e.ExtIDs = append(e.ExtIDs, p)
		}
	}

	p, err := hex.DecodeString(j.Content)
	if err != nil {
		return fmt.Errorf("Could not decode Content %s: %s", j.Content, err)
	}
	e.Content = p

	return nil
}

// ComposeEntryCommit creates a JSON2Request to commit a new Entry via the
// factomd web api. The request includes the marshaled MessageRequest with the
// Entry Credit Signature.
func ComposeEntryCommit(e *Entry, ec *ECAddress) (*JSON2Request, error) {
	buf := new(bytes.Buffer)

	// 1 byte version
	buf.Write([]byte{0})

	// 6 byte milliTimestamp (truncated unix time)
	buf.Write(milliTime())

	// 32 byte Entry Hash
	buf.Write(e.Hash())

	// 1 byte number of entry credits to pay
	if c, err := entryCost(e); err != nil {
		return nil, err
	} else {
		buf.WriteByte(byte(c))
	}

	// 32 byte Entry Credit Address Public Key + 64 byte Signature
	sig := ec.Sign(buf.Bytes())
	buf.Write(ec.PubBytes())
	buf.Write(sig[:])

	params := entryRequest{Entry: hex.EncodeToString(buf.Bytes())}
	req := NewJSON2Request("commit-entry", apiCounter(), params)

	return req, nil
}

// ComposeEntryReveal creates a JSON2Request to reveal the Entry via the factomd
// web api.
func ComposeEntryReveal(e *Entry) (*JSON2Request, error) {
	p, err := e.MarshalBinary()
	if err != nil {
		return nil, err
	}

	params := entryRequest{Entry: hex.EncodeToString(p)}
	req := NewJSON2Request("reveal-entry", apiCounter(), params)

	return req, nil
}

// CommitEntry sends the signed Entry Hash and the Entry Credit public key to
// the factom network. Once the payment is verified and the network is commited
// to publishing the Entry it may be published with a call to RevealEntry.
func CommitEntry(e *Entry, ec *ECAddress) (string, error) {
	type commitResponse struct {
		Message string `json:"message"`
		TxID    string `json:"txid"`
	}

	req, err := ComposeEntryReveal(e)
	if err != nil {
		return "", err
	}

	resp, err := factomdRequest(req)
	if err != nil {
		return "", err
	}
	if resp.Error != nil {
		return "", resp.Error
	}
	r := new(commitResponse)
	if err := json.Unmarshal(resp.JSONResult(), r); err != nil {
		return "", err
	}

	return r.TxID, nil
}

func RevealEntry(e *Entry) error {
	req, err := ComposeEntryReveal(e)
	if err != nil {
		return err
	}

	resp, err := factomdRequest(req)
	if err != nil {
		return err
	}
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}
<|endoftext|>


<commit_before>package citrixadc

import (
	"github.com/chiradeep/go-nitro/config/system"

	"github.com/chiradeep/go-nitro/netscaler"
	"github.com/hashicorp/terraform/helper/schema"

	"fmt"
	"log"
)

func resourceCitrixAdcSystemcmdpolicy() *schema.Resource {
	return &schema.Resource{
		SchemaVersion: 1,
		Create:        createSystemcmdpolicyFunc,
		Read:          readSystemcmdpolicyFunc,
		Update:        updateSystemcmdpolicyFunc,
		Delete:        deleteSystemcmdpolicyFunc,
		Schema: map[string]*schema.Schema{
			"action": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"cmdspec": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"policyname": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
		},
	}
}

func createSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG]  citrixadc-provider: In createSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Get("policyname").(string)

	systemcmdpolicy := system.Systemcmdpolicy{
		Action:     d.Get("action").(string),
		Cmdspec:    d.Get("cmdspec").(string),
		Policyname: d.Get("policyname").(string),
	}

	_, err := client.AddResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName, &systemcmdpolicy)
	if err != nil {
		return err
	}

	d.SetId(systemcmdpolicyName)

	err = readSystemcmdpolicyFunc(d, meta)
	if err != nil {
		log.Printf("[ERROR] netscaler-provider: ?? we just created this systemcmdpolicy but we can't read it ?? %s", systemcmdpolicyName)
		return nil
	}
	return nil
}

func readSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] citrixadc-provider:  In readSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Id()
	log.Printf("[DEBUG] citrixadc-provider: Reading systemcmdpolicy state %s", systemcmdpolicyName)
	data, err := client.FindResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName)
	if err != nil {
		log.Printf("[WARN] citrixadc-provider: Clearing systemcmdpolicy state %s", systemcmdpolicyName)
		d.SetId("")
		return nil
	}
	d.Set("name", data["name"])
	d.Set("action", data["action"])
	d.Set("cmdspec", data["cmdspec"])
	d.Set("policyname", data["policyname"])

	return nil

}

func updateSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG]  citrixadc-provider: In updateSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Get("policyname").(string)

	systemcmdpolicy := system.Systemcmdpolicy{
		Policyname: d.Get("policyname").(string),
	}
	hasChange := false
	if d.HasChange("action") {
		log.Printf("[DEBUG]  citrixadc-provider: Action has changed for systemcmdpolicy %s, starting update", systemcmdpolicyName)
		systemcmdpolicy.Action = d.Get("action").(string)
		systemcmdpolicy.Cmdspec = d.Get("cmdspec").(string)
		hasChange = true
	}
	if d.HasChange("cmdspec") {
		log.Printf("[DEBUG]  citrixadc-provider: Cmdspec has changed for systemcmdpolicy %s, starting update", systemcmdpolicyName)
		systemcmdpolicy.Cmdspec = d.Get("cmdspec").(string)
		systemcmdpolicy.Action = d.Get("action").(string)
		hasChange = true
	}

	if hasChange {
		_, err := client.UpdateResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName, &systemcmdpolicy)
		if err != nil {
			return fmt.Errorf("Error updating systemcmdpolicy %s:%s", systemcmdpolicyName, err.Error())
		}
	}
	return readSystemcmdpolicyFunc(d, meta)
}

func deleteSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG]  citrixadc-provider: In deleteSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Id()
	err := client.DeleteResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName)
	if err != nil {
		return err
	}

	d.SetId("")

	return nil
}
<commit_msg>Implement import operation for resource systemcmdpolicy<commit_after>package citrixadc

import (
	"github.com/chiradeep/go-nitro/config/system"

	"github.com/chiradeep/go-nitro/netscaler"
	"github.com/hashicorp/terraform/helper/schema"

	"fmt"
	"log"
)

func resourceCitrixAdcSystemcmdpolicy() *schema.Resource {
	return &schema.Resource{
		SchemaVersion: 1,
		Create:        createSystemcmdpolicyFunc,
		Read:          readSystemcmdpolicyFunc,
		Update:        updateSystemcmdpolicyFunc,
		Delete:        deleteSystemcmdpolicyFunc,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},
		Schema: map[string]*schema.Schema{
			"action": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"cmdspec": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"policyname": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
		},
	}
}

func createSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG]  citrixadc-provider: In createSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Get("policyname").(string)

	systemcmdpolicy := system.Systemcmdpolicy{
		Action:     d.Get("action").(string),
		Cmdspec:    d.Get("cmdspec").(string),
		Policyname: d.Get("policyname").(string),
	}

	_, err := client.AddResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName, &systemcmdpolicy)
	if err != nil {
		return err
	}

	d.SetId(systemcmdpolicyName)

	err = readSystemcmdpolicyFunc(d, meta)
	if err != nil {
		log.Printf("[ERROR] netscaler-provider: ?? we just created this systemcmdpolicy but we can't read it ?? %s", systemcmdpolicyName)
		return nil
	}
	return nil
}

func readSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] citrixadc-provider:  In readSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Id()
	log.Printf("[DEBUG] citrixadc-provider: Reading systemcmdpolicy state %s", systemcmdpolicyName)
	data, err := client.FindResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName)
	if err != nil {
		log.Printf("[WARN] citrixadc-provider: Clearing systemcmdpolicy state %s", systemcmdpolicyName)
		d.SetId("")
		return nil
	}
	d.Set("name", data["name"])
	d.Set("action", data["action"])
	d.Set("cmdspec", data["cmdspec"])
	d.Set("policyname", data["policyname"])

	return nil

}

func updateSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG]  citrixadc-provider: In updateSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Get("policyname").(string)

	systemcmdpolicy := system.Systemcmdpolicy{
		Policyname: d.Get("policyname").(string),
	}
	hasChange := false
	if d.HasChange("action") {
		log.Printf("[DEBUG]  citrixadc-provider: Action has changed for systemcmdpolicy %s, starting update", systemcmdpolicyName)
		systemcmdpolicy.Action = d.Get("action").(string)
		systemcmdpolicy.Cmdspec = d.Get("cmdspec").(string)
		hasChange = true
	}
	if d.HasChange("cmdspec") {
		log.Printf("[DEBUG]  citrixadc-provider: Cmdspec has changed for systemcmdpolicy %s, starting update", systemcmdpolicyName)
		systemcmdpolicy.Cmdspec = d.Get("cmdspec").(string)
		systemcmdpolicy.Action = d.Get("action").(string)
		hasChange = true
	}

	if hasChange {
		_, err := client.UpdateResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName, &systemcmdpolicy)
		if err != nil {
			return fmt.Errorf("Error updating systemcmdpolicy %s:%s", systemcmdpolicyName, err.Error())
		}
	}
	return readSystemcmdpolicyFunc(d, meta)
}

func deleteSystemcmdpolicyFunc(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG]  citrixadc-provider: In deleteSystemcmdpolicyFunc")
	client := meta.(*NetScalerNitroClient).client
	systemcmdpolicyName := d.Id()
	err := client.DeleteResource(netscaler.Systemcmdpolicy.Type(), systemcmdpolicyName)
	if err != nil {
		return err
	}

	d.SetId("")

	return nil
}
<|endoftext|>


<commit_before>package revel

import (
	"github.com/streadway/simpleuuid"
	"net/http"
	"net/url"
	"strings"
	"time"
)

// A signed cookie (and thus limited to 4kb in size).
// Restriction: Keys may not have a colon in them.
type Session map[string]string

const (
	SESSION_ID_KEY = "_ID"
)

// Return a UUID identifying this session.
func (s Session) Id() string {
	if uuidStr, ok := s[SESSION_ID_KEY]; ok {
		return uuidStr
	}

	uuid, err := simpleuuid.NewTime(time.Now())
	if err != nil {
		panic(err) // I don't think this can actually happen.
	}
	s[SESSION_ID_KEY] = uuid.String()
	return s[SESSION_ID_KEY]
}

type SessionPlugin struct{ EmptyPlugin }

func (p SessionPlugin) BeforeRequest(c *Controller) {
	c.Session = restoreSession(c.Request.Request)
}

func (p SessionPlugin) AfterRequest(c *Controller) {
	// Store the session (and sign it).
	var sessionValue string
	for key, value := range c.Session {
		if strings.Contains(key, ":") {
			panic("Session keys may not have colons")
		}
		sessionValue += "\x00" + key + ":" + value + "\x00"
	}
	sessionData := url.QueryEscape(sessionValue)
	c.SetCookie(&http.Cookie{
		Name:  CookiePrefix + "_SESSION",
		Value: Sign(sessionData) + "-" + sessionData,
		Path:  "/",
	})
}

func restoreSession(req *http.Request) Session {
	session := make(map[string]string)
	cookie, err := req.Cookie(CookiePrefix + "_SESSION")
	if err != nil {
		return Session(session)
	}

	// Separate the data from the signature.
	hyphen := strings.Index(cookie.Value, "-")
	if hyphen == -1 || hyphen >= len(cookie.Value)-1 {
		return Session(session)
	}
	sig, data := cookie.Value[:hyphen], cookie.Value[hyphen+1:]

	// Verify the signature.
	if Sign(data) != sig {
		INFO.Println("Session cookie signature failed")
		return Session(session)
	}

	ParseKeyValueCookie(data, func(key, val string) {
		session[key] = val
	})

	return Session(session)
}
<commit_msg>Fixed an injection vulnerability in session management.<commit_after>package revel

import (
	"github.com/streadway/simpleuuid"
	"net/http"
	"net/url"
	"strings"
	"time"
)

// A signed cookie (and thus limited to 4kb in size).
// Restriction: Keys may not have a colon in them.
type Session map[string]string

const (
	SESSION_ID_KEY = "_ID"
)

// Return a UUID identifying this session.
func (s Session) Id() string {
	if uuidStr, ok := s[SESSION_ID_KEY]; ok {
		return uuidStr
	}

	uuid, err := simpleuuid.NewTime(time.Now())
	if err != nil {
		panic(err) // I don't think this can actually happen.
	}
	s[SESSION_ID_KEY] = uuid.String()
	return s[SESSION_ID_KEY]
}

type SessionPlugin struct{ EmptyPlugin }

func (p SessionPlugin) BeforeRequest(c *Controller) {
	c.Session = restoreSession(c.Request.Request)
}

func (p SessionPlugin) AfterRequest(c *Controller) {
	// Store the session (and sign it).
	var sessionValue string
	for key, value := range c.Session {
		if strings.Contains(key, ":") {
			panic("Session keys may not have colons")
		}
		if strings.Contains(key, "\x00") {
			panic("Session keys may not have null bytes")
		}
		if strings.Contains(value, "\x00") {
			panic("Session values may not have null bytes")
		}
		sessionValue += "\x00" + key + ":" + value + "\x00"
	}
	sessionData := url.QueryEscape(sessionValue)
	c.SetCookie(&http.Cookie{
		Name:  CookiePrefix + "_SESSION",
		Value: Sign(sessionData) + "-" + sessionData,
		Path:  "/",
	})
}

func restoreSession(req *http.Request) Session {
	session := make(map[string]string)
	cookie, err := req.Cookie(CookiePrefix + "_SESSION")
	if err != nil {
		return Session(session)
	}

	// Separate the data from the signature.
	hyphen := strings.Index(cookie.Value, "-")
	if hyphen == -1 || hyphen >= len(cookie.Value)-1 {
		return Session(session)
	}
	sig, data := cookie.Value[:hyphen], cookie.Value[hyphen+1:]

	// Verify the signature.
	if Sign(data) != sig {
		INFO.Println("Session cookie signature failed")
		return Session(session)
	}

	ParseKeyValueCookie(data, func(key, val string) {
		session[key] = val
	})

	return Session(session)
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The gocql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gocql

import (
	"errors"
	"fmt"
	"io"
	"sync"
	"time"
)

// Session is the interface used by users to interact with the database.
//
// It's safe for concurrent use by multiple goroutines and a typical usage
// scenario is to have one global session object to interact with the
// whole Cassandra cluster.
//
// This type extends the Node interface by adding a convinient query builder
// and automatically sets a default consinstency level on all operations
// that do not have a consistency level set.
type Session struct {
	Node     Node
	cons     Consistency
	pageSize int
	prefetch float64
	trace    Tracer
	mu       sync.RWMutex
}

// NewSession wraps an existing Node.
func NewSession(node Node) *Session {
	return &Session{Node: node, cons: Quorum, prefetch: 0.25}
}

// SetConsistency sets the default consistency level for this session. This
// setting can also be changed on a per-query basis and the default value
// is Quorum.
func (s *Session) SetConsistency(cons Consistency) {
	s.mu.Lock()
	s.cons = cons
	s.mu.Unlock()
}

// SetPageSize sets the default page size for this session. A value <= 0 will
// disable paging. This setting can also be changed on a per-query basis.
func (s *Session) SetPageSize(n int) {
	s.mu.Lock()
	s.pageSize = n
	s.mu.Unlock()
}

// SetPrefetch sets the default threshold for pre-fetching new pages. If
// there are only p*pageSize rows remaining, the next page will be requested
// automatically. This value can also be changed on a per-query basis and
// the default value is 0.25.
func (s *Session) SetPrefetch(p float64) {
	s.mu.Lock()
	s.prefetch = p
	s.mu.Unlock()
}

// SetTrace sets the default tracer for this session. This setting can also
// be changed on a per-query basis.
func (s *Session) SetTrace(trace Tracer) {
	s.mu.Lock()
	s.trace = trace
	s.mu.Unlock()
}

// Query generates a new query object for interacting with the database.
// Further details of the query may be tweaked using the resulting query
// value before the query is executed.
func (s *Session) Query(stmt string, values ...interface{}) *Query {
	s.mu.RLock()
	qry := &Query{stmt: stmt, values: values, cons: s.cons,
		session: s, pageSize: s.pageSize, trace: s.trace,
		prefetch: s.prefetch}
	s.mu.RUnlock()
	return qry
}

// Close closes all connections. The session is unusable after this
// operation.
func (s *Session) Close() {
	s.Node.Close()
}

func (s *Session) executeQuery(qry *Query) *Iter {
	conn := s.Node.Pick(nil)
	if conn == nil {
		return &Iter{err: ErrUnavailable}
	}
	return conn.executeQuery(qry)
}

func (s *Session) ExecuteBatch(batch *Batch) error {
	conn := s.Node.Pick(nil)
	if conn == nil {
		return ErrUnavailable
	}
	return conn.executeBatch(batch)
}

// Query represents a CQL statement that can be executed.
type Query struct {
	stmt      string
	values    []interface{}
	cons      Consistency
	pageSize  int
	pageState []byte
	prefetch  float64
	trace     Tracer
	session   *Session
}

// Consistency sets the consistency level for this query. If no consistency
// level have been set, the default consistency level of the cluster
// is used.
func (q *Query) Consistency(c Consistency) *Query {
	q.cons = c
	return q
}

// Trace enables tracing of this query. Look at the documentation of the
// Tracer interface to learn more about tracing.
func (q *Query) Trace(trace Tracer) *Query {
	q.trace = trace
	return q
}

// PageSize will tell the iterator to fetch the result in pages of size n.
// This is useful for iterating over large result sets, but setting the
// page size to low might decrease the performance. This feature is only
// available in Cassandra 2 and onwards.
func (q *Query) PageSize(n int) *Query {
	q.pageSize = n
	return q
}

// SetPrefetch sets the default threshold for pre-fetching new pages. If
// there are only p*pageSize rows remaining, the next page will be requested
// automatically.
func (q *Query) Prefetch(p float64) *Query {
	q.prefetch = p
	return q
}

// Exec executes the query without returning any rows.
func (q *Query) Exec() error {
	iter := q.session.executeQuery(q)
	return iter.err
}

// Iter executes the query and returns an iterator capable of iterating
// over all results.
func (q *Query) Iter() *Iter {
	return q.session.executeQuery(q)
}

// Scan executes the query, copies the columns of the first selected
// row into the values pointed at by dest and discards the rest. If no rows
// were selected, ErrNotFound is returned.
func (q *Query) Scan(dest ...interface{}) error {
	iter := q.Iter()
	if iter.err != nil {
		return iter.err
	}
	if len(iter.rows) == 0 {
		return ErrNotFound
	}
	iter.Scan(dest...)
	return iter.Close()
}

// ScanCAS executes a lightweight transaction (i.e. an UPDATE or INSERT
// statement containing an IF clause). If the transaction fails because
// the existing values did not match, the previos values will be stored
// in dest.
func (q *Query) ScanCAS(dest ...interface{}) (applied bool, err error) {
	iter := q.Iter()
	if iter.err != nil {
		return false, iter.err
	}
	if len(iter.rows) == 0 {
		return false, ErrNotFound
	}
	if len(iter.Columns()) > 1 {
		dest = append([]interface{}{&applied}, dest...)
		iter.Scan(dest...)
	} else {
		iter.Scan(&applied)
	}
	return applied, iter.Close()
}

// Iter represents an iterator that can be used to iterate over all rows that
// were returned by a query. The iterator might send additional queries to the
// database during the iteration if paging was enabled.
type Iter struct {
	err     error
	pos     int
	rows    [][][]byte
	columns []ColumnInfo
	next    *nextIter
}

// Columns returns the name and type of the selected columns.
func (iter *Iter) Columns() []ColumnInfo {
	return iter.columns
}

// Scan consumes the next row of the iterator and copies the columns of the
// current row into the values pointed at by dest. Scan might send additional
// queries to the database to retrieve the next set of rows if paging was
// enabled.
//
// Scan returns true if the row was successfully unmarshaled or false if the
// end of the result set was reached or if an error occurred. Close should
// be called afterwards to retrieve any potential errors.
func (iter *Iter) Scan(dest ...interface{}) bool {
	if iter.err != nil {
		return false
	}
	if iter.pos >= len(iter.rows) {
		if iter.next != nil {
			*iter = *iter.next.fetch()
			return iter.Scan(dest...)
		}
		return false
	}
	if iter.next != nil && iter.pos == iter.next.pos {
		go iter.next.fetch()
	}
	if len(dest) > len(iter.columns) {
		iter.err = errors.New("count mismatch")
		return false
	}
	for i := 0; i < len(dest); i++ {
		err := Unmarshal(iter.columns[i].TypeInfo, iter.rows[iter.pos][i], dest[i])
		if err != nil {
			iter.err = err
			return false
		}
	}
	iter.pos++
	return true
}

// Close closes the iterator and returns any errors that happened during
// the query or the iteration.
func (iter *Iter) Close() error {
	return iter.err
}

type nextIter struct {
	qry  Query
	pos  int
	once sync.Once
	next *Iter
}

func (n *nextIter) fetch() *Iter {
	n.once.Do(func() {
		n.next = n.qry.session.executeQuery(&n.qry)
	})
	return n.next
}

type Batch struct {
	Type    BatchType
	Entries []BatchEntry
	Cons    Consistency
}

func NewBatch(typ BatchType) *Batch {
	return &Batch{Type: typ}
}

func (b *Batch) Query(stmt string, args ...interface{}) {
	b.Entries = append(b.Entries, BatchEntry{Stmt: stmt, Args: args})
}

type BatchType int

const (
	LoggedBatch   BatchType = 0
	UnloggedBatch BatchType = 1
	CounterBatch  BatchType = 2
)

type BatchEntry struct {
	Stmt string
	Args []interface{}
}

type Consistency int

const (
	Any Consistency = 1 + iota
	One
	Two
	Three
	Quorum
	All
	LocalQuorum
	EachQuorum
	Serial
	LocalSerial
)

var consinstencyNames = []string{
	0:           "default",
	Any:         "any",
	One:         "one",
	Two:         "two",
	Three:       "three",
	Quorum:      "quorum",
	All:         "all",
	LocalQuorum: "localquorum",
	EachQuorum:  "eachquorum",
	Serial:      "serial",
	LocalSerial: "localserial",
}

func (c Consistency) String() string {
	return consinstencyNames[c]
}

type ColumnInfo struct {
	Keyspace string
	Table    string
	Name     string
	TypeInfo *TypeInfo
}

// Tracer is the interface implemented by query tracers. Tracers have the
// ability to obtain a detailed event log of all events that happened during
// the execution of a query from Cassandra. Gathering this information might
// be essential for debugging and optimizing queries, but this feature should
// not be used on production systems with very high load.
type Tracer interface {
	Trace(traceId []byte)
}

type traceWriter struct {
	session *Session
	w       io.Writer
	mu      sync.Mutex
}

// NewTraceWriter returns a simple Tracer implementation that outputs
// the event log in a textual format.
func NewTraceWriter(session *Session, w io.Writer) Tracer {
	return traceWriter{session: session, w: w}
}

func (t traceWriter) Trace(traceId []byte) {
	var (
		coordinator string
		duration    int
	)
	t.session.Query(`SELECT coordinator, duration
			FROM system_traces.sessions
			WHERE session_id = ?`, traceId).
		Consistency(One).Scan(&coordinator, &duration)

	iter := t.session.Query(`SELECT event_id, activity, source, source_elapsed
			FROM system_traces.events
			WHERE session_id = ?`, traceId).
		Consistency(One).Iter()
	var (
		timestamp time.Time
		activity  string
		source    string
		elapsed   int
	)
	t.mu.Lock()
	defer t.mu.Unlock()
	fmt.Fprintf(t.w, "Tracing session %016x (coordinator: %s, duration: %v):\n",
		traceId, coordinator, time.Duration(duration)*time.Microsecond)
	for iter.Scan(&timestamp, &activity, &source, &elapsed) {
		fmt.Fprintf(t.w, "%s: %s (source: %s, elapsed: %d)\n",
			timestamp.Format("2006/01/02 15:04:05.999999"), activity, source, elapsed)
	}
	if err := iter.Close(); err != nil {
		fmt.Fprintln(t.w, "Error:", err)
	}
}

type Error struct {
	Code    int
	Message string
}

func (e Error) Error() string {
	return e.Message
}

var (
	ErrNotFound    = errors.New("not found")
	ErrUnavailable = errors.New("unavailable")
	ErrProtocol    = errors.New("protocol error")
	ErrUnsupported = errors.New("feature not supported")
)
<commit_msg>Revert changes and allow <nil> interfaces instead<commit_after>// Copyright (c) 2012 The gocql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gocql

import (
	"errors"
	"fmt"
	"io"
	"sync"
	"time"
)

// Session is the interface used by users to interact with the database.
//
// It's safe for concurrent use by multiple goroutines and a typical usage
// scenario is to have one global session object to interact with the
// whole Cassandra cluster.
//
// This type extends the Node interface by adding a convinient query builder
// and automatically sets a default consinstency level on all operations
// that do not have a consistency level set.
type Session struct {
	Node     Node
	cons     Consistency
	pageSize int
	prefetch float64
	trace    Tracer
	mu       sync.RWMutex
}

// NewSession wraps an existing Node.
func NewSession(node Node) *Session {
	return &Session{Node: node, cons: Quorum, prefetch: 0.25}
}

// SetConsistency sets the default consistency level for this session. This
// setting can also be changed on a per-query basis and the default value
// is Quorum.
func (s *Session) SetConsistency(cons Consistency) {
	s.mu.Lock()
	s.cons = cons
	s.mu.Unlock()
}

// SetPageSize sets the default page size for this session. A value <= 0 will
// disable paging. This setting can also be changed on a per-query basis.
func (s *Session) SetPageSize(n int) {
	s.mu.Lock()
	s.pageSize = n
	s.mu.Unlock()
}

// SetPrefetch sets the default threshold for pre-fetching new pages. If
// there are only p*pageSize rows remaining, the next page will be requested
// automatically. This value can also be changed on a per-query basis and
// the default value is 0.25.
func (s *Session) SetPrefetch(p float64) {
	s.mu.Lock()
	s.prefetch = p
	s.mu.Unlock()
}

// SetTrace sets the default tracer for this session. This setting can also
// be changed on a per-query basis.
func (s *Session) SetTrace(trace Tracer) {
	s.mu.Lock()
	s.trace = trace
	s.mu.Unlock()
}

// Query generates a new query object for interacting with the database.
// Further details of the query may be tweaked using the resulting query
// value before the query is executed.
func (s *Session) Query(stmt string, values ...interface{}) *Query {
	s.mu.RLock()
	qry := &Query{stmt: stmt, values: values, cons: s.cons,
		session: s, pageSize: s.pageSize, trace: s.trace,
		prefetch: s.prefetch}
	s.mu.RUnlock()
	return qry
}

// Close closes all connections. The session is unusable after this
// operation.
func (s *Session) Close() {
	s.Node.Close()
}

func (s *Session) executeQuery(qry *Query) *Iter {
	conn := s.Node.Pick(nil)
	if conn == nil {
		return &Iter{err: ErrUnavailable}
	}
	return conn.executeQuery(qry)
}

func (s *Session) ExecuteBatch(batch *Batch) error {
	conn := s.Node.Pick(nil)
	if conn == nil {
		return ErrUnavailable
	}
	return conn.executeBatch(batch)
}

// Query represents a CQL statement that can be executed.
type Query struct {
	stmt      string
	values    []interface{}
	cons      Consistency
	pageSize  int
	pageState []byte
	prefetch  float64
	trace     Tracer
	session   *Session
}

// Consistency sets the consistency level for this query. If no consistency
// level have been set, the default consistency level of the cluster
// is used.
func (q *Query) Consistency(c Consistency) *Query {
	q.cons = c
	return q
}

// Trace enables tracing of this query. Look at the documentation of the
// Tracer interface to learn more about tracing.
func (q *Query) Trace(trace Tracer) *Query {
	q.trace = trace
	return q
}

// PageSize will tell the iterator to fetch the result in pages of size n.
// This is useful for iterating over large result sets, but setting the
// page size to low might decrease the performance. This feature is only
// available in Cassandra 2 and onwards.
func (q *Query) PageSize(n int) *Query {
	q.pageSize = n
	return q
}

// SetPrefetch sets the default threshold for pre-fetching new pages. If
// there are only p*pageSize rows remaining, the next page will be requested
// automatically.
func (q *Query) Prefetch(p float64) *Query {
	q.prefetch = p
	return q
}

// Exec executes the query without returning any rows.
func (q *Query) Exec() error {
	iter := q.session.executeQuery(q)
	return iter.err
}

// Iter executes the query and returns an iterator capable of iterating
// over all results.
func (q *Query) Iter() *Iter {
	return q.session.executeQuery(q)
}

// Scan executes the query, copies the columns of the first selected
// row into the values pointed at by dest and discards the rest. If no rows
// were selected, ErrNotFound is returned.
func (q *Query) Scan(dest ...interface{}) error {
	iter := q.Iter()
	if iter.err != nil {
		return iter.err
	}
	if len(iter.rows) == 0 {
		return ErrNotFound
	}
	iter.Scan(dest...)
	return iter.Close()
}

// ScanCAS executes a lightweight transaction (i.e. an UPDATE or INSERT
// statement containing an IF clause). If the transaction fails because
// the existing values did not match, the previos values will be stored
// in dest.
func (q *Query) ScanCAS(dest ...interface{}) (applied bool, err error) {
	iter := q.Iter()
	if iter.err != nil {
		return false, iter.err
	}
	if len(iter.rows) == 0 {
		return false, ErrNotFound
	}
	if len(iter.Columns()) > 1 {
		dest = append([]interface{}{&applied}, dest...)
		iter.Scan(dest...)
	} else {
		iter.Scan(&applied)
	}
	return applied, iter.Close()
}

// Iter represents an iterator that can be used to iterate over all rows that
// were returned by a query. The iterator might send additional queries to the
// database during the iteration if paging was enabled.
type Iter struct {
	err     error
	pos     int
	rows    [][][]byte
	columns []ColumnInfo
	next    *nextIter
}

// Columns returns the name and type of the selected columns.
func (iter *Iter) Columns() []ColumnInfo {
	return iter.columns
}

// Scan consumes the next row of the iterator and copies the columns of the
// current row into the values pointed at by dest. Scan might send additional
// queries to the database to retrieve the next set of rows if paging was
// enabled.
//
// Scan returns true if the row was successfully unmarshaled or false if the
// end of the result set was reached or if an error occurred. Close should
// be called afterwards to retrieve any potential errors.
func (iter *Iter) Scan(dest ...interface{}) bool {
	if iter.err != nil {
		return false
	}
	if iter.pos >= len(iter.rows) {
		if iter.next != nil {
			*iter = *iter.next.fetch()
			return iter.Scan(dest...)
		}
		return false
	}
	if iter.next != nil && iter.pos == iter.next.pos {
		go iter.next.fetch()
	}
	if len(dest) != len(iter.columns) {
		iter.err = errors.New("count mismatch")
		return false
	}
	for i := 0; i < len(iter.columns); i++ {
		if dest[i] == nil {
			continue
		}
		err := Unmarshal(iter.columns[i].TypeInfo, iter.rows[iter.pos][i], dest[i])
		if err != nil {
			iter.err = err
			return false
		}
	}
	iter.pos++
	return true
}

// Close closes the iterator and returns any errors that happened during
// the query or the iteration.
func (iter *Iter) Close() error {
	return iter.err
}

type nextIter struct {
	qry  Query
	pos  int
	once sync.Once
	next *Iter
}

func (n *nextIter) fetch() *Iter {
	n.once.Do(func() {
		n.next = n.qry.session.executeQuery(&n.qry)
	})
	return n.next
}

type Batch struct {
	Type    BatchType
	Entries []BatchEntry
	Cons    Consistency
}

func NewBatch(typ BatchType) *Batch {
	return &Batch{Type: typ}
}

func (b *Batch) Query(stmt string, args ...interface{}) {
	b.Entries = append(b.Entries, BatchEntry{Stmt: stmt, Args: args})
}

type BatchType int

const (
	LoggedBatch   BatchType = 0
	UnloggedBatch BatchType = 1
	CounterBatch  BatchType = 2
)

type BatchEntry struct {
	Stmt string
	Args []interface{}
}

type Consistency int

const (
	Any Consistency = 1 + iota
	One
	Two
	Three
	Quorum
	All
	LocalQuorum
	EachQuorum
	Serial
	LocalSerial
)

var consinstencyNames = []string{
	0:           "default",
	Any:         "any",
	One:         "one",
	Two:         "two",
	Three:       "three",
	Quorum:      "quorum",
	All:         "all",
	LocalQuorum: "localquorum",
	EachQuorum:  "eachquorum",
	Serial:      "serial",
	LocalSerial: "localserial",
}

func (c Consistency) String() string {
	return consinstencyNames[c]
}

type ColumnInfo struct {
	Keyspace string
	Table    string
	Name     string
	TypeInfo *TypeInfo
}

// Tracer is the interface implemented by query tracers. Tracers have the
// ability to obtain a detailed event log of all events that happened during
// the execution of a query from Cassandra. Gathering this information might
// be essential for debugging and optimizing queries, but this feature should
// not be used on production systems with very high load.
type Tracer interface {
	Trace(traceId []byte)
}

type traceWriter struct {
	session *Session
	w       io.Writer
	mu      sync.Mutex
}

// NewTraceWriter returns a simple Tracer implementation that outputs
// the event log in a textual format.
func NewTraceWriter(session *Session, w io.Writer) Tracer {
	return traceWriter{session: session, w: w}
}

func (t traceWriter) Trace(traceId []byte) {
	var (
		coordinator string
		duration    int
	)
	t.session.Query(`SELECT coordinator, duration
			FROM system_traces.sessions
			WHERE session_id = ?`, traceId).
		Consistency(One).Scan(&coordinator, &duration)

	iter := t.session.Query(`SELECT event_id, activity, source, source_elapsed
			FROM system_traces.events
			WHERE session_id = ?`, traceId).
		Consistency(One).Iter()
	var (
		timestamp time.Time
		activity  string
		source    string
		elapsed   int
	)
	t.mu.Lock()
	defer t.mu.Unlock()
	fmt.Fprintf(t.w, "Tracing session %016x (coordinator: %s, duration: %v):\n",
		traceId, coordinator, time.Duration(duration)*time.Microsecond)
	for iter.Scan(&timestamp, &activity, &source, &elapsed) {
		fmt.Fprintf(t.w, "%s: %s (source: %s, elapsed: %d)\n",
			timestamp.Format("2006/01/02 15:04:05.999999"), activity, source, elapsed)
	}
	if err := iter.Close(); err != nil {
		fmt.Fprintln(t.w, "Error:", err)
	}
}

type Error struct {
	Code    int
	Message string
}

func (e Error) Error() string {
	return e.Message
}

var (
	ErrNotFound    = errors.New("not found")
	ErrUnavailable = errors.New("unavailable")
	ErrProtocol    = errors.New("protocol error")
	ErrUnsupported = errors.New("feature not supported")
)
<|endoftext|>


<commit_before>/******************************************************************************
 * A Discord API for Golang.
 *
 * This file has structs and functions specific to a session.
 *
 * A session is a single connection to Discord for a given
 * user and all REST and Websock API functions exist within
 * a session.
 *
 * See the restapi.go and wsapi.go for more information.
 */

package discordgo

import (
	"net"

	"github.com/gorilla/websocket"
)
<commit_msg>Not needed anymore.<commit_after><|endoftext|>


<commit_before>package waitress

import (
	"encoding/json"
	"net/http"
	"strings"
)

// ErrorResponse is an error that can be written as JSON.
type ErrorResponse struct {
	Code    int    `json:"-"`
	Name    string `json:"name"`
	Message string `json:"message"`
}

// MethodNotAllowedResponse is a special ErrorResponse that provides a list of
// allowed methods.
type MethodNotAllowedResponse struct {
	*ErrorResponse
	Allowed []string
}

// HTTP 400 Bad Request
func BadRequest() *ErrorResponse {
	return &ErrorResponse{
		Code: 400,
		Name: "Bad Request",
		Message: "The request could not be understood by the server " +
			"due to malformed syntax.",
	}
}

// HTTP 401 Unauthorized
func Unauthorized() *ErrorResponse {
	return &ErrorResponse{
		Code: 401,
		Name: "Unauthorized",
		Message: "Authentication is required and has failed or " +
			"not yet been provided.",
	}
}

// HTTP 403 Forbidden
func Forbidden() *ErrorResponse {
	return &ErrorResponse{
		Code: 403,
		Name: "Forbidden",
		Message: "The request was valid, but the server is refusing " +
			"to respond to it.",
	}
}

// HTTP 404 Not Found
func NotFound() *ErrorResponse {
	return &ErrorResponse{
		Code: 404,
		Name: "Not Found",
		Message: "The requested resource could not be found but " +
			"may be available again in the future.",
	}
}

// HTTP 405 Method Not Allowed
func MethodNotAllowed(allowed []string) *MethodNotAllowedResponse {
	return &MethodNotAllowedResponse{
		Allowed: allowed,
		ErrorResponse: &ErrorResponse{
			Code:    405,
			Name:    "Method Not Allowed",
			Message: "The method specified is not allowed for the resource.",
		},
	}
}

// HTTP 406 Not Acceptable
func NotAcceptable() *ErrorResponse {
	return &ErrorResponse{
		Code: 406,
		Name: "Not Acceptable",
		Message: "The requested resource is only capable of generating " +
			"content not acceptable according to the Accept headers sent " +
			"in the request.",
	}
}

// HTTP 408 Request Timeout
func RequestTimeout() *ErrorResponse {
	return &ErrorResponse{
		Code: 408,
		Name: "Request Timeout",
		Message: "The client did not produce a request within the time " +
			"that the server was prepared to wait.",
	}
}

// HTTP 409 Conflict
func Conflict() *ErrorResponse {
	return &ErrorResponse{
		Code: 409,
		Name: "Conflict",
		Message: "The request could not be completed due to a conflict " +
			"with the current state of the resource.",
	}
}

// HTTP 410 Gone
func Gone() *ErrorResponse {
	return &ErrorResponse{
		Code:    410,
		Name:    "Gone",
		Message: "The requested resource is no longer available.",
	}
}

// HTTP 411 Length Required
func LengthRequired() *ErrorResponse {
	return &ErrorResponse{
		Code: 411,
		Name: "Length Required",
		Message: "The server refuses to accept the request without a " +
			"defined Content-Length.",
	}
}

// HTTP 412 Precondition Failed
func PreconditionFailed() *ErrorResponse {
	return &ErrorResponse{
		Code: 412,
		Name: "Precondition Failed",
		Message: "The server does not meet one or more of the " +
			"preconditions given in the request.",
	}
}

// HTTP 413 Request Entity Too Large
func RequestEntityTooLarge() *ErrorResponse {
	return &ErrorResponse{
		Code: 413,
		Name: "Request Entity Too Large",
		Message: "The request is larger than the server is willing or " +
			"able to process.",
	}
}

// HTTP 414 Request URI Too Long
func RequestURITooLong() *ErrorResponse {
	return &ErrorResponse{
		Code:    414,
		Name:    "Request-URI Too Long",
		Message: "The provided URI was too long for the server to process.",
	}
}

// HTTP 415 Unsupported Media Type
func UnsupportedMediaType() *ErrorResponse {
	return &ErrorResponse{
		Code: 415,
		Name: "Unsupported Media Type",
		Message: "The request entity has a media type which the server " +
			"or resource does not support.",
	}
}

// HTTP 416 Requested Range Not Satisfiable
func RequestedRangeNotSatisfiable() *ErrorResponse {
	return &ErrorResponse{
		Code:    416,
		Name:    "Requested Range Not Satisfiable",
		Message: "The server cannot provide the requested range.",
	}
}

// HTTP 417 Expectation Failed
func ExpectationFailed() *ErrorResponse {
	return &ErrorResponse{
		Code: 417,
		Name: "Expectation Failed",
		Message: "The server cannot meet the requirements of the " +
			"Expect request-header field.",
	}
}

// HTTP 422 Unprocessable Entity
func UnprocessableEntity() *ErrorResponse {
	return &ErrorResponse{
		Code: 422,
		Name: "Unprocessable Entity",
		Message: "The request was well-formed but was unable to be " +
			"followed due to semantic errors.",
	}
}

// HTTP 429 Too Many Requests
func TooManyRequests() *ErrorResponse {
	return &ErrorResponse{
		Code: 429,
		Name: "Too Many Requests",
		Message: "The user has sent too many requests in a given " +
			"amount of time.",
	}
}

// HTTP 500 Internal Server Error
func InternalServerError() *ErrorResponse {
	return &ErrorResponse{
		Code: 500,
		Name: "Internal Server Error",
		Message: "The server encountered an unexpected condition which " +
			"prevented it from fulfilling the request.",
	}
}

// HTTP 501 Not Implemented
func NotImplemented() *ErrorResponse {
	return &ErrorResponse{
		Code: 501,
		Name: "Not Implemented",
		Message: "The server does not support the functionality required " +
			"to fulfill the request.",
	}
}

// HTTP 502 Bad Gateway
func BadGateway() *ErrorResponse {
	return &ErrorResponse{
		Code: 502,
		Name: "Bad Gateway",
		Message: "The server, while acting as a gateway or proxy, received " +
			"an invalid response from the upstream server it accessed.",
	}
}

// HTTP 503 Service Unavailable
func ServiceUnavailable() *ErrorResponse {
	return &ErrorResponse{
		Code: 503,
		Name: "Service Unavailable",
		Message: "The server is currently unable to handle the request " +
			"due to a temporary overloading or maintenance of the server.",
	}
}

// HTTP 504 Gateway Timeout
func GatewayTimeout() *ErrorResponse {
	return &ErrorResponse{
		Code: 504,
		Name: "Gateway Timeout",
		Message: "The server, while acting as a gateway or proxy, did " +
			"not receive a timely response from the upstream server.",
	}
}

// Error implements the error interface and returns the error message.
func (e *ErrorResponse) Error() string {
	return e.Message
}

// Write attempts to return the appropriate error as a friendly JSON response,
// but may fail with an HTTP 500 Internal Status Error if there was an issue
// marshalling the JSON.
func (e *ErrorResponse) Write(w http.ResponseWriter, body []byte, err error) {
	if err != nil {
		http.Error(w, "Internal Server Error", 500)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(e.Code)
	w.Write(body)
}

// ServeHTTP implements the http.Handler interface.
func (e *ErrorResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	rv, err := json.MarshalIndent(e, "", "  ")
	e.Write(w, rv, err)
}

// ServeHTTP implements the http.Handler interface.
func (e *MethodNotAllowedResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	allowed := strings.Join(e.Allowed, ", ")
	w.Header().Set("Allow", allowed)
	e.ErrorResponse.ServeHTTP(w, r)
}
<commit_msg>Clean up superfluous error handling code.<commit_after>package waitress

import (
	"encoding/json"
	"net/http"
	"strings"
)

// ErrorResponse is an error that can be written as JSON.
type ErrorResponse struct {
	Code    int    `json:"-"`
	Name    string `json:"name"`
	Message string `json:"message"`
}

// MethodNotAllowedResponse is a special ErrorResponse that provides a list of
// allowed methods.
type MethodNotAllowedResponse struct {
	*ErrorResponse
	Allowed []string
}

// HTTP 400 Bad Request
func BadRequest() *ErrorResponse {
	return &ErrorResponse{
		Code: 400,
		Name: "Bad Request",
		Message: "The request could not be understood by the server " +
			"due to malformed syntax.",
	}
}

// HTTP 401 Unauthorized
func Unauthorized() *ErrorResponse {
	return &ErrorResponse{
		Code: 401,
		Name: "Unauthorized",
		Message: "Authentication is required and has failed or " +
			"not yet been provided.",
	}
}

// HTTP 403 Forbidden
func Forbidden() *ErrorResponse {
	return &ErrorResponse{
		Code: 403,
		Name: "Forbidden",
		Message: "The request was valid, but the server is refusing " +
			"to respond to it.",
	}
}

// HTTP 404 Not Found
func NotFound() *ErrorResponse {
	return &ErrorResponse{
		Code: 404,
		Name: "Not Found",
		Message: "The requested resource could not be found but " +
			"may be available again in the future.",
	}
}

// HTTP 405 Method Not Allowed
func MethodNotAllowed(allowed []string) *MethodNotAllowedResponse {
	return &MethodNotAllowedResponse{
		Allowed: allowed,
		ErrorResponse: &ErrorResponse{
			Code:    405,
			Name:    "Method Not Allowed",
			Message: "The method specified is not allowed for the resource.",
		},
	}
}

// HTTP 406 Not Acceptable
func NotAcceptable() *ErrorResponse {
	return &ErrorResponse{
		Code: 406,
		Name: "Not Acceptable",
		Message: "The requested resource is only capable of generating " +
			"content not acceptable according to the Accept headers sent " +
			"in the request.",
	}
}

// HTTP 408 Request Timeout
func RequestTimeout() *ErrorResponse {
	return &ErrorResponse{
		Code: 408,
		Name: "Request Timeout",
		Message: "The client did not produce a request within the time " +
			"that the server was prepared to wait.",
	}
}

// HTTP 409 Conflict
func Conflict() *ErrorResponse {
	return &ErrorResponse{
		Code: 409,
		Name: "Conflict",
		Message: "The request could not be completed due to a conflict " +
			"with the current state of the resource.",
	}
}

// HTTP 410 Gone
func Gone() *ErrorResponse {
	return &ErrorResponse{
		Code:    410,
		Name:    "Gone",
		Message: "The requested resource is no longer available.",
	}
}

// HTTP 411 Length Required
func LengthRequired() *ErrorResponse {
	return &ErrorResponse{
		Code: 411,
		Name: "Length Required",
		Message: "The server refuses to accept the request without a " +
			"defined Content-Length.",
	}
}

// HTTP 412 Precondition Failed
func PreconditionFailed() *ErrorResponse {
	return &ErrorResponse{
		Code: 412,
		Name: "Precondition Failed",
		Message: "The server does not meet one or more of the " +
			"preconditions given in the request.",
	}
}

// HTTP 413 Request Entity Too Large
func RequestEntityTooLarge() *ErrorResponse {
	return &ErrorResponse{
		Code: 413,
		Name: "Request Entity Too Large",
		Message: "The request is larger than the server is willing or " +
			"able to process.",
	}
}

// HTTP 414 Request URI Too Long
func RequestURITooLong() *ErrorResponse {
	return &ErrorResponse{
		Code:    414,
		Name:    "Request-URI Too Long",
		Message: "The provided URI was too long for the server to process.",
	}
}

// HTTP 415 Unsupported Media Type
func UnsupportedMediaType() *ErrorResponse {
	return &ErrorResponse{
		Code: 415,
		Name: "Unsupported Media Type",
		Message: "The request entity has a media type which the server " +
			"or resource does not support.",
	}
}

// HTTP 416 Requested Range Not Satisfiable
func RequestedRangeNotSatisfiable() *ErrorResponse {
	return &ErrorResponse{
		Code:    416,
		Name:    "Requested Range Not Satisfiable",
		Message: "The server cannot provide the requested range.",
	}
}

// HTTP 417 Expectation Failed
func ExpectationFailed() *ErrorResponse {
	return &ErrorResponse{
		Code: 417,
		Name: "Expectation Failed",
		Message: "The server cannot meet the requirements of the " +
			"Expect request-header field.",
	}
}

// HTTP 422 Unprocessable Entity
func UnprocessableEntity() *ErrorResponse {
	return &ErrorResponse{
		Code: 422,
		Name: "Unprocessable Entity",
		Message: "The request was well-formed but was unable to be " +
			"followed due to semantic errors.",
	}
}

// HTTP 429 Too Many Requests
func TooManyRequests() *ErrorResponse {
	return &ErrorResponse{
		Code: 429,
		Name: "Too Many Requests",
		Message: "The user has sent too many requests in a given " +
			"amount of time.",
	}
}

// HTTP 500 Internal Server Error
func InternalServerError() *ErrorResponse {
	return &ErrorResponse{
		Code: 500,
		Name: "Internal Server Error",
		Message: "The server encountered an unexpected condition which " +
			"prevented it from fulfilling the request.",
	}
}

// HTTP 501 Not Implemented
func NotImplemented() *ErrorResponse {
	return &ErrorResponse{
		Code: 501,
		Name: "Not Implemented",
		Message: "The server does not support the functionality required " +
			"to fulfill the request.",
	}
}

// HTTP 502 Bad Gateway
func BadGateway() *ErrorResponse {
	return &ErrorResponse{
		Code: 502,
		Name: "Bad Gateway",
		Message: "The server, while acting as a gateway or proxy, received " +
			"an invalid response from the upstream server it accessed.",
	}
}

// HTTP 503 Service Unavailable
func ServiceUnavailable() *ErrorResponse {
	return &ErrorResponse{
		Code: 503,
		Name: "Service Unavailable",
		Message: "The server is currently unable to handle the request " +
			"due to a temporary overloading or maintenance of the server.",
	}
}

// HTTP 504 Gateway Timeout
func GatewayTimeout() *ErrorResponse {
	return &ErrorResponse{
		Code: 504,
		Name: "Gateway Timeout",
		Message: "The server, while acting as a gateway or proxy, did " +
			"not receive a timely response from the upstream server.",
	}
}

// Error implements the error interface and returns the error message.
func (e *ErrorResponse) Error() string {
	return e.Message
}

// ServeHTTP implements the http.Handler interface.
func (e *ErrorResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	b, err := json.MarshalIndent(e, "", "  ")
	if err != nil {
		http.Error(w, "Internal Server Error", 500)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(e.Code)
	w.Write(b)
}

// ServeHTTP implements the http.Handler interface.
func (e *MethodNotAllowedResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	allowed := strings.Join(e.Allowed, ", ")
	w.Header().Set("Allow", allowed)
	e.ErrorResponse.ServeHTTP(w, r)
}
<|endoftext|>


<commit_before>package eventsource

import (
	"bytes"
	"compress/zlib"
	"encoding/base64"
)

// An event is the high-level construct to send messages to clients
// It holds all the information necessary to build the actual text/stream event
type Event struct {
	Name     string
	Message  []byte
	Channels []string
	Compress bool
}

// The send function receives a list of clients and send to each client channel
// the text/stream event to be written on the client's connection
// After all clients have received the message or disconnected, the event logs
// how many clients received the message and the duration the event took to
// finish
func (e *Event) send(clients []client) {
	pending := len(clients)
	if pending == 0 {
		return
	}

	data := e.bytes()

	for i := range clients {
		c := clients[i]
		go func() {
			select {
			case c.events <- data:
			case <-c.done:
			}
		}()
	}
}

// The bytes function returns the text/stream message to be sent to the client
// If the event has name, it is added first, then the data. Optionally, the data
// can be compressed using zlib
func (e *Event) bytes() []byte {
	var buf bytes.Buffer
	if e.Name != "" {
		buf.WriteString("event: ")
		buf.WriteString(e.Name)
		buf.WriteString("\n")
	}
	buf.WriteString("data: ")
	if e.Compress {
		deflated := deflate(e.Message)
		buf.WriteString(deflated)
	} else {
		buf.Write(e.Message)
	}
	buf.WriteString("\n\n")
	return buf.Bytes()
}

// The deflate function compress a slice of bytes using zlib default compression
// and returns a base64 encoded string
func deflate(message []byte) string {
	var buf bytes.Buffer
	w := zlib.NewWriter(&buf)
	w.Write(message)
	w.Close()
	return base64.StdEncoding.EncodeToString(buf.Bytes())
}
<commit_msg>Use non-pointer methods for events<commit_after>package eventsource

import (
	"bytes"
	"compress/zlib"
	"encoding/base64"
)

// An event is the high-level construct to send messages to clients
// It holds all the information necessary to build the actual text/stream event
type Event struct {
	Name     string
	Message  []byte
	Channels []string
	Compress bool
}

// The send function receives a list of clients and send to each client channel
// the text/stream event to be written on the client's connection
func (e Event) send(clients []client) {
	pending := len(clients)
	if pending == 0 {
		return
	}

	data := e.bytes()

	for i := range clients {
		c := clients[i]
		go func() {
			select {
			case c.events <- data:
			case <-c.done:
			}
		}()
	}
}

// The bytes function returns the text/stream message to be sent to the client
// If the event has name, it is added first, then the data. Optionally, the data
// can be compressed using zlib
func (e Event) bytes() []byte {
	var buf bytes.Buffer
	if e.Name != "" {
		buf.WriteString("event: ")
		buf.WriteString(e.Name)
		buf.WriteString("\n")
	}
	buf.WriteString("data: ")
	if e.Compress {
		deflated := deflate(e.Message)
		buf.WriteString(deflated)
	} else {
		buf.Write(e.Message)
	}
	buf.WriteString("\n\n")
	return buf.Bytes()
}

// The deflate function compress a slice of bytes using zlib default compression
// and returns a base64 encoded string
func deflate(message []byte) string {
	var buf bytes.Buffer
	w := zlib.NewWriter(&buf)
	w.Write(message)
	w.Close()
	return base64.StdEncoding.EncodeToString(buf.Bytes())
}
<|endoftext|>


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

// Package bind provides interfaces and types for use when binding an app to a
// service.
package bind

import "io"

// EnvVar represents a environment variable for an app.
type EnvVar struct {
	Name         string
	Value        string
	Public       bool
	InstanceName string
}

// Unit represents an application unit to be used in binds.
type Unit interface {
	GetID() string
	GetIp() string
}

type App interface {
	// GetIp returns the app ip.
	GetIp() string

	// GetName returns the app name.
	GetName() string

	// GetUnits returns the app units.
	GetUnits() ([]Unit, error)

	// InstanceEnv returns the app enviroment variables.
	InstanceEnv(string) map[string]EnvVar

	// SetEnvs adds enviroment variables in the app.
	SetEnvs(envs []EnvVar, publicOnly bool, w io.Writer) error

	// UnsetEnvs removes the given enviroment variables from the app.
	UnsetEnvs(envNames []string, publicOnly bool, w io.Writer) error

	// AddInstance adds an instance to the application.
	AddInstance(serviceName string, instance ServiceInstance, writer io.Writer) error

	// RemoveInstance removes an instance from the application.
	RemoveInstance(serviceName string, instance ServiceInstance, writer io.Writer) error
}

type ServiceInstance struct {
	Name string            `json:"instance_name"`
	Envs map[string]string `json:"envs"`
}
<commit_msg>app/bind/binder: json format EnvVar.<commit_after>// Copyright 2015 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package bind provides interfaces and types for use when binding an app to a
// service.
package bind

import "io"

// EnvVar represents a environment variable for an app.
type EnvVar struct {
	Name         string `json:"name"`
	Value        string `json:"value"`
	Public       bool   `json:"public"`
	InstanceName string `json:"-"`
}

// Unit represents an application unit to be used in binds.
type Unit interface {
	GetID() string
	GetIp() string
}

type App interface {
	// GetIp returns the app ip.
	GetIp() string

	// GetName returns the app name.
	GetName() string

	// GetUnits returns the app units.
	GetUnits() ([]Unit, error)

	// InstanceEnv returns the app enviroment variables.
	InstanceEnv(string) map[string]EnvVar

	// SetEnvs adds enviroment variables in the app.
	SetEnvs(envs []EnvVar, publicOnly bool, w io.Writer) error

	// UnsetEnvs removes the given enviroment variables from the app.
	UnsetEnvs(envNames []string, publicOnly bool, w io.Writer) error

	// AddInstance adds an instance to the application.
	AddInstance(serviceName string, instance ServiceInstance, writer io.Writer) error

	// RemoveInstance removes an instance from the application.
	RemoveInstance(serviceName string, instance ServiceInstance, writer io.Writer) error
}

type ServiceInstance struct {
	Name string            `json:"instance_name"`
	Envs map[string]string `json:"envs"`
}
<|endoftext|>


<commit_before>// +build linux

package main

import (
	"os"
	"os/signal"
	"syscall"

	"github.com/Sirupsen/logrus"
	"github.com/opencontainers/runc/libcontainer"
	"github.com/opencontainers/runc/libcontainer/utils"
)

const signalBufferSize = 2048

// newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals
// while still forwarding all other signals to the process.
func newSignalHandler(tty *tty) *signalHandler {
	// ensure that we have a large buffer size so that we do not miss any signals
	// incase we are not processing them fast enough.
	s := make(chan os.Signal, signalBufferSize)
	// handle all signals for the process.
	signal.Notify(s)
	return &signalHandler{
		tty:     tty,
		signals: s,
	}
}

// exit models a process exit status with the pid and
// exit status.
type exit struct {
	pid    int
	status int
}

type signalHandler struct {
	signals chan os.Signal
	tty     *tty
}

// forward handles the main signal event loop forwarding, resizing, or reaping depending
// on the signal received.
func (h *signalHandler) forward(process *libcontainer.Process) (int, error) {
	// make sure we know the pid of our main process so that we can return
	// after it dies.
	pid1, err := process.Pid()
	if err != nil {
		return -1, err
	}
	// perform the initial tty resize.
	h.tty.resize()
	for s := range h.signals {
		switch s {
		case syscall.SIGWINCH:
			h.tty.resize()
		case syscall.SIGCHLD:
			exits, err := h.reap()
			if err != nil {
				logrus.Error(err)
			}
			for _, e := range exits {
				logrus.WithFields(logrus.Fields{
					"pid":    e.pid,
					"status": e.status,
				}).Debug("process exited")
				if e.pid == pid1 {
					// call Wait() on the process even though we already have the exit
					// status because we must ensure that any of the go specific process
					// fun such as flushing pipes are complete before we return.
					process.Wait()
					return e.status, nil
				}
			}
		default:
			logrus.Debugf("sending signal to process %s", s)
			if err := syscall.Kill(pid1, s.(syscall.Signal)); err != nil {
				logrus.Error(err)
			}
		}
	}
	return -1, nil
}

// reap runs wait4 in a loop until we have finished processing any existing exits
// then returns all exits to the main event loop for further processing.
func (h *signalHandler) reap() (exits []exit, err error) {
	var (
		ws  syscall.WaitStatus
		rus syscall.Rusage
	)
	for {
		pid, err := syscall.Wait4(-1, &ws, syscall.WNOHANG, &rus)
		if err != nil {
			if err == syscall.ECHILD {
				return exits, nil
			}
			return nil, err
		}
		exits = append(exits, exit{
			pid:    pid,
			status: utils.ExitStatus(ws),
		})
	}
}

func (h *signalHandler) Close() error {
	return h.tty.Close()
}
<commit_msg>signal: Fix leak<commit_after>// +build linux

package main

import (
	"os"
	"os/signal"
	"syscall"

	"github.com/Sirupsen/logrus"
	"github.com/opencontainers/runc/libcontainer"
	"github.com/opencontainers/runc/libcontainer/utils"
)

const signalBufferSize = 2048

// newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals
// while still forwarding all other signals to the process.
func newSignalHandler(tty *tty) *signalHandler {
	// ensure that we have a large buffer size so that we do not miss any signals
	// incase we are not processing them fast enough.
	s := make(chan os.Signal, signalBufferSize)
	// handle all signals for the process.
	signal.Notify(s)
	return &signalHandler{
		tty:     tty,
		signals: s,
	}
}

// exit models a process exit status with the pid and
// exit status.
type exit struct {
	pid    int
	status int
}

type signalHandler struct {
	signals chan os.Signal
	tty     *tty
}

// forward handles the main signal event loop forwarding, resizing, or reaping depending
// on the signal received.
func (h *signalHandler) forward(process *libcontainer.Process) (int, error) {
	// make sure we know the pid of our main process so that we can return
	// after it dies.
	pid1, err := process.Pid()
	if err != nil {
		return -1, err
	}
	// perform the initial tty resize.
	h.tty.resize()
	for s := range h.signals {
		switch s {
		case syscall.SIGWINCH:
			h.tty.resize()
		case syscall.SIGCHLD:
			exits, err := h.reap()
			if err != nil {
				logrus.Error(err)
			}
			for _, e := range exits {
				logrus.WithFields(logrus.Fields{
					"pid":    e.pid,
					"status": e.status,
				}).Debug("process exited")
				if e.pid == pid1 {
					// call Wait() on the process even though we already have the exit
					// status because we must ensure that any of the go specific process
					// fun such as flushing pipes are complete before we return.
					process.Wait()
					return e.status, nil
				}
			}
		default:
			logrus.Debugf("sending signal to process %s", s)
			if err := syscall.Kill(pid1, s.(syscall.Signal)); err != nil {
				logrus.Error(err)
			}
		}
	}
	return -1, nil
}

// reap runs wait4 in a loop until we have finished processing any existing exits
// then returns all exits to the main event loop for further processing.
func (h *signalHandler) reap() (exits []exit, err error) {
	var (
		ws  syscall.WaitStatus
		rus syscall.Rusage
	)
	for {
		pid, err := syscall.Wait4(-1, &ws, syscall.WNOHANG, &rus)
		if err != nil {
			if err == syscall.ECHILD {
				return exits, nil
			}
			return nil, err
		}
		if pid <= 0 {
			return exits, nil
		}
		exits = append(exits, exit{
			pid:    pid,
			status: utils.ExitStatus(ws),
		})
	}
}

func (h *signalHandler) Close() error {
	return h.tty.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"os/signal"

	"github.com/opencontainers/runc/libcontainer"
	"github.com/opencontainers/runc/libcontainer/system"
	"github.com/opencontainers/runc/libcontainer/utils"

	"github.com/sirupsen/logrus"
	"golang.org/x/sys/unix"
)

const signalBufferSize = 2048

// newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals
// while still forwarding all other signals to the process.
// If notifySocket is present, use it to read systemd notifications from the container and
// forward them to notifySocketHost.
func newSignalHandler(enableSubreaper bool, notifySocket *notifySocket) *signalHandler {
	if enableSubreaper {
		// set us as the subreaper before registering the signal handler for the container
		if err := system.SetSubreaper(1); err != nil {
			logrus.Warn(err)
		}
	}
	// ensure that we have a large buffer size so that we do not miss any signals
	// in case we are not processing them fast enough.
	s := make(chan os.Signal, signalBufferSize)
	// handle all signals for the process.
	signal.Notify(s)
	return &signalHandler{
		signals:      s,
		notifySocket: notifySocket,
	}
}

// exit models a process exit status with the pid and
// exit status.
type exit struct {
	pid    int
	status int
}

type signalHandler struct {
	signals      chan os.Signal
	notifySocket *notifySocket
}

// forward handles the main signal event loop forwarding, resizing, or reaping depending
// on the signal received.
func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) {
	// make sure we know the pid of our main process so that we can return
	// after it dies.
	if detach && h.notifySocket == nil {
		return 0, nil
	}

	pid1, err := process.Pid()
	if err != nil {
		return -1, err
	}

	if h.notifySocket != nil {
		if detach {
			_ = h.notifySocket.run(pid1)
			return 0, nil
		}
		_ = h.notifySocket.run(os.Getpid())
		go func() { _ = h.notifySocket.run(0) }()
	}

	// Perform the initial tty resize. Always ignore errors resizing because
	// stdout might have disappeared (due to races with when SIGHUP is sent).
	_ = tty.resize()
	// Handle and forward signals.
	for s := range h.signals {
		switch s {
		case unix.SIGWINCH:
			// Ignore errors resizing, as above.
			_ = tty.resize()
		case unix.SIGCHLD:
			exits, err := h.reap()
			if err != nil {
				logrus.Error(err)
			}
			for _, e := range exits {
				logrus.WithFields(logrus.Fields{
					"pid":    e.pid,
					"status": e.status,
				}).Debug("process exited")
				if e.pid == pid1 {
					// call Wait() on the process even though we already have the exit
					// status because we must ensure that any of the go specific process
					// fun such as flushing pipes are complete before we return.
					_, _ = process.Wait()
					return e.status, nil
				}
			}
		default:
			us := s.(unix.Signal)
			logrus.Debugf("forwarding signal %d (%s) to %d", int(us), unix.SignalName(us), pid1)
			if err := unix.Kill(pid1, us); err != nil {
				logrus.Error(err)
			}
		}
	}
	return -1, nil
}

// reap runs wait4 in a loop until we have finished processing any existing exits
// then returns all exits to the main event loop for further processing.
func (h *signalHandler) reap() (exits []exit, err error) {
	var (
		ws  unix.WaitStatus
		rus unix.Rusage
	)
	for {
		pid, err := unix.Wait4(-1, &ws, unix.WNOHANG, &rus)
		if err != nil {
			if err == unix.ECHILD { //nolint:errorlint // unix errors are bare
				return exits, nil
			}
			return nil, err
		}
		if pid <= 0 {
			return exits, nil
		}
		exits = append(exits, exit{
			pid:    pid,
			status: utils.ExitStatus(ws),
		})
	}
}
<commit_msg>runc run/exec: ignore SIGURG<commit_after>package main

import (
	"os"
	"os/signal"

	"github.com/opencontainers/runc/libcontainer"
	"github.com/opencontainers/runc/libcontainer/system"
	"github.com/opencontainers/runc/libcontainer/utils"

	"github.com/sirupsen/logrus"
	"golang.org/x/sys/unix"
)

const signalBufferSize = 2048

// newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals
// while still forwarding all other signals to the process.
// If notifySocket is present, use it to read systemd notifications from the container and
// forward them to notifySocketHost.
func newSignalHandler(enableSubreaper bool, notifySocket *notifySocket) *signalHandler {
	if enableSubreaper {
		// set us as the subreaper before registering the signal handler for the container
		if err := system.SetSubreaper(1); err != nil {
			logrus.Warn(err)
		}
	}
	// ensure that we have a large buffer size so that we do not miss any signals
	// in case we are not processing them fast enough.
	s := make(chan os.Signal, signalBufferSize)
	// handle all signals for the process.
	signal.Notify(s)
	return &signalHandler{
		signals:      s,
		notifySocket: notifySocket,
	}
}

// exit models a process exit status with the pid and
// exit status.
type exit struct {
	pid    int
	status int
}

type signalHandler struct {
	signals      chan os.Signal
	notifySocket *notifySocket
}

// forward handles the main signal event loop forwarding, resizing, or reaping depending
// on the signal received.
func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) {
	// make sure we know the pid of our main process so that we can return
	// after it dies.
	if detach && h.notifySocket == nil {
		return 0, nil
	}

	pid1, err := process.Pid()
	if err != nil {
		return -1, err
	}

	if h.notifySocket != nil {
		if detach {
			_ = h.notifySocket.run(pid1)
			return 0, nil
		}
		_ = h.notifySocket.run(os.Getpid())
		go func() { _ = h.notifySocket.run(0) }()
	}

	// Perform the initial tty resize. Always ignore errors resizing because
	// stdout might have disappeared (due to races with when SIGHUP is sent).
	_ = tty.resize()
	// Handle and forward signals.
	for s := range h.signals {
		switch s {
		case unix.SIGWINCH:
			// Ignore errors resizing, as above.
			_ = tty.resize()
		case unix.SIGCHLD:
			exits, err := h.reap()
			if err != nil {
				logrus.Error(err)
			}
			for _, e := range exits {
				logrus.WithFields(logrus.Fields{
					"pid":    e.pid,
					"status": e.status,
				}).Debug("process exited")
				if e.pid == pid1 {
					// call Wait() on the process even though we already have the exit
					// status because we must ensure that any of the go specific process
					// fun such as flushing pipes are complete before we return.
					_, _ = process.Wait()
					return e.status, nil
				}
			}
		case unix.SIGURG:
			// SIGURG is used by go runtime for async preemptive
			// scheduling, so runc receives it from time to time,
			// and it should not be forwarded to the container.
			// Do nothing.
		default:
			us := s.(unix.Signal)
			logrus.Debugf("forwarding signal %d (%s) to %d", int(us), unix.SignalName(us), pid1)
			if err := unix.Kill(pid1, us); err != nil {
				logrus.Error(err)
			}
		}
	}
	return -1, nil
}

// reap runs wait4 in a loop until we have finished processing any existing exits
// then returns all exits to the main event loop for further processing.
func (h *signalHandler) reap() (exits []exit, err error) {
	var (
		ws  unix.WaitStatus
		rus unix.Rusage
	)
	for {
		pid, err := unix.Wait4(-1, &ws, unix.WNOHANG, &rus)
		if err != nil {
			if err == unix.ECHILD { //nolint:errorlint // unix errors are bare
				return exits, nil
			}
			return nil, err
		}
		if pid <= 0 {
			return exits, nil
		}
		exits = append(exits, exit{
			pid:    pid,
			status: utils.ExitStatus(ws),
		})
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 JT Olds
// See LICENSE for copying information

package webhelp

import (
	"net/http"
)

type fatalBehavior func(w http.ResponseWriter, r *http.Request)

// FatalHandler takes a Handler and returns a new one that works with
// Fatal, FatalRedirect, and FatalError. FatalHandler should be placed *inside*
// a LoggingHandler, otherwise logging will be one of the things interrupted
// by Fatal calls.
func FatalHandler(h http.Handler) http.Handler {
	return RouteHandlerFunc(h, func(w http.ResponseWriter, r *http.Request) {
		rw := wrapResponseWriter(w)
		defer func() {
			rec := recover()
			if rec == nil {
				return
			}
			behavior, ok := rec.(fatalBehavior)
			if !ok {
				panic(rec)
			}
			behavior(rw, r)
			if !rw.WroteHeader() {
				rw.WriteHeader(http.StatusInternalServerError)
			}
		}()
		h.ServeHTTP(rw, r)
	})
}

// FatalRedirect is like Redirect but panics so all additional request
// processing terminates. Implemented with Fatal().
//
// IMPORTANT: must be used with FatalHandler, or else the http.ResponseWriter
// won't be able to be obtained. Because this requires FatalHandler, if
// you're writing a library intended to be used by others, please avoid this
// and other Fatal* methods. If you are writing a library intended to be used
// by yourself, you should probably avoid these methods anyway.
func FatalRedirect(redirectTo string) {
	Fatal(func(w http.ResponseWriter, r *http.Request) {
		Redirect(w, r, redirectTo)
	})
}

// FatalError is like HandleError but panics so that all additional request
// processing terminates. Implemented with Fatal()
//
// IMPORTANT: must be used with FatalHandler, or else the http.ResponseWriter
// won't be able to be obtained. Because this requires FatalHandler, if
// you're writing a library intended to be used by others, please avoid this
// and other Fatal* methods. If you are writing a library intended to be used
// by yourself, you should probably avoid these methods anyway.
func FatalError(err error) {
	Fatal(func(w http.ResponseWriter, r *http.Request) {
		HandleError(w, r, err)
	})
}

// Fatal panics in a way that FatalHandler understands to abort all additional
// request processing. Once request processing has been aborted, handler is
// called. If handler doesn't write a response, a 500 will automatically be
// returned. FatalError and FatalRedirect are implemented using this method.
//
// IMPORTANT: must be used with FatalHandler, or else the http.ResponseWriter
// won't be able to be obtained. Because this requires FatalHandler, if
// you're writing a library intended to be used by others, please avoid this
// and other Fatal* methods. If you are writing a library intended to be used
// by yourself, you should probably avoid these methods anyway.
func Fatal(handler func(w http.ResponseWriter, r *http.Request)) {
	panic(fatalBehavior(handler))
}
<commit_msg>clarify Fatal(nil)<commit_after>// Copyright (C) 2016 JT Olds
// See LICENSE for copying information

package webhelp

import (
	"net/http"
)

type fatalBehavior func(w http.ResponseWriter, r *http.Request)

// FatalHandler takes a Handler and returns a new one that works with
// Fatal, FatalRedirect, and FatalError. FatalHandler should be placed *inside*
// a LoggingHandler, otherwise logging will be one of the things interrupted
// by Fatal calls.
func FatalHandler(h http.Handler) http.Handler {
	return RouteHandlerFunc(h, func(w http.ResponseWriter, r *http.Request) {
		rw := wrapResponseWriter(w)
		defer func() {
			rec := recover()
			if rec == nil {
				return
			}
			behavior, ok := rec.(fatalBehavior)
			if !ok {
				panic(rec)
			}
			if behavior != nil {
				behavior(rw, r)
			}
			if !rw.WroteHeader() {
				rw.WriteHeader(http.StatusInternalServerError)
			}
		}()
		h.ServeHTTP(rw, r)
	})
}

// FatalRedirect is like Redirect but panics so all additional request
// processing terminates. Implemented with Fatal().
//
// IMPORTANT: must be used with FatalHandler, or else the http.ResponseWriter
// won't be able to be obtained. Because this requires FatalHandler, if
// you're writing a library intended to be used by others, please avoid this
// and other Fatal* methods. If you are writing a library intended to be used
// by yourself, you should probably avoid these methods anyway.
func FatalRedirect(redirectTo string) {
	Fatal(func(w http.ResponseWriter, r *http.Request) {
		Redirect(w, r, redirectTo)
	})
}

// FatalError is like HandleError but panics so that all additional request
// processing terminates. Implemented with Fatal()
//
// IMPORTANT: must be used with FatalHandler, or else the http.ResponseWriter
// won't be able to be obtained. Because this requires FatalHandler, if
// you're writing a library intended to be used by others, please avoid this
// and other Fatal* methods. If you are writing a library intended to be used
// by yourself, you should probably avoid these methods anyway.
func FatalError(err error) {
	Fatal(func(w http.ResponseWriter, r *http.Request) {
		HandleError(w, r, err)
	})
}

// Fatal panics in a way that FatalHandler understands to abort all additional
// request processing. Once request processing has been aborted, handler is
// called, if not nil. If handler doesn't write a response, a 500 will
// automatically be returned. FatalError and FatalRedirect are implemented
// using this method.
//
// IMPORTANT: must be used with FatalHandler, or else the http.ResponseWriter
// won't be able to be obtained. Because this requires FatalHandler, if
// you're writing a library intended to be used by others, please avoid this
// and other Fatal* methods. If you are writing a library intended to be used
// by yourself, you should probably avoid these methods anyway.
func Fatal(handler func(w http.ResponseWriter, r *http.Request)) {
	// even if handler == nil, this is NOT the same as panic(nil), so we're okay.
	panic(fatalBehavior(handler))
}
<|endoftext|>


<commit_before>package resource

import (
	"log"
	"sync/atomic"
	"time"
)

// StateRefreshFunc is a function type used for StateChangeConf that is
// responsible for refreshing the item being watched for a state change.
//
// It returns three results. `result` is any object that will be returned
// as the final object after waiting for state change. This allows you to
// return the final updated object, for example an EC2 instance after refreshing
// it.
//
// `state` is the latest state of that object. And `err` is any error that
// may have happened while refreshing the state.
type StateRefreshFunc func() (result interface{}, state string, err error)

// StateChangeConf is the configuration struct used for `WaitForState`.
type StateChangeConf struct {
	Delay          time.Duration    // Wait this time before starting checks
	Pending        []string         // States that are "allowed" and will continue trying
	Refresh        StateRefreshFunc // Refreshes the current state
	Target         []string         // Target state
	Timeout        time.Duration    // The amount of time to wait before timeout
	MinTimeout     time.Duration    // Smallest time to wait before refreshes
	PollInterval   time.Duration    // Override MinTimeout/backoff and only poll this often
	NotFoundChecks int              // Number of times to allow not found

	// This is to work around inconsistent APIs
	ContinuousTargetOccurence int // Number of times the Target state has to occur continuously
}

// WaitForState watches an object and waits for it to achieve the state
// specified in the configuration using the specified Refresh() func,
// waiting the number of seconds specified in the timeout configuration.
//
// If the Refresh function returns a error, exit immediately with that error.
//
// If the Refresh function returns a state other than the Target state or one
// listed in Pending, return immediately with an error.
//
// If the Timeout is exceeded before reaching the Target state, return an
// error.
//
// Otherwise, result the result of the first call to the Refresh function to
// reach the target state.
func (conf *StateChangeConf) WaitForState() (interface{}, error) {
	log.Printf("[DEBUG] Waiting for state to become: %s", conf.Target)

	notfoundTick := 0
	targetOccurence := 0

	// Set a default for times to check for not found
	if conf.NotFoundChecks == 0 {
		conf.NotFoundChecks = 20
	}

	if conf.ContinuousTargetOccurence == 0 {
		conf.ContinuousTargetOccurence = 1
	}

	// We can't safely read the result values if we timeout, so store them in
	// an atomic.Value
	type Result struct {
		Result interface{}
		State  string
		Error  error
	}
	var lastResult atomic.Value
	lastResult.Store(Result{})

	doneCh := make(chan struct{})
	go func() {
		defer close(doneCh)

		// Wait for the delay
		time.Sleep(conf.Delay)

		wait := 100 * time.Millisecond

		for {
			res, currentState, err := conf.Refresh()
			result := Result{
				Result: res,
				State:  currentState,
				Error:  err,
			}
			lastResult.Store(result)

			if err != nil {
				return
			}

			// If we're waiting for the absence of a thing, then return
			if res == nil && len(conf.Target) == 0 {
				targetOccurence += 1
				if conf.ContinuousTargetOccurence == targetOccurence {
					return
				} else {
					continue
				}
			}

			if res == nil {
				// If we didn't find the resource, check if we have been
				// not finding it for awhile, and if so, report an error.
				notfoundTick += 1
				if notfoundTick > conf.NotFoundChecks {
					result.Error = &NotFoundError{
						LastError: err,
						Retries:   notfoundTick,
					}
					lastResult.Store(result)
					return
				}
			} else {
				// Reset the counter for when a resource isn't found
				notfoundTick = 0
				found := false

				for _, allowed := range conf.Target {
					if currentState == allowed {
						found = true
						targetOccurence += 1
						if conf.ContinuousTargetOccurence == targetOccurence {
							return
						} else {
							continue
						}
					}
				}

				for _, allowed := range conf.Pending {
					if currentState == allowed {
						found = true
						targetOccurence = 0
						break
					}
				}

				if !found && len(conf.Pending) > 0 {
					result.Error = &UnexpectedStateError{
						LastError:     err,
						State:         result.State,
						ExpectedState: conf.Target,
					}
					lastResult.Store(result)
					return
				}
			}

			// If a poll interval has been specified, choose that interval.
			// Otherwise bound the default value.
			if conf.PollInterval > 0 && conf.PollInterval < 180*time.Second {
				wait = conf.PollInterval
			} else {
				if wait < conf.MinTimeout {
					wait = conf.MinTimeout
				} else if wait > 10*time.Second {
					wait = 10 * time.Second
				}
			}

			log.Printf("[TRACE] Waiting %s before next try", wait)
			time.Sleep(wait)

			// Wait between refreshes using exponential backoff, except when
			// waiting for the target state to reoccur.
			if targetOccurence == 0 {
				wait *= 2
			}
		}
	}()

	select {
	case <-doneCh:
		r := lastResult.Load().(Result)
		return r.Result, r.Error
	case <-time.After(conf.Timeout):
		r := lastResult.Load().(Result)
		return nil, &TimeoutError{
			LastError:     r.Error,
			LastState:     r.State,
			Timeout:       conf.Timeout,
			ExpectedState: conf.Target,
		}
	}
}
<commit_msg>don't leave WaitForState goroutine running<commit_after>package resource

import (
	"log"
	"time"
)

// StateRefreshFunc is a function type used for StateChangeConf that is
// responsible for refreshing the item being watched for a state change.
//
// It returns three results. `result` is any object that will be returned
// as the final object after waiting for state change. This allows you to
// return the final updated object, for example an EC2 instance after refreshing
// it.
//
// `state` is the latest state of that object. And `err` is any error that
// may have happened while refreshing the state.
type StateRefreshFunc func() (result interface{}, state string, err error)

// StateChangeConf is the configuration struct used for `WaitForState`.
type StateChangeConf struct {
	Delay          time.Duration    // Wait this time before starting checks
	Pending        []string         // States that are "allowed" and will continue trying
	Refresh        StateRefreshFunc // Refreshes the current state
	Target         []string         // Target state
	Timeout        time.Duration    // The amount of time to wait before timeout
	MinTimeout     time.Duration    // Smallest time to wait before refreshes
	PollInterval   time.Duration    // Override MinTimeout/backoff and only poll this often
	NotFoundChecks int              // Number of times to allow not found

	// This is to work around inconsistent APIs
	ContinuousTargetOccurence int // Number of times the Target state has to occur continuously
}

// WaitForState watches an object and waits for it to achieve the state
// specified in the configuration using the specified Refresh() func,
// waiting the number of seconds specified in the timeout configuration.
//
// If the Refresh function returns a error, exit immediately with that error.
//
// If the Refresh function returns a state other than the Target state or one
// listed in Pending, return immediately with an error.
//
// If the Timeout is exceeded before reaching the Target state, return an
// error.
//
// Otherwise, result the result of the first call to the Refresh function to
// reach the target state.
func (conf *StateChangeConf) WaitForState() (interface{}, error) {
	log.Printf("[DEBUG] Waiting for state to become: %s", conf.Target)

	notfoundTick := 0
	targetOccurence := 0

	// Set a default for times to check for not found
	if conf.NotFoundChecks == 0 {
		conf.NotFoundChecks = 20
	}

	if conf.ContinuousTargetOccurence == 0 {
		conf.ContinuousTargetOccurence = 1
	}

	type Result struct {
		Result interface{}
		State  string
		Error  error
		Done   bool
	}

	// read ever result from the refresh loop, waiting for a positive result.Done
	resCh := make(chan Result, 1)
	// cancellation channel for the refresh loop
	cancelCh := make(chan struct{})

	go func() {
		defer close(resCh)

		time.Sleep(conf.Delay)

		// start with 0 delay for the first loop
		var wait time.Duration

		for {
			// wait and watch for cancellation
			select {
			case <-cancelCh:
				return
			case <-time.After(wait):
				// first round had no wait
				if wait == 0 {
					wait = 100 * time.Millisecond
				}
			}

			res, currentState, err := conf.Refresh()
			result := Result{
				Result: res,
				State:  currentState,
				Error:  err,
			}
			resCh <- result

			if err != nil {
				return
			}

			// If we're waiting for the absence of a thing, then return
			if res == nil && len(conf.Target) == 0 {
				targetOccurence += 1
				if conf.ContinuousTargetOccurence == targetOccurence {
					result.Done = true
					resCh <- result
					return
				} else {
					continue
				}
			}

			if res == nil {
				// If we didn't find the resource, check if we have been
				// not finding it for awhile, and if so, report an error.
				notfoundTick += 1
				if notfoundTick > conf.NotFoundChecks {
					result.Error = &NotFoundError{
						LastError: err,
						Retries:   notfoundTick,
					}
					resCh <- result
					return
				}
			} else {
				// Reset the counter for when a resource isn't found
				notfoundTick = 0
				found := false

				for _, allowed := range conf.Target {
					if currentState == allowed {
						found = true
						targetOccurence += 1
						if conf.ContinuousTargetOccurence == targetOccurence {
							result.Done = true
							resCh <- result
							return
						} else {
							continue
						}
					}
				}

				for _, allowed := range conf.Pending {
					if currentState == allowed {
						found = true
						targetOccurence = 0
						break
					}
				}

				if !found && len(conf.Pending) > 0 {
					result.Error = &UnexpectedStateError{
						LastError:     err,
						State:         result.State,
						ExpectedState: conf.Target,
					}
					resCh <- result
					return
				}
			}

			// If a poll interval has been specified, choose that interval.
			// Otherwise bound the default value.
			if conf.PollInterval > 0 && conf.PollInterval < 180*time.Second {
				wait = conf.PollInterval
			} else {
				if wait < conf.MinTimeout {
					wait = conf.MinTimeout
				} else if wait > 10*time.Second {
					wait = 10 * time.Second
				}

				// Wait between refreshes using exponential backoff, except when
				// waiting for the target state to reoccur.
				if targetOccurence == 0 {
					wait *= 2
				}
			}

			log.Printf("[TRACE] Waiting %s before next try", wait)
		}
	}()

	// store the last value result from the refresh loop
	lastResult := Result{}

	timeout := time.After(conf.Timeout)
	for {
		select {
		case r, ok := <-resCh:
			// channel closed, so return the last result
			if !ok {
				return lastResult.Result, lastResult.Error
			}

			// we reached the intended state
			if r.Done {
				return r.Result, r.Error
			}

			// still waiting, store the last result
			lastResult = r

		case <-timeout:
			close(cancelCh)
			return nil, &TimeoutError{
				LastError:     lastResult.Error,
				LastState:     lastResult.State,
				Timeout:       conf.Timeout,
				ExpectedState: conf.Target,
			}
		}
	}
}
<|endoftext|>