<commit_before>package dukedb

import (
	"strconv"
)

type BaseModelIntID struct {
	ID uint64
}

func (b BaseModelIntID) GetID() string {
	return strconv.FormatUint(b.ID, 64)
}

func (b BaseModelIntID) SetID(rawId string) error {
	id, err := strconv.ParseUint(rawId, 10, 64)
	if err != nil {
		return err
	}
	b.ID = id
	return nil
}
<commit_msg>fixed basemodelintid<commit_after>package dukedb

import (
	"strconv"
)

type BaseModelIntID struct {
	ID uint64
}

func (b BaseModelIntID) GetID() string {
	return strconv.FormatUint(b.ID, 10)
}

func (b *BaseModelIntID) SetID(rawId string) error {
	id, err := strconv.ParseUint(rawId, 10, 64)
	if err != nil {
		return err
	}
	b.ID = id
	return nil
}
<|endoftext|>


<commit_before>package goutube

type MediaType int

const (
	VIDEO MediaType = iota
	AUDIO
)

func (t MediaType) String() string {
	var s string
	switch t {
	case VIDEO:
		s = "VIDEO"
	case AUDIO:
		s = "AUDIO"
	}
	return s
}

type MediaFormat struct {
	Type         string
	VideoCodec   string
	AudioCodec   string
	Raw          string
}

type Link struct {
	URL          string
	Type         MediaType
	Signature    string
	Quality      string
	Format       MediaFormat
}

type Result struct {
	Done         chan bool
	Error        chan error
	Links        []Link
}
<commit_msg>Made printing to the Link struct more human-readable<commit_after>package goutube

import "fmt"

type MediaType int

const (
	VIDEO MediaType = iota
	AUDIO
)

func (t MediaType) String() string {
	var s string
	switch t {
	case VIDEO:
		s = "VIDEO"
	case AUDIO:
		s = "AUDIO"
	}
	return s
}

type MediaFormat struct {
	Type         string
	VideoCodec   string
	AudioCodec   string
	Raw          string
}

type Link struct {
	URL          string
	Type         MediaType
	Signature    string
	Quality      string
	Format       MediaFormat
}

func (t Link) String() string {
	quality := t.Quality
	if len(quality) == 0 {
		quality = "NA"
	}
	s := fmt.Sprintf("URL: %s,\n Type: %s,\n Quality: %s,\n Format(Raw): %s\n",
		t.URL, t.Type, quality, t.Format.Raw)
	return s
}

type Result struct {
	Done         chan bool
	Error        chan error
	Links        []Link
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/csv"
	"encoding/xml"
	"github.com/gin-gonic/gin"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	"log"
	"strconv"
	"time"
)

type FiveMinuteObservation struct {
	Year_rtm              int
	Day_rtm               int
	Hourminute_rtm        int
	Air_temp107_avg       sql.NullFloat64
	Relative_humidity_avg sql.NullFloat64
	Leaf_wetness_mv_avg   sql.NullFloat64
	Solar_radiation_avg   sql.NullFloat64
	Wind_direction_d1_wvt sql.NullFloat64
	Wind_speed_wvt        sql.NullFloat64
	Rain_mm               sql.NullFloat64
	Datetime              time.Time
}

type Rain struct {
	Rain_mm  float64   `xml:"rain-mm"`
	Datetime time.Time `xml:"datetime"`
}

func (d *FiveMinuteObservation) toMawn() []string {
	values := []string{
		"5",
		strconv.Itoa(d.Year_rtm),
		strconv.Itoa(d.Day_rtm),
		strconv.Itoa(d.Hourminute_rtm),
		floatToString(d.Rain_mm),
		floatToString(d.Leaf_wetness_mv_avg),
		"",
		floatToString(d.Wind_speed_wvt),
		floatToString(d.Air_temp107_avg),
		floatToString(d.Relative_humidity_avg),
		d.Datetime.Format(time.RFC3339),
	}
	return values
}

func (d *FiveMinuteObservation) mawnHeader() []string {
	values := []string{
		"#code",
		"year",
		"day",
		"time",
		"rain_mm",
		"leaf wetness A",
		"leaf wetnetss B",
		"wind speed",
		"air temperature",
		"relative humidity",
		"timestamp",
	}
	return values
}

func (d *FiveMinuteObservation) mawnUnit() []string {
	values := []string{
		"#",
		"",
		"",
		"",
		"mm",
		"",
		"",
		"m/s",
		"C",
		"%",
	}
	return values
}

func five_minute_observations(db *sqlx.DB, c *gin.Context) {

	rows, err := db.Queryx("select * from (select air_temp107_avg, relative_humidity_avg, leaf_wetness_mv_avg, solar_radiation_avg, wind_direction_d1_wvt, wind_speed_wvt, rain_tipping_mm as rain_mm, lter_five_minute_a.datetime from weather.lter_five_minute_a order by datetime desc limit $1 ) t1 order by datetime", limit(c, 1154))

	if err != nil {
		log.Print("error in query")
		log.Fatal(err)
	}
	defer rows.Close()

	i := 0
	writer := csv.NewWriter(c.Writer)

	obs := FiveMinuteObservation{}
	writer.Write(obs.mawnHeader())
	writer.Write(obs.mawnUnit())
	for rows.Next() {
		if err := rows.StructScan(&obs); err != nil {
			log.Fatal(err)
		}

		obs.Year_rtm, obs.Day_rtm, obs.Hourminute_rtm = CampbellTime(obs.Datetime.Local())

		obs.Relative_humidity_avg.Float64 = obs.Relative_humidity_avg.Float64 * 100

		writer.Write(obs.toMawn())

		if i%500 == 0 {
			writer.Flush()
		}
		i = i + 1

	}
	writer.Flush()
}

func five_minute_observations_js(db *sqlx.DB, c *gin.Context) {
	datetime := c.Request.URL.Query().Get("datetime")

	log.Println(datetime)
	data := []FiveMinuteObservation{}

	db.Select(&data, "select rain_mm, air_temp107_avg, datetime from weather.lter_five_minute_a where datetime > $1 order by datetime desc limit 1", datetime)
	c.JSON(200, data)
}

func five_minute_observations_xml(db *sqlx.DB, c *gin.Context) {
	data := []FiveMinuteObservation{}

	db.Select(&data, "select rain_mm, datetime from weather.lter_five_minute_a order by datetime desc limit $1", limit(c, 3))
	output := make([]Rain, len(data))
	for key, value := range data {
		output[key].Rain_mm = value.Rain_mm.Float64
		output[key].Datetime = value.Datetime
	}
	xmlOut, err := xml.MarshalIndent(output, " ", " ")
	if err != nil {
		log.Fatal(err)
	}
	c.Writer.Write(xmlOut)
}
<commit_msg>pick the oldest observation that is newer than the cutoff<commit_after>package main

import (
	"database/sql"
	"encoding/csv"
	"encoding/xml"
	"github.com/gin-gonic/gin"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	"log"
	"strconv"
	"time"
)

type FiveMinuteObservation struct {
	Year_rtm              int
	Day_rtm               int
	Hourminute_rtm        int
	Air_temp107_avg       sql.NullFloat64
	Relative_humidity_avg sql.NullFloat64
	Leaf_wetness_mv_avg   sql.NullFloat64
	Solar_radiation_avg   sql.NullFloat64
	Wind_direction_d1_wvt sql.NullFloat64
	Wind_speed_wvt        sql.NullFloat64
	Rain_mm               sql.NullFloat64
	Datetime              time.Time
}

type Rain struct {
	Rain_mm  float64   `xml:"rain-mm"`
	Datetime time.Time `xml:"datetime"`
}

func (d *FiveMinuteObservation) toMawn() []string {
	values := []string{
		"5",
		strconv.Itoa(d.Year_rtm),
		strconv.Itoa(d.Day_rtm),
		strconv.Itoa(d.Hourminute_rtm),
		floatToString(d.Rain_mm),
		floatToString(d.Leaf_wetness_mv_avg),
		"",
		floatToString(d.Wind_speed_wvt),
		floatToString(d.Air_temp107_avg),
		floatToString(d.Relative_humidity_avg),
		d.Datetime.Format(time.RFC3339),
	}
	return values
}

func (d *FiveMinuteObservation) mawnHeader() []string {
	values := []string{
		"#code",
		"year",
		"day",
		"time",
		"rain_mm",
		"leaf wetness A",
		"leaf wetnetss B",
		"wind speed",
		"air temperature",
		"relative humidity",
		"timestamp",
	}
	return values
}

func (d *FiveMinuteObservation) mawnUnit() []string {
	values := []string{
		"#",
		"",
		"",
		"",
		"mm",
		"",
		"",
		"m/s",
		"C",
		"%",
	}
	return values
}

func five_minute_observations(db *sqlx.DB, c *gin.Context) {

	rows, err := db.Queryx("select * from (select air_temp107_avg, relative_humidity_avg, leaf_wetness_mv_avg, solar_radiation_avg, wind_direction_d1_wvt, wind_speed_wvt, rain_tipping_mm as rain_mm, lter_five_minute_a.datetime from weather.lter_five_minute_a order by datetime desc limit $1 ) t1 order by datetime", limit(c, 1154))

	if err != nil {
		log.Print("error in query")
		log.Fatal(err)
	}
	defer rows.Close()

	i := 0
	writer := csv.NewWriter(c.Writer)

	obs := FiveMinuteObservation{}
	writer.Write(obs.mawnHeader())
	writer.Write(obs.mawnUnit())
	for rows.Next() {
		if err := rows.StructScan(&obs); err != nil {
			log.Fatal(err)
		}

		obs.Year_rtm, obs.Day_rtm, obs.Hourminute_rtm = CampbellTime(obs.Datetime.Local())

		obs.Relative_humidity_avg.Float64 = obs.Relative_humidity_avg.Float64 * 100

		writer.Write(obs.toMawn())

		if i%500 == 0 {
			writer.Flush()
		}
		i = i + 1

	}
	writer.Flush()
}

func five_minute_observations_js(db *sqlx.DB, c *gin.Context) {
	datetime := c.Request.URL.Query().Get("datetime")

	log.Println(datetime)
	data := []FiveMinuteObservation{}

	db.Select(&data, "select rain_mm, air_temp107_avg, datetime from weather.lter_five_minute_a where datetime > $1 order by datetime limit 1", datetime)
	c.JSON(200, data)
}

func five_minute_observations_xml(db *sqlx.DB, c *gin.Context) {
	data := []FiveMinuteObservation{}

	db.Select(&data, "select rain_mm, datetime from weather.lter_five_minute_a order by datetime desc limit $1", limit(c, 3))
	output := make([]Rain, len(data))
	for key, value := range data {
		output[key].Rain_mm = value.Rain_mm.Float64
		output[key].Datetime = value.Datetime
	}
	xmlOut, err := xml.MarshalIndent(output, " ", " ")
	if err != nil {
		log.Fatal(err)
	}
	c.Writer.Write(xmlOut)
}
<|endoftext|>


<commit_before>package sources

import (
	"net/http"
	"fmt"
	"encoding/json"
	"github.com/golang/glog"
	"bytes")

type DmrContainer struct {
	Name    string      `json:"name,omitempty"`
	Host    string      `json:"host"`
	DmrPort int         `json:"dmrPort"`
	Stats   *StatsEntry `json:"stats,omitempty"`
}

type DmrAttributeRequest struct {
	Operation 	string	`json:"operation"`
	Name      	string	`json:"name"`
	Pretty		int		`json:"json.pretty"`
}

type DmrResourceRequest struct {
	Operation 			string		`json:"operation"`
	IncludeRuntime      bool		`json:"include-runtime"`
	Address				[]string	`json:"address"`
	Pretty				int			`json:"json.pretty"`
}

type DmrResponse struct {
	Outcome 				string		`json:"outcome"`
	Result      			interface{}	`json:"result"`
	FailureDescription      string		`json:"failure-description"`
	RolledBacked      		bool		`json:"rolled-back"`
}

type WebResult struct {
	BytesReceived		StringInt			`json:"bytesReceived"`
	BytesSent			StringInt			`json:"bytesSent"`
	EnableLookups		bool				`json:"enable-lookups"`
	Enabled				bool				`json:"enabled"`
	ErrorCount			StringInt			`json:"errorCount"`
	Executor			string				`json:"executor"`
	MaxConnections		int					`json:"max-connections"`
	MaxPostSize			int64				`json:"max-post-size"`
	MaxSavePostSize		int64				`json:"max-save-post-size"`
	MaxTime				StringInt			`json:"maxTime"`
	Name				string				`json:"name"`
	ProcessingTime		StringInt			`json:"processingTime"`
	Protocol			string				`json:"protocol"`
	ProxyName			string				`json:"proxy-name"`
	ProxyPort			string				`json:"proxy-port"`
	RedirectPort		int					`json:"redirect-port"`
	RequestCount		StringInt			`json:"requestCount"`
	Scheme				string				`json:"scheme"`
	Secure				bool				`json:"secure"`
	SocketBinding		string				`json:"socket-binding"`
	SSL					string				`json:"ssl"`
	VirtualServer		string				`json:"virtual-server"`
}

func (self *DmrContainer) GetName() string {
	return self.Name
}

func (self *DmrContainer) GetStats() (*StatsEntry, error) {
	dmrRequest := DmrResourceRequest{
		Operation: "read-resource",
		IncludeRuntime: true,
		Address: []string{"subsystem", "web", "connector", "http"},
		Pretty: 1,
	}

	wr := WebResult{}
	dmrResponse := DmrResponse{
		Result: &wr,
	}

	err := self.getStats(&dmrRequest, &dmrResponse)
	if err != nil {
		return nil, err
	}

	glog.Infof("outcome: %s, result: %s, failure: %s", dmrResponse.Outcome, dmrResponse.Result, dmrResponse.FailureDescription)

	return &StatsEntry{}, nil
}

func (self *DmrContainer) getStats(request interface{}, result interface{}) error {
	reqBody, err := json.Marshal(request)
	if err != nil {
		return err
	}

	url := fmt.Sprintf("http://%s:%d/management", self.Host, self.DmrPort)

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(reqBody))
	if err != nil {
		return err
	}

	req.Header.Add("Content-Type", "application/json")

	err = PostRequestAndGetValue(&http.Client{}, req, result)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>copying DMR response into struct<commit_after>package sources

import (
	"net/http"
	"fmt"
	"encoding/json"
	"github.com/golang/glog"
	"bytes")

type DmrContainer struct {
	Name    string      `json:"name,omitempty"`
	Host    string      `json:"host"`
	DmrPort int         `json:"dmrPort"`
	Stats   *StatsEntry `json:"stats,omitempty"`
}

type DmrAttributeRequest struct {
	Operation 	string	`json:"operation"`
	Name      	string	`json:"name"`
	Pretty		int		`json:"json.pretty"`
}

type DmrResourceRequest struct {
	Operation 			string		`json:"operation"`
	IncludeRuntime      bool		`json:"include-runtime"`
	Address				[]string	`json:"address"`
	Pretty				int			`json:"json.pretty"`
}

type DmrResponse struct {
	Outcome 				string		`json:"outcome"`
	Result      			interface{}	`json:"result"`
	FailureDescription      string		`json:"failure-description"`
	RolledBacked      		bool		`json:"rolled-back"`
}

type WebResult struct {
	BytesReceived		StringInt			`json:"bytesReceived"`
	BytesSent			StringInt			`json:"bytesSent"`
	EnableLookups		bool				`json:"enable-lookups"`
	Enabled				bool				`json:"enabled"`
	ErrorCount			StringInt			`json:"errorCount"`
	Executor			string				`json:"executor"`
	MaxConnections		int					`json:"max-connections"`
	MaxPostSize			int64				`json:"max-post-size"`
	MaxSavePostSize		int64				`json:"max-save-post-size"`
	MaxTime				StringInt			`json:"maxTime"`
	Name				string				`json:"name"`
	ProcessingTime		StringInt			`json:"processingTime"`
	Protocol			string				`json:"protocol"`
	ProxyName			string				`json:"proxy-name"`
	ProxyPort			string				`json:"proxy-port"`
	RedirectPort		int					`json:"redirect-port"`
	RequestCount		StringInt			`json:"requestCount"`
	Scheme				string				`json:"scheme"`
	Secure				bool				`json:"secure"`
	SocketBinding		string				`json:"socket-binding"`
	SSL					string				`json:"ssl"`
	VirtualServer		string				`json:"virtual-server"`
}

func (self *DmrContainer) GetName() string {
	return self.Name
}

func (self *DmrContainer) GetStats() (*StatsEntry, error) {
	dmrRequest := DmrResourceRequest{
		Operation: "read-resource",
		IncludeRuntime: true,
		Address: []string{"subsystem", "web", "connector", "http"},
		Pretty: 1,
	}

	wr := WebResult{}
	dmrResponse := DmrResponse{
		Result: &wr,
	}

	err := self.getStats(&dmrRequest, &dmrResponse)
	if err != nil {
		return nil, err
	}

	glog.Infof("outcome: %s, result: %s, failure: %s", dmrResponse.Outcome, dmrResponse.Result, dmrResponse.FailureDescription)

	dmrStats := make(map[string]interface{})
	dmrStats["bytes_received"] = wr.BytesReceived
	dmrStats["bytes_sent"] = wr.BytesSent
	dmrStats["enable_lookups"] = wr.EnableLookups
	dmrStats["enabled"] = wr.Enabled
	dmrStats["error_count"] = wr.ErrorCount
	dmrStats["executor"] = wr.Executor
	dmrStats["max_connections"] = wr.MaxConnections
	dmrStats["max_post_size"] = wr.MaxPostSize
	dmrStats["max_save_post_size"] = wr.MaxSavePostSize
	dmrStats["max_time"] = wr.MaxTime
	dmrStats["name"] = wr.Name
	dmrStats["processing_time"] = wr.ProcessingTime
	dmrStats["protocol"] = wr.Protocol
	dmrStats["proxy_name"] = wr.ProxyName
	dmrStats["proxy_port"] = wr.ProxyPort
	dmrStats["redirect_port"] = wr.RedirectPort
	dmrStats["request_count"] = wr.RequestCount
	dmrStats["scheme"] = wr.Scheme
	dmrStats["secure"] = wr.Secure
	dmrStats["socket_binding"] = wr.SocketBinding
	dmrStats["ssl"] = wr.SSL
	dmrStats["virtual_server"] = wr.VirtualServer

	responseStats := make(map[string]StatsValue)
	responseStats["dmr"] = dmrStats

	result := &StatsEntry {
		Timestamp: time.Now().Local(),
		Stats:     responseStats,
	}

	glog.V(2).Infof("Retrieved DMR stats: %v", dmrStats)

	return result, nil
}

func (self *DmrContainer) getStats(request interface{}, result interface{}) error {
	reqBody, err := json.Marshal(request)
	if err != nil {
		return err
	}

	url := fmt.Sprintf("http://%s:%d/management", self.Host, self.DmrPort)

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(reqBody))
	if err != nil {
		return err
	}

	req.Header.Add("Content-Type", "application/json")

	err = PostRequestAndGetValue(&http.Client{}, req, result)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package orbit

import (
	"fmt"
	"path"

	"github.com/robertkrimen/otto"
)

var (
	beg = "(function(module) { var require = module.require; var exports = module.exports; var __dirname = module.__dirname; var __filename = module.__filename;"
	end = "})"
)

func null() module {
	return func(ctx *Orbit) (val otto.Value, err error) {
		return otto.UndefinedValue(), nil
	}
}

func load(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		// Check loaded modules
		if module, ok := ctx.modules[name]; ok {
			return module, nil
		}

		// Check global modules
		if module, ok := modules[name]; ok {
			return module(ctx)
		}

		ctx.modules[name], err = find(name, fold)(ctx)

		return ctx.modules[name], err

	}
}

func find(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if len(name) == 0 {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		var files []string

		if path.IsAbs(name) == true {
			if path.Ext(name) != "" {
				files = append(files, name)
			}
			if path.Ext(name) == "" {
				files = append(files, name+".js")
				files = append(files, path.Join(name, "index.js"))
			}
		}

		if path.IsAbs(name) == false {
			if path.Ext(name) != "" {
				files = append(files, path.Join(fold, name))
			}
			if path.Ext(name) == "" {
				files = append(files, path.Join(fold, name)+".js")
				files = append(files, path.Join(fold, name, "index.js"))
			}
		}

		code, file, err := finder(ctx, files)
		if err != nil {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		return exec(code, file)(ctx)

	}
}

func main(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		slf, _ := module.Get("exports")

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(slf, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}

func exec(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if path.Ext(full) == ".json" {
			return ctx.Call("JSON.parse", nil, fmt.Sprintf("%s", code))
		}

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		slf, _ := module.Get("exports")

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(slf, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}
<commit_msg>Don’t start node.js module code on second line<commit_after>// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package orbit

import (
	"fmt"
	"path"

	"github.com/robertkrimen/otto"
)

var (
	beg = "(function(module) { var require = module.require; var exports = module.exports; var __dirname = module.__dirname; var __filename = module.__filename;"
	end = "})"
)

func null() module {
	return func(ctx *Orbit) (val otto.Value, err error) {
		return otto.UndefinedValue(), nil
	}
}

func load(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		// Check loaded modules
		if module, ok := ctx.modules[name]; ok {
			return module, nil
		}

		// Check global modules
		if module, ok := modules[name]; ok {
			return module(ctx)
		}

		ctx.modules[name], err = find(name, fold)(ctx)

		return ctx.modules[name], err

	}
}

func find(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if len(name) == 0 {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		var files []string

		if path.IsAbs(name) == true {
			if path.Ext(name) != "" {
				files = append(files, name)
			}
			if path.Ext(name) == "" {
				files = append(files, name+".js")
				files = append(files, path.Join(name, "index.js"))
			}
		}

		if path.IsAbs(name) == false {
			if path.Ext(name) != "" {
				files = append(files, path.Join(fold, name))
			}
			if path.Ext(name) == "" {
				files = append(files, path.Join(fold, name)+".js")
				files = append(files, path.Join(fold, name, "index.js"))
			}
		}

		code, file, err := finder(ctx, files)
		if err != nil {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		return exec(code, file)(ctx)

	}
}

func main(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s %s %s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		slf, _ := module.Get("exports")

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(slf, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}

func exec(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if path.Ext(full) == ".json" {
			return ctx.Call("JSON.parse", nil, fmt.Sprintf("%s", code))
		}

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s %s %s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		slf, _ := module.Get("exports")

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(slf, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}
<|endoftext|>


<commit_before>package build

import (
	"flag"
	"testing"

	"github.com/google/go-cmp/cmp"
)

func TestFlags(t *testing.T) {
	cases := []struct {
		args []string
		want Options
	}{{
		// Defaults
		args: []string{},
		want: Options{},
	}, {
		args: []string{"-index", "/tmp"},
		want: Options{
			IndexDir: "/tmp",
		},
	}, {
		// single large file pattern
		args: []string{"-large_file", "*.md"},
		want: Options{
			LargeFiles: []string{"*.md"},
		},
	}, {
		// multiple large file pattern
		args: []string{"-large_file", "*.md", "-large_file", "*.yaml"},
		want: Options{
			LargeFiles: []string{"*.md", "*.yaml"},
		},
	}}

	for _, c := range cases {
		c.want.SetDefaults()

		got := Options{}
		fs := flag.NewFlagSet("", flag.ContinueOnError)
		got.Flags(fs)
		if err := fs.Parse(c.args); err != nil {
			t.Errorf("failed to parse args %v: %v", c.args, err)
		} else if !cmp.Equal(got, c.want) {
			t.Errorf("mismatch for %v (-want +got):\n%s", c.args, cmp.Diff(c.want, got))
		}
	}
}
<commit_msg>build: filter out CTags setting from flag parse test<commit_after>package build

import (
	"flag"
	"testing"

	"github.com/google/go-cmp/cmp"
)

func TestFlags(t *testing.T) {
	cases := []struct {
		args []string
		want Options
	}{{
		// Defaults
		args: []string{},
		want: Options{},
	}, {
		args: []string{"-index", "/tmp"},
		want: Options{
			IndexDir: "/tmp",
		},
	}, {
		// single large file pattern
		args: []string{"-large_file", "*.md"},
		want: Options{
			LargeFiles: []string{"*.md"},
		},
	}, {
		// multiple large file pattern
		args: []string{"-large_file", "*.md", "-large_file", "*.yaml"},
		want: Options{
			LargeFiles: []string{"*.md", "*.yaml"},
		},
	}}

	for _, c := range cases {
		c.want.SetDefaults()
		// depends on $PATH setting.
		c.want.CTags = ""

		got := Options{}
		fs := flag.NewFlagSet("", flag.ContinueOnError)
		got.Flags(fs)
		if err := fs.Parse(c.args); err != nil {
			t.Errorf("failed to parse args %v: %v", c.args, err)
		} else if !cmp.Equal(got, c.want) {
			t.Errorf("mismatch for %v (-want +got):\n%s", c.args, cmp.Diff(c.want, got))
		}
	}
}
<|endoftext|>


<commit_before>package handlers

import (
	"fmt"

	"github.com/gizak/termui"
	"github.com/nlopes/slack"

	"github.com/erroneousboat/slack-term/src/context"
	"github.com/erroneousboat/slack-term/src/views"
)

func RegisterEventHandlers(ctx *context.AppContext) {
	termui.Handle("/sys/kbd/", anyKeyHandler(ctx))
	termui.Handle("/sys/wnd/resize", resizeHandler(ctx))
	termui.Handle("/timer/1s", timeHandler(ctx))

	// TODO: check channel of message should be added to correct channel
	go func() {
		for {
			select {
			case msg := <-ctx.Service.RTM.IncomingEvents:
				switch ev := msg.Data.(type) {
				case *slack.MessageEvent:
					var name string
					user, err := ctx.Service.Client.GetUserInfo(ev.User)
					if err == nil {
						name = user.Name
					} else {
						name = "unknown"
					}
					msg := fmt.Sprintf("[%s] %s", name, ev.Text)
					ctx.View.Chat.AddMessage(msg)
				}
			}
		}
	}()
}

func anyKeyHandler(ctx *context.AppContext) func(termui.Event) {
	return func(e termui.Event) {
		key := e.Data.(termui.EvtKbd).KeyStr

		if ctx.Mode == context.CommandMode {
			switch key {
			case "q":
				actionQuit()
				return
			case "i":
				actionInsertMode(ctx)
				return
			}
		} else if ctx.Mode == context.InsertMode {
			switch key {
			case "<escape>":
				actionCommandMode(ctx)
				return
			case "<enter>":
				actionSend(ctx)
				return
			case "<space>":
				actionInput(ctx.View, " ")
				return
			case "<backspace>":
				actionBackSpace(ctx.View)
			case "C-8":
				actionBackSpace(ctx.View)
			case "<right>":
				actionMoveCursorRight(ctx.View)
			case "<left>":
				actionMoveCursorLeft(ctx.View)
			default:
				actionInput(ctx.View, key)
				return
			}

		}

	}
}

func resizeHandler(ctx *context.AppContext) func(termui.Event) {
	return func(e termui.Event) {
		actionResize(ctx)
	}
}

func timeHandler(ctx *context.AppContext) func(termui.Event) {
	return func(e termui.Event) {
	}
}

// FIXME: resize only seems to work for width and resizing it too small
// will cause termui to panic
func actionResize(ctx *context.AppContext) {
	termui.Body.Width = termui.TermWidth()
	termui.Body.Align()
	termui.Render(termui.Body)
}

func actionInput(view *views.View, key string) {
	view.Input.Insert(key)
	termui.Render(view.Input)
}

func actionBackSpace(view *views.View) {
	view.Input.Remove()
	termui.Render(view.Input)
}

func actionMoveCursorRight(view *views.View) {
	view.Input.MoveCursorRight()
	termui.Render(view.Input)
}

func actionMoveCursorLeft(view *views.View) {
	view.Input.MoveCursorLeft()
	termui.Render(view.Input)
}

func actionSend(ctx *context.AppContext) {
	if !ctx.View.Input.IsEmpty() {
		// FIXME
		ctx.View.Chat.List.Items = append(ctx.View.Chat.List.Items, ctx.View.Input.Text())
		ctx.View.Input.Clear()
		ctx.View.Refresh()
	}
}

func actionQuit() {
	termui.StopLoop()
}

func actionInsertMode(ctx *context.AppContext) {
	ctx.Mode = context.InsertMode
	ctx.View.Mode.Par.Text = "INSERT"
	termui.Render(ctx.View.Mode)
}

func actionCommandMode(ctx *context.AppContext) {
	ctx.Mode = context.CommandMode
	ctx.View.Mode.Par.Text = "NORMAL"
	termui.Render(ctx.View.Mode)
}

// TODO: get message for channel
func actionGetMessages(ctx *context.AppContext) {
	ctx.View.Chat.GetMessages(ctx.Service)
	termui.Render(ctx.View.Chat)
}

func actionGetChannels(ctx *context.AppContext) {
	ctx.View.Channels.GetChannels(ctx.Service)
	termui.Render(ctx.View.Channels)
}
<commit_msg>Update event incomingMessageHandler<commit_after>package handlers

import (
	"fmt"

	"github.com/gizak/termui"
	"github.com/nlopes/slack"

	"github.com/erroneousboat/slack-term/src/context"
	"github.com/erroneousboat/slack-term/src/views"
)

func RegisterEventHandlers(ctx *context.AppContext) {
	termui.Handle("/sys/kbd/", anyKeyHandler(ctx))
	termui.Handle("/sys/wnd/resize", resizeHandler(ctx))
	termui.Handle("/timer/1s", timeHandler(ctx))
	incomingMessageHandler(ctx)
}

func anyKeyHandler(ctx *context.AppContext) func(termui.Event) {
	return func(e termui.Event) {
		key := e.Data.(termui.EvtKbd).KeyStr

		if ctx.Mode == context.CommandMode {
			switch key {
			case "q":
				actionQuit()
				return
			case "i":
				actionInsertMode(ctx)
				return
			}
		} else if ctx.Mode == context.InsertMode {
			switch key {
			case "<escape>":
				actionCommandMode(ctx)
				return
			case "<enter>":
				actionSend(ctx)
				return
			case "<space>":
				actionInput(ctx.View, " ")
				return
			case "<backspace>":
				actionBackSpace(ctx.View)
			case "C-8":
				actionBackSpace(ctx.View)
			case "<right>":
				actionMoveCursorRight(ctx.View)
			case "<left>":
				actionMoveCursorLeft(ctx.View)
			default:
				actionInput(ctx.View, key)
				return
			}

		}

	}
}

func resizeHandler(ctx *context.AppContext) func(termui.Event) {
	return func(e termui.Event) {
		actionResize(ctx)
	}
}

func timeHandler(ctx *context.AppContext) func(termui.Event) {
	return func(e termui.Event) {
	}
}

func incomingMessageHandler(ctx *context.AppContext) {
	go func() {
		for {
			select {
			case msg := <-ctx.Service.RTM.IncomingEvents:
				switch ev := msg.Data.(type) {
				case *slack.MessageEvent:

					// TODO: refactor this to CreateMessage
					var name string
					user, err := ctx.Service.Client.GetUserInfo(ev.User)
					if err == nil {
						name = user.Name
					} else {
						name = "unknown"
					}
					m := fmt.Sprintf("[%s] %s", name, ev.Text)

					// Add message to the selected channel
					// fmt.Println(ev.Channel)
					if ev.Channel == ctx.View.Chat.SelectedChannel {
						ctx.View.Chat.AddMessage(m)
					}
				}
			}
		}
	}()
}

// FIXME: resize only seems to work for width and resizing it too small
// will cause termui to panic
func actionResize(ctx *context.AppContext) {
	termui.Body.Width = termui.TermWidth()
	termui.Body.Align()
	termui.Render(termui.Body)
}

func actionInput(view *views.View, key string) {
	view.Input.Insert(key)
	termui.Render(view.Input)
}

func actionBackSpace(view *views.View) {
	view.Input.Remove()
	termui.Render(view.Input)
}

func actionMoveCursorRight(view *views.View) {
	view.Input.MoveCursorRight()
	termui.Render(view.Input)
}

func actionMoveCursorLeft(view *views.View) {
	view.Input.MoveCursorLeft()
	termui.Render(view.Input)
}

func actionSend(ctx *context.AppContext) {
	if !ctx.View.Input.IsEmpty() {
		// FIXME
		ctx.View.Chat.List.Items = append(ctx.View.Chat.List.Items, ctx.View.Input.Text())
		ctx.View.Input.Clear()
		ctx.View.Refresh()
	}
}

func actionQuit() {
	termui.StopLoop()
}

func actionInsertMode(ctx *context.AppContext) {
	ctx.Mode = context.InsertMode
	ctx.View.Mode.Par.Text = "INSERT"
	termui.Render(ctx.View.Mode)
}

func actionCommandMode(ctx *context.AppContext) {
	ctx.Mode = context.CommandMode
	ctx.View.Mode.Par.Text = "NORMAL"
	termui.Render(ctx.View.Mode)
}

// TODO: get message for channel
func actionGetMessages(ctx *context.AppContext) {
	ctx.View.Chat.GetMessages(ctx.Service)
	termui.Render(ctx.View.Chat)
}

func actionGetChannels(ctx *context.AppContext) {
	ctx.View.Channels.GetChannels(ctx.Service)
	termui.Render(ctx.View.Channels)
}
<|endoftext|>


<commit_before>package hooks

import (
	"compress/gzip"
	"github.com/imosquera/uploadthis/commands"
	"github.com/imosquera/uploadthis/util"
	log "github.com/cihub/seelog"
	"io"
	"path"
	"os"
	"path/filepath"
	"crypto/rand"
	"encoding/hex"
)

//*********************
// COMPRESSOR
//*********************
type GzipFileCompressor struct{}

func (self *GzipFileCompressor) Compress(filepath string) (string, error) {
	inFile, err := util.Fs.Open(filepath)
	if err != nil {
		log.Critical("Error for file " + filepath + " " + err.Error())
	}

	//create the gzip file
	gzipPath := path.Join(path.Dir(filepath), path.Base(filepath)+".gz")
	outFile, err := util.Fs.Create(gzipPath)
	util.LogPanic(err)

	//create a new gzip writer so we can copy the bytes
	gzipWriter, err := gzip.NewWriterLevel(outFile, gzip.BestCompression)
	util.LogPanic(err)
	_, err = io.Copy(gzipWriter, inFile)
	util.LogPanic(err)

	gzipWriter.Close()
	return gzipPath, err
}

type Compressor interface {
	Compress(filepath string) (string, error)
}

func NewCompressPrehook() *CompressPrehook {
	return &CompressPrehook{
		commands.NewFileStateCommand(),
		&GzipFileCompressor{},
	}
}

type CompressPrehook struct {
	*commands.Command
	compressor Compressor
}

//this function will compress the infile and
//return a file pointer that is readible
func (c CompressPrehook) Run() ([]string, error) {
	var err error
	newFiles := make([]string, 0, len(c.UploadFiles))
	for _, uploadFile := range c.UploadFiles {
		uploadFile, _ := c.compressor.Compress(uploadFile)
		newFiles = append(newFiles, uploadFile)
	}
	return newFiles, err
}

//**************
// Renamer
//**************
type Renamer interface {
	Rename(filepath string) (string, error)
	SetProperties(...interface {})
}

type UniqueSuffixRenamer struct{
	Renamer
	suffixLength int
}

func (self *UniqueSuffixRenamer) Rename(filename string) (string, error) {
	var extension = filepath.Ext(filename)
	var name = filename[0:len(filename)-len(extension)]
	suffix, _ := self.GenerateRandomString(self.suffixLength)
	var newName = name + "-" + suffix + extension

	err := os.Rename(filename, newName)
	if err != nil {
		log.Critical("Error for file " + filename + " " + err.Error())
		util.LogPanic(err)
	}
	return newName, err
}

func (self *UniqueSuffixRenamer) GenerateRandomString(length int) (string, error) {
	uuid := make([]byte, length)
	_, err := rand.Read(uuid)
	if err != nil {
		log.Critical("Error generating random string " + err.Error())
		util.LogPanic(err)
		return "", err
	}
	return hex.EncodeToString(uuid), nil
}

type RenamePrehook struct {
	*commands.Command
	renamer Renamer
}

func NewRenamePrehook() *RenamePrehook {
	return &RenamePrehook{
		commands.NewFileStateCommand(),
		&UniqueSuffixRenamer{suffixLength: 2},
	}
}

//this function will rename the infile and
//return a new file name
func (self RenamePrehook) Run() ([]string, error) {
	var err error
	newFiles := make([]string, 0, len(self.UploadFiles))
	for _, uploadFile := range self.UploadFiles {
		newFile, the_err := self.renamer.Rename(uploadFile)
		log.Info("Rename: ", uploadFile, " -> ", newFile)
		if the_err != nil {
			err = the_err
		}
		newFiles = append(newFiles, newFile)
	}
	return newFiles, err
}
<commit_msg>Fix bug: Uploader does not delete original files after compression https://www.pivotaltracker.com/story/show/62644146<commit_after>package hooks

import (
	"compress/gzip"
	"github.com/imosquera/uploadthis/commands"
	"github.com/imosquera/uploadthis/util"
	log "github.com/cihub/seelog"
	"io"
	"path"
	"os"
	"path/filepath"
	"crypto/rand"
	"encoding/hex"
)

//*********************
// COMPRESSOR
//*********************
type GzipFileCompressor struct{}

func (self *GzipFileCompressor) Compress(filepath string) (string, error) {
	inFile, err := util.Fs.Open(filepath)
	if err != nil {
		log.Critical("Error for file " + filepath + " " + err.Error())
	}

	//create the gzip file
	gzipPath := path.Join(path.Dir(filepath), path.Base(filepath)+".gz")
	outFile, err := util.Fs.Create(gzipPath)
	util.LogPanic(err)

	//create a new gzip writer so we can copy the bytes
	gzipWriter, err := gzip.NewWriterLevel(outFile, gzip.BestCompression)
	util.LogPanic(err)
	_, err = io.Copy(gzipWriter, inFile)
	util.LogPanic(err)

	err = os.Remove(filepath)
	util.LogPanic(err)

	gzipWriter.Close()
	return gzipPath, err
}

type Compressor interface {
	Compress(filepath string) (string, error)
}

func NewCompressPrehook() *CompressPrehook {
	return &CompressPrehook{
		commands.NewFileStateCommand(),
		&GzipFileCompressor{},
	}
}

type CompressPrehook struct {
	*commands.Command
	compressor Compressor
}

//this function will compress the infile and
//return a file pointer that is readible
func (c CompressPrehook) Run() ([]string, error) {
	var err error
	newFiles := make([]string, 0, len(c.UploadFiles))
	for _, uploadFile := range c.UploadFiles {
		uploadFile, _ := c.compressor.Compress(uploadFile)
		newFiles = append(newFiles, uploadFile)
	}
	return newFiles, err
}

//**************
// Renamer
//**************
type Renamer interface {
	Rename(filepath string) (string, error)
	SetProperties(...interface {})
}

type UniqueSuffixRenamer struct{
	Renamer
	suffixLength int
}

func (self *UniqueSuffixRenamer) Rename(filename string) (string, error) {
	var extension = filepath.Ext(filename)
	var name = filename[0:len(filename)-len(extension)]
	suffix, _ := self.GenerateRandomString(self.suffixLength)
	var newName = name + "-" + suffix + extension

	err := os.Rename(filename, newName)
	if err != nil {
		log.Critical("Error for file " + filename + " " + err.Error())
		util.LogPanic(err)
	}
	return newName, err
}

func (self *UniqueSuffixRenamer) GenerateRandomString(length int) (string, error) {
	uuid := make([]byte, length)
	_, err := rand.Read(uuid)
	if err != nil {
		log.Critical("Error generating random string " + err.Error())
		util.LogPanic(err)
		return "", err
	}
	return hex.EncodeToString(uuid), nil
}

type RenamePrehook struct {
	*commands.Command
	renamer Renamer
}

func NewRenamePrehook() *RenamePrehook {
	return &RenamePrehook{
		commands.NewFileStateCommand(),
		&UniqueSuffixRenamer{suffixLength: 2},
	}
}

//this function will rename the infile and
//return a new file name
func (self RenamePrehook) Run() ([]string, error) {
	var err error
	newFiles := make([]string, 0, len(self.UploadFiles))
	for _, uploadFile := range self.UploadFiles {
		newFile, the_err := self.renamer.Rename(uploadFile)
		log.Info("Rename: ", uploadFile, " -> ", newFile)
		if the_err != nil {
			err = the_err
		}
		newFiles = append(newFiles, newFile)
	}
	return newFiles, err
}
<|endoftext|>


<commit_before>/**
 *  Copyright 2014 Paul Querna
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package hotp

import (
	"github.com/pquerna/otp"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"encoding/base32"
	"testing"
)

type tc struct {
	Counter uint64
	TOTP    string
	Mode    otp.Algorithm
	Secret  string
}

var (
	secSha1 = base32.StdEncoding.EncodeToString([]byte("12345678901234567890"))

	rfcMatrixTCs = []tc{
		tc{0, "755224", otp.AlgorithmSHA1, secSha1},
		tc{1, "287082", otp.AlgorithmSHA1, secSha1},
		tc{2, "359152", otp.AlgorithmSHA1, secSha1},
		tc{3, "969429", otp.AlgorithmSHA1, secSha1},
		tc{4, "338314", otp.AlgorithmSHA1, secSha1},
		tc{5, "254676", otp.AlgorithmSHA1, secSha1},
		tc{6, "287922", otp.AlgorithmSHA1, secSha1},
		tc{7, "162583", otp.AlgorithmSHA1, secSha1},
		tc{8, "399871", otp.AlgorithmSHA1, secSha1},
		tc{9, "520489", otp.AlgorithmSHA1, secSha1},
	}
)

// Test values from http://tools.ietf.org/html/rfc4226#appendix-D
func TestValidateRFCMatrix(t *testing.T) {

	for _, tx := range rfcMatrixTCs {
		valid, err := ValidateCustom(tx.TOTP, tx.Counter, tx.Secret,
			ValidateOpts{
				Digits:    otp.DigitsSix,
				Algorithm: tx.Mode,
			})
		require.NoError(t, err,
			"unexpected error totp=%s mode=%v counter=%v", tx.TOTP, tx.Mode, tx.Counter)
		require.True(t, valid,
			"unexpected totp failure totp=%s mode=%v counter=%v", tx.TOTP, tx.Mode, tx.Counter)
	}
}

func TestGenerateRFCMatrix(t *testing.T) {
	for _, tx := range rfcMatrixTCs {
		passcode, err := GenerateCodeCustom(tx.Secret, tx.Counter,
			ValidateOpts{
				Digits:    otp.DigitsSix,
				Algorithm: tx.Mode,
			})
		assert.Nil(t, err)
		assert.Equal(t, tx.TOTP, passcode)
	}
}

func TestValidateInvalid(t *testing.T) {
	secSha1 := base32.StdEncoding.EncodeToString([]byte("12345678901234567890"))

	valid, err := ValidateCustom("foo", 11, secSha1,
		ValidateOpts{
			Digits:    otp.DigitsSix,
			Algorithm: otp.AlgorithmSHA1,
		})
	require.Equal(t, otp.ErrValidateInputInvalidLength, err, "Expected Invalid length error.")
	require.Equal(t, false, valid, "Valid should be false when we have an error.")

	valid, err = ValidateCustom("foo", 11, secSha1,
		ValidateOpts{
			Digits:    otp.DigitsEight,
			Algorithm: otp.AlgorithmSHA1,
		})
	require.Equal(t, otp.ErrValidateInputInvalidLength, err, "Expected Invalid length error.")
	require.Equal(t, false, valid, "Valid should be false when we have an error.")

	valid, err = ValidateCustom("000000", 11, secSha1,
		ValidateOpts{
			Digits:    otp.DigitsSix,
			Algorithm: otp.AlgorithmSHA1,
		})
	require.NoError(t, err, "Expected no error.")
	require.Equal(t, false, valid, "Valid should be false.")

	valid = Validate("000000", 11, secSha1)
	require.Equal(t, false, valid, "Valid should be false.")
}

func TestGenerate(t *testing.T) {
	k, err := Generate(GenerateOpts{
		Issuer:      "SnakeOil",
		AccountName: "alice@example.com",
	})
	require.NoError(t, err, "generate basic TOTP")
	require.Equal(t, "SnakeOil", k.Issuer(), "Extracting Issuer")
	require.Equal(t, "alice@example.com", k.AccountName(), "Extracting Account Name")
	require.Equal(t, 16, len(k.Secret()), "Secret is 16 bytes long as base32.")

	k, err = Generate(GenerateOpts{
		Issuer:      "SnakeOil",
		AccountName: "alice@example.com",
		SecretSize:  20,
	})
	require.NoError(t, err, "generate larger TOTP")
	require.Equal(t, 32, len(k.Secret()), "Secret is 32 bytes long as base32.")

	k, err = Generate(GenerateOpts{
		Issuer:      "",
		AccountName: "alice@example.com",
	})
	require.Equal(t, otp.ErrGenerateMissingIssuer, err, "generate missing issuer")
	require.Nil(t, k, "key should be nil on error.")

	k, err = Generate(GenerateOpts{
		Issuer:      "Foobar, Inc",
		AccountName: "",
	})
	require.Equal(t, otp.ErrGenerateMissingAccountName, err, "generate missing account name.")
	require.Nil(t, k, "key should be nil on error.")
}
<commit_msg>#10 added spec to test secret without padding<commit_after>/**
 *  Copyright 2014 Paul Querna
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package hotp

import (
	"github.com/pquerna/otp"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"encoding/base32"
	"testing"
)

type tc struct {
	Counter uint64
	TOTP    string
	Mode    otp.Algorithm
	Secret  string
}

var (
	secSha1 = base32.StdEncoding.EncodeToString([]byte("12345678901234567890"))

	rfcMatrixTCs = []tc{
		tc{0, "755224", otp.AlgorithmSHA1, secSha1},
		tc{1, "287082", otp.AlgorithmSHA1, secSha1},
		tc{2, "359152", otp.AlgorithmSHA1, secSha1},
		tc{3, "969429", otp.AlgorithmSHA1, secSha1},
		tc{4, "338314", otp.AlgorithmSHA1, secSha1},
		tc{5, "254676", otp.AlgorithmSHA1, secSha1},
		tc{6, "287922", otp.AlgorithmSHA1, secSha1},
		tc{7, "162583", otp.AlgorithmSHA1, secSha1},
		tc{8, "399871", otp.AlgorithmSHA1, secSha1},
		tc{9, "520489", otp.AlgorithmSHA1, secSha1},
	}
)

// Test values from http://tools.ietf.org/html/rfc4226#appendix-D
func TestValidateRFCMatrix(t *testing.T) {

	for _, tx := range rfcMatrixTCs {
		valid, err := ValidateCustom(tx.TOTP, tx.Counter, tx.Secret,
			ValidateOpts{
				Digits:    otp.DigitsSix,
				Algorithm: tx.Mode,
			})
		require.NoError(t, err,
			"unexpected error totp=%s mode=%v counter=%v", tx.TOTP, tx.Mode, tx.Counter)
		require.True(t, valid,
			"unexpected totp failure totp=%s mode=%v counter=%v", tx.TOTP, tx.Mode, tx.Counter)
	}
}

func TestGenerateRFCMatrix(t *testing.T) {
	for _, tx := range rfcMatrixTCs {
		passcode, err := GenerateCodeCustom(tx.Secret, tx.Counter,
			ValidateOpts{
				Digits:    otp.DigitsSix,
				Algorithm: tx.Mode,
			})
		assert.Nil(t, err)
		assert.Equal(t, tx.TOTP, passcode)
	}
}

func TestValidateInvalid(t *testing.T) {
	secSha1 := base32.StdEncoding.EncodeToString([]byte("12345678901234567890"))

	valid, err := ValidateCustom("foo", 11, secSha1,
		ValidateOpts{
			Digits:    otp.DigitsSix,
			Algorithm: otp.AlgorithmSHA1,
		})
	require.Equal(t, otp.ErrValidateInputInvalidLength, err, "Expected Invalid length error.")
	require.Equal(t, false, valid, "Valid should be false when we have an error.")

	valid, err = ValidateCustom("foo", 11, secSha1,
		ValidateOpts{
			Digits:    otp.DigitsEight,
			Algorithm: otp.AlgorithmSHA1,
		})
	require.Equal(t, otp.ErrValidateInputInvalidLength, err, "Expected Invalid length error.")
	require.Equal(t, false, valid, "Valid should be false when we have an error.")

	valid, err = ValidateCustom("000000", 11, secSha1,
		ValidateOpts{
			Digits:    otp.DigitsSix,
			Algorithm: otp.AlgorithmSHA1,
		})
	require.NoError(t, err, "Expected no error.")
	require.Equal(t, false, valid, "Valid should be false.")

	valid = Validate("000000", 11, secSha1)
	require.Equal(t, false, valid, "Valid should be false.")
}

// This tests for issue #10 - secrets without padding
func TestValidatePadding(t *testing.T) {
	valid, err := ValidateCustom("831097", 0, "JBSWY3DPEHPK3PX",
		ValidateOpts{
			Digits:    otp.DigitsSix,
			Algorithm: otp.AlgorithmSHA1,
		})
	require.NoError(t, err, "Expected no error.")
	require.Equal(t, true, valid, "Valid should be true.")
}

func TestGenerate(t *testing.T) {
	k, err := Generate(GenerateOpts{
		Issuer:      "SnakeOil",
		AccountName: "alice@example.com",
	})
	require.NoError(t, err, "generate basic TOTP")
	require.Equal(t, "SnakeOil", k.Issuer(), "Extracting Issuer")
	require.Equal(t, "alice@example.com", k.AccountName(), "Extracting Account Name")
	require.Equal(t, 16, len(k.Secret()), "Secret is 16 bytes long as base32.")

	k, err = Generate(GenerateOpts{
		Issuer:      "SnakeOil",
		AccountName: "alice@example.com",
		SecretSize:  20,
	})
	require.NoError(t, err, "generate larger TOTP")
	require.Equal(t, 32, len(k.Secret()), "Secret is 32 bytes long as base32.")

	k, err = Generate(GenerateOpts{
		Issuer:      "",
		AccountName: "alice@example.com",
	})
	require.Equal(t, otp.ErrGenerateMissingIssuer, err, "generate missing issuer")
	require.Nil(t, k, "key should be nil on error.")

	k, err = Generate(GenerateOpts{
		Issuer:      "Foobar, Inc",
		AccountName: "",
	})
	require.Equal(t, otp.ErrGenerateMissingAccountName, err, "generate missing account name.")
	require.Nil(t, k, "key should be nil on error.")
}
<|endoftext|>


<commit_before>package endpoint

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"sync"
	"time"
)

const (
	httpExpiresAfter       = time.Second * 30
	httpRequestTimeout     = time.Second * 5
	httpMaxIdleConnections = 20
)

type HTTPEndpointConn struct {
	mu     sync.Mutex
	ep     Endpoint
	ex     bool
	t      time.Time
	client *http.Client
}

func newHTTPEndpointConn(ep Endpoint) *HTTPEndpointConn {
	return &HTTPEndpointConn{
		ep: ep,
		t:  time.Now(),
	}
}

func (conn *HTTPEndpointConn) Expired() bool {
	conn.mu.Lock()
	defer conn.mu.Unlock()
	if !conn.ex {
		if time.Now().Sub(conn.t) > httpExpiresAfter {
			conn.ex = true
			conn.client = nil
		}
	}
	return conn.ex
}

func (conn *HTTPEndpointConn) Send(msg string) error {
	conn.mu.Lock()
	defer conn.mu.Unlock()
	if conn.ex {
		return errExpired
	}
	conn.t = time.Now()
	if conn.client == nil {
		conn.client = &http.Client{
			Transport: &http.Transport{
				MaxIdleConnsPerHost: httpMaxIdleConnections,
			},
			Timeout: httpRequestTimeout,
		}
	}
	req, err := http.NewRequest("POST", conn.ep.Original, bytes.NewBufferString(msg))
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json")
	resp, err := conn.client.Do(req)
	if err != nil {
		return err
	}
	// close the connection to reuse it
	defer resp.Body.Close()
	// discard response
	if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
		return err
	}
	// we only care about the 200 response
	if resp.StatusCode != 200 {
		return fmt.Errorf("invalid status: %s", resp.Status)
	}
	return nil
}
<commit_msg>Fix leaking http connections (#147)<commit_after>package endpoint

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"sync"
	"time"
)

const (
	httpExpiresAfter       = time.Second * 30
	httpRequestTimeout     = time.Second * 5
	httpMaxIdleConnections = 20
)

type HTTPEndpointConn struct {
	mu     sync.Mutex
	ep     Endpoint
	client *http.Client
}

func newHTTPEndpointConn(ep Endpoint) *HTTPEndpointConn {
	return &HTTPEndpointConn{
		ep: ep,
	}
}

func (conn *HTTPEndpointConn) Expired() bool {
	return false
}

func (conn *HTTPEndpointConn) Send(msg string) error {
	conn.mu.Lock()
	defer conn.mu.Unlock()

	if conn.client == nil {
		conn.client = &http.Client{
			Transport: &http.Transport{
				MaxIdleConnsPerHost: httpMaxIdleConnections,
				IdleConnTimeout:     httpExpiresAfter,
			},
			Timeout: httpRequestTimeout,
		}
	}
	req, err := http.NewRequest("POST", conn.ep.Original, bytes.NewBufferString(msg))
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json")
	resp, err := conn.client.Do(req)
	if err != nil {
		return err
	}
	// close the connection to reuse it
	defer resp.Body.Close()
	// discard response
	if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
		return err
	}
	// we only care about the 200 response
	if resp.StatusCode != 200 {
		return fmt.Errorf("invalid status: %s", resp.Status)
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/mehrdadrad/myping/cli"
	"github.com/mehrdadrad/myping/icmp"
	"github.com/mehrdadrad/myping/icmp/telia"
	"net"
	"regexp"
	"strings"
)

type Provider interface {
	Init(host, version string)
	GetDefaultNode() string
	GetNodes() map[string]string
	Ping() (string, error)
}

var providers = map[string]Provider{"telia": new(telia.Provider)}

func validateProvider(p string) (string, error) {
	p = strings.ToLower(p)
	return p, nil
}

func main() {
	var (
		err    error
		cPName string = "local"
	)

	rep := make(chan string, 1)
	cmd := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(cmd, nxt)

	r, _ := regexp.Compile("(ping|connect) (.*)")

	for {
		select {
		case req := <-cmd:
			subReq := r.FindStringSubmatch(req)
			if len(subReq) == 0 {
				println("syntax error")
				nxt <- struct{}{}
				continue
			}
			switch {
			case subReq[1] == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", subReq[2])
				if err != nil {
					println("cannot resolve", subReq[2], ": Unknown host")
					nxt <- struct{}{}
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				nxt <- struct{}{}
			case subReq[1] == "ping" && cPName == "telia":
				providers[cPName].Init(subReq[2], "ipv4")
				m, _ := providers[cPName].Ping()
				println(m)
				nxt <- struct{}{}
			case subReq[1] == "connect":
				var pName string
				if pName, err = validateProvider(subReq[2]); err != nil {
					println("provider not available")
					nxt <- struct{}{}
					continue
				}
				cPName = pName
				c.SetPrompt(cPName + "/" + providers[cPName].GetDefaultNode())
				nxt <- struct{}{}
			}
		}
	}
}
<commit_msg>fixed case extrnal ping logic<commit_after>package main

import (
	"github.com/mehrdadrad/myping/cli"
	"github.com/mehrdadrad/myping/icmp"
	"github.com/mehrdadrad/myping/icmp/telia"
	"net"
	"regexp"
	"strings"
)

type Provider interface {
	Init(host, version string)
	GetDefaultNode() string
	GetNodes() map[string]string
	Ping() (string, error)
}

var providers = map[string]Provider{"telia": new(telia.Provider)}

func validateProvider(p string) (string, error) {
	p = strings.ToLower(p)
	return p, nil
}

func main() {
	var (
		err    error
		cPName string = "local"
	)

	rep := make(chan string, 1)
	cmd := make(chan string, 1)
	nxt := make(chan struct{}, 1)

	c := cli.Init("local")
	go c.Run(cmd, nxt)

	r, _ := regexp.Compile("(ping|connect) (.*)")

	for {
		select {
		case req := <-cmd:
			subReq := r.FindStringSubmatch(req)
			if len(subReq) == 0 {
				println("syntax error")
				nxt <- struct{}{}
				continue
			}
			switch {
			case subReq[1] == "ping" && cPName == "local":
				p := icmp.NewPing()
				ra, err := net.ResolveIPAddr("ip", subReq[2])
				if err != nil {
					println("cannot resolve", subReq[2], ": Unknown host")
					nxt <- struct{}{}
					continue
				}
				p.IP(ra.String())
				for n := 0; n < 4; n++ {
					p.Ping(rep)
					println(<-rep)
				}
				nxt <- struct{}{}
			case subReq[1] == "ping":
				providers[cPName].Init(subReq[2], "ipv4")
				m, _ := providers[cPName].Ping()
				println(m)
				nxt <- struct{}{}
			case subReq[1] == "connect":
				var pName string
				if pName, err = validateProvider(subReq[2]); err != nil {
					println("provider not available")
					nxt <- struct{}{}
					continue
				}
				cPName = pName
				c.SetPrompt(cPName + "/" + providers[cPName].GetDefaultNode())
				nxt <- struct{}{}
			}
		}
	}
}
<|endoftext|>


<commit_before>// TODO: libraries should not use log.Fatal
// TODO: ... perhaps not log.Printf either.

package doozerconfig

import (
	"reflect"
	"github.com/ActiveState/doozer"
	"encoding/json"
	"errors" // TODO: create custom errors
	"log"
)

type DoozerConfig struct {
	conn        *doozer.Conn
	configStruct interface{}
	prefix       string
	fields       map[string]reflect.Value
}

func New(conn *doozer.Conn, configStruct interface{}, prefix string) *DoozerConfig{
	return &DoozerConfig{conn, configStruct, prefix, make(map[string]reflect.Value)}
}

// initialize the config data by loading from doozer.
// will return error if any of the config is not found
func (c *DoozerConfig) Load() error {
	elem := reflect.ValueOf(c.configStruct).Elem()
	elemType := elem.Type()
	for i := 0; i < elem.NumField(); i++ {
		field := elem.Field(i)
		fieldType := elemType.Field(i)

		// read json-encoded bytes from doozer
		path := fieldType.Tag.Get("doozer")
		if path == "" {
			// this field is not supposed to be loaded from doozer
			continue
		}
		path = c.prefix + path
		data, _, err := c.conn.Get(path, nil)
		if err != nil {
			return err
		}

		c.fields[path] = field

		// extract the value based on the field type
		err = setFieldWithData(field, data)
		if err != nil {
			return err
		}
	}
	return nil
}

func (c *DoozerConfig) Monitor(glob string, rev int64) {
	for evt := range doozerWatch(c.conn, glob, rev) {
		if field, ok := c.fields[evt.Path]; ok {
			err := setFieldWithData(field, evt.Body)
			if err != nil {
				log.Fatal(err)
			}
			log.Printf("New Config: %+v\n", c.configStruct)
		}
	}
}

// set this struct field with data json-decoded as the same tyhpe
func setFieldWithData(field reflect.Value, data []byte) error {
	// TODO: simplify this using interface{}
	switch(field.Kind()){
	case reflect.Int:
		var val int64
		json.Unmarshal(data, &val)
		field.SetInt(val)
	case reflect.String:
		var val string
		json.Unmarshal(data, &val)
		field.SetString(val)
	default:
		return errors.New("doozerconfig: unsupported field " + string(field.Kind()))
	}
	return nil
}

// monitor mutations on the given glob of keys and report them in the
// returned channel
func doozerWatch(c *doozer.Conn, glob string, rev int64) chan doozer.Event {
	ch := make(chan doozer.Event)
	go func() {
		for {
			evt, err := c.Wait(glob, rev)
			if err != nil {
				close(ch)
				// FIXME: on doozer watch errors, the entire basin process
				// must not go down. figure a way to report the error in
				// console and silently proceed.
				log.Fatal(err)
				return
			}
			rev = evt.Rev + 1
			ch <- evt
		}
	}()
	return ch
}

<commit_msg>doozerconfig: simplify setFieldWithData using reflection<commit_after>// TODO: libraries should not use log.Fatal
// TODO: ... perhaps not log.Printf either.

package doozerconfig

import (
	"reflect"
	"github.com/ActiveState/doozer"
	"encoding/json"
	"log"
)

type DoozerConfig struct {
	conn        *doozer.Conn
	configStruct interface{}
	prefix       string
	fields       map[string]reflect.Value
}

func New(conn *doozer.Conn, configStruct interface{}, prefix string) *DoozerConfig{
	return &DoozerConfig{conn, configStruct, prefix, make(map[string]reflect.Value)}
}

// initialize the config data by loading from doozer.
// will return error if any of the config is not found
func (c *DoozerConfig) Load() error {
	elem := reflect.ValueOf(c.configStruct).Elem()
	elemType := elem.Type()
	for i := 0; i < elem.NumField(); i++ {
		field := elem.Field(i)
		fieldType := elemType.Field(i)

		// read json-encoded bytes from doozer
		path := fieldType.Tag.Get("doozer")
		if path == "" {
			// this field is not supposed to be loaded from doozer
			continue
		}
		path = c.prefix + path
		data, _, err := c.conn.Get(path, nil)
		if err != nil {
			return err
		}

		c.fields[path] = field

		// extract the value based on the field type
		err = unmarshalIntoValue(data, field)
		if err != nil {
			return err
		}
	}
	return nil
}

func (c *DoozerConfig) Monitor(glob string, rev int64) error {
	for evt := range doozerWatch(c.conn, glob, rev) {
		if field, ok := c.fields[evt.Path]; ok {
			err := unmarshalIntoValue(evt.Body, field)
			if err != nil {
				return err
			}
			log.Printf("New Config: %+v\n", c.configStruct)
		}
	}
	return nil
}

// a version of json.Unmarshal that unmarshalls into a reflect.Value type
func unmarshalIntoValue(data []byte, field reflect.Value) error {
	fieldInterface := field.Addr().Interface()
	return json.Unmarshal(data, &fieldInterface)
}

// monitor mutations on the given glob of keys and report them in the
// returned channel
func doozerWatch(c *doozer.Conn, glob string, rev int64) chan doozer.Event {
	ch := make(chan doozer.Event)
	go func() {
		for {
			evt, err := c.Wait(glob, rev)
			if err != nil {
				close(ch)
				// FIXME: on doozer watch errors, the entire basin process
				// must not go down. figure a way to report the error in
				// console and silently proceed.
				// besides, it is not the library's job to crash a program.
				log.Fatal(err)
				return
			}
			rev = evt.Rev + 1
			ch <- evt
		}
	}()
	return ch
}

<|endoftext|>


<commit_before>package http

import (
	"net/http"
	"golib/utils"
	"strings"
	"fmt"
)

var (

)

type Handler interface {
	handler(url string) bool
}

type handleFuncMap struct {
	simple map[string]restHandlerFunc
	rest *restHandlerMap
}

func (this handleFuncMap) getHandler(req *http.Request) (http.HandlerFunc,error)  {
	var err error
	url := req.URL.Path
	method := req.Method
	rest,ok:=this.simple[url]
	if ok {
		if rest.matchMethod(method) {
			return rest.function,nil
		}else {
			err = fmt.Errorf("url:%s;method not match:methodStr is %s but %s",url,rest.methodStr,method)
		}
	}
	restHandler,urlValues := this.rest.getHandler(url)
	if restHandler != nil {
		if restHandler.matchMethod(method){
			for k,v:=range urlValues{
				req.Form.Add(k,v)
			}
			return restHandler.function,nil
		}
	}
	err = fmt.Errorf("url:%s;not found macth url",url)
	return nil,err
}

type restHandlerFunc struct {
	methodStr string
	function http.HandlerFunc
}

func (this restHandlerFunc) matchMethod(method string) bool{
	if this.methodStr == "" || this.methodStr == "*" {
		return true
	}
	return strings.Index(this.methodStr, method) >= 0
}

type restHandlerMap struct {
	urls map[int][]urlInfo
}

func (this restHandlerMap) getHandler(url string) (restHandlerFunc,map[string]string) {
	urlParaLen := len(utils.Split(url,"/"))
	urlInfos,ok := this.urls[urlParaLen]
	if ok {
		for _,v := range urlInfos {
			handler,urlPara,err := v.match(url)
			if err != nil{
				continue
			}else{
				return handler,urlPara
			}
		}
	}
	return nil,nil
}

func (this Handler) ServeHTTP(res http.ResponseWriter, req *http.Request)  {
	url := req.URL.Path
	urlParas := utils.Split(url , "/")
	urlLenGroup := urls[len(urlParas)]

}

type urlMacthPara struct {
	urlPara string
	matchInfo string
}

func (this urlMacthPara) macth(para string) (bool,string) {
	switch this.matchInfo {
	case "*":
		return true,"*"
	case "{}":
		return true,para
	case "":
		return this.urlPara == para , ""
	default:
		return this.urlPara == para , ""
	}
}

type urlInfo struct {
	urlParas []urlMacthPara
	handler restHandlerFunc
}

func (this urlInfo) addUrlPara(para string)  {
	this.urls = append(this.urls , para)
}

func (this urlInfo) addUrlMatchPara(para string)  {
	matchIndex := len(this.urls)
	this.matchIndex = append(this.matchIndex , matchIndex)
	this.urls = append(this.urls , para)
}

func (this urlInfo) len() int  {
	return len(this.urls)
}

func (this urlInfo) match(url string) (http.HandlerFunc,map[string]string,error) {
	var urlParavalueMap map[string]string
	urlParas := utils.Split(url,"/")
	for i , _ := range urlParas {
		should := this.urlParas[i]
		real := urlParas[i]
		if macth,res:=should.macth(real);macth{
			switch res {
			case "*":
				urlParavalueMap["*"]=strings.Join(urlParas[i:],"/")
				return this.handler,urlParavalueMap,nil
			case "{}":
				urlParavalueMap[should.urlPara] = real
			default :

			}
		}else {
			return nil,nil,fmt.Errorf("not macth")
		}
	}
	return this.handler,urlParavalueMap,nil
}

func AddHandlerFunc(url string, handler http.HandlerFunc){
	paras := utils.Split(url,"/")
	for _,v := range paras{
		urlinfo := urlInfo{}
		para := strings.TrimSpace(v)
		if para[0] == '{' && para[len(para) - 1] == '}' {
			urlinfo.addUrlMatchPara(para[1:len(para)])
		}else if para == '*' {
			urlinfo.addUrlMatchPara(para)
		}else {
			urlinfo.addUrlPara(para)
			simpleUrls[url] = handler
			return
		}
		urlinfo.handler = handler
		len := urlinfo.len()
		urls[len] = append(urls[len],urlinfo)
	}
}<commit_msg>添加实现思路,还未完成<commit_after>package http

/*
现实思路:
    分为三种类型url
	1.普通的:如/fff/ddd/lll
	2.有映射值的:如/user/{who}/info
	3.尾部全部匹配的:如/user/*('*'只可以用于尾部)
    先进行分组,将普通的于要进行取值的分开
    普通的对于一个map,直接使用map[string]获取handlerFunc
    要取值得将url利用"/"切分成数组,匹配是再将实际url切分成数组进行比对并取值

 */

import (
	"net/http"
	"golib/utils"
	"strings"
	"fmt"
)

var (
	handler handleFuncMap
)

type Handler interface {
	handler(url string) bool
}

type handleFuncMap struct {
	simple map[string]restHandlerFunc
	rest *restHandlerMap
}

func (this handleFuncMap) getHandler(req *http.Request) (http.HandlerFunc,error)  {
	var err error
	url := req.URL.Path
	method := req.Method
	rest,ok:=this.simple[url]
	if ok {
		if rest.matchMethod(method) {
			return rest.function,nil
		}else {
			err = fmt.Errorf("url:%s;method not match:methodStr is %s but %s",url,rest.methodStr,method)
		}
	}
	restHandler,urlValues := this.rest.getHandler(url)
	if restHandler != nil {
		if restHandler.matchMethod(method){
			for k,v:=range urlValues{
				req.Form.Add(k,v)
			}
			return restHandler.function,nil
		}
	}
	err = fmt.Errorf("url:%s;not found macth url",url)
	return nil,err
}

type restHandlerFunc struct {
	methodStr string
	function http.HandlerFunc
}

func (this restHandlerFunc) matchMethod(method string) bool{
	if this.methodStr == "" || this.methodStr == "*" {
		return true
	}
	return strings.Index(this.methodStr, method) >= 0
}

type restHandlerMap struct {
	urls map[int][]urlInfo
}

func (this restHandlerMap) getHandler(url string) (restHandlerFunc,map[string]string) {
	urlParaLen := len(utils.Split(url,"/"))
	urlInfos,ok := this.urls[urlParaLen]
	if ok {
		for _,v := range urlInfos {
			handler,urlPara,err := v.match(url)
			if err != nil{
				continue
			}else{
				return handler,urlPara
			}
		}
	}
	return nil,nil
}

func (this Handler) ServeHTTP(res http.ResponseWriter, req *http.Request)  {
	url := req.URL.Path
	urlParas := utils.Split(url , "/")
	urlLenGroup := urls[len(urlParas)]

}

type urlMacthPara struct {
	urlPara string
	matchInfo string
}

func (this urlMacthPara) macth(para string) (bool,string) {
	switch this.matchInfo {
	case "*":
		return true,"*"
	case "{}":
		return true,para
	case "":
		return this.urlPara == para , ""
	default:
		return this.urlPara == para , ""
	}
}

type urlInfo struct {
	urlParas []urlMacthPara
	handler restHandlerFunc
}

func (this urlInfo) addUrlPara(para string)  {
	this.urls = append(this.urls , para)
}

func (this urlInfo) addUrlMatchPara(para string)  {
	matchIndex := len(this.urls)
	this.matchIndex = append(this.matchIndex , matchIndex)
	this.urls = append(this.urls , para)
}

func (this urlInfo) len() int  {
	return len(this.urls)
}

func (this urlInfo) match(url string) (http.HandlerFunc,map[string]string,error) {
	var urlParavalueMap map[string]string
	urlParas := utils.Split(url,"/")
	for i , _ := range urlParas {
		should := this.urlParas[i]
		real := urlParas[i]
		if macth,res:=should.macth(real);macth{
			switch res {
			case "*":
				urlParavalueMap["*"]=strings.Join(urlParas[i:],"/")
				return this.handler,urlParavalueMap,nil
			case "{}":
				urlParavalueMap[should.urlPara] = real
			default :

			}
		}else {
			return nil,nil,fmt.Errorf("not macth")
		}
	}
	return this.handler,urlParavalueMap,nil
}

func AddHandlerFunc(url string, handler http.HandlerFunc){
	paras := utils.Split(url,"/")
	for _,v := range paras{
		urlinfo := urlInfo{}
		para := strings.TrimSpace(v)
		if para[0] == '{' && para[len(para) - 1] == '}' {
			urlinfo.addUrlMatchPara(para[1:len(para)])
		}else if para == '*' {
			urlinfo.addUrlMatchPara(para)
		}else {
			urlinfo.addUrlPara(para)
			simpleUrls[url] = handler
			return
		}
		urlinfo.handler = handler
		len := urlinfo.len()
		urls[len] = append(urls[len],urlinfo)
	}
}<|endoftext|>


<commit_before>package sudokustate

import (
	"encoding/json"
	"github.com/jkomoros/sudoku"
)

type digest struct {
	Puzzle string
	Moves  []digestMove
}

type digestMove struct {
	Type   string
	Cell   sudoku.CellRef
	Marks  map[int]bool
	Time   int
	Number *int
	Group  groupInfo
}

//TODO: implement model.LoadDigest([]byte)

//Digest returns a []byte with the JSON that represents this model.
func (m *Model) Digest() []byte {
	obj := m.makeDigest()

	result, err := json.MarshalIndent(obj, "", "  ")
	if err != nil {
		return nil
	}
	return result
}

func (m *Model) makeDigest() digest {
	//TODO: test this
	return digest{
		Puzzle: m.snapshot,
		Moves:  m.makeMovesDigest(),
	}
}

func (m *Model) makeMovesDigest() []digestMove {
	var result []digestMove

	//Move command cursor to the very first item in the linked list.
	currentCommand := m.commands
	if currentCommand == nil {
		return nil
	}
	for currentCommand.prev != nil {
		currentCommand = currentCommand.prev
	}

	for currentCommand != nil {

		command := currentCommand.c

		groupInfoPtr := command.GroupInfo()

		var info groupInfo

		if groupInfoPtr == nil {
			info = groupInfo{}
		} else {
			info = *groupInfoPtr
		}

		for _, subCommand := range command.SubCommands() {
			result = append(result, digestMove{
				Type: subCommand.Type(),
				//TODO: this is a hack, we just happen to know that there's only one item
				Cell:   subCommand.ModifiedCells(m)[0],
				Group:  info,
				Marks:  subCommand.Marks(),
				Number: subCommand.Number(),
			})
		}

		currentCommand = currentCommand.next
	}

	return result
}
<commit_msg>Made it so group info is null if not in a group<commit_after>package sudokustate

import (
	"encoding/json"
	"github.com/jkomoros/sudoku"
)

type digest struct {
	Puzzle string
	Moves  []digestMove
}

type digestMove struct {
	Type   string
	Cell   sudoku.CellRef
	Marks  map[int]bool
	Time   int
	Number *int
	Group  *groupInfo
}

//TODO: implement model.LoadDigest([]byte)

//Digest returns a []byte with the JSON that represents this model.
func (m *Model) Digest() []byte {
	obj := m.makeDigest()

	result, err := json.MarshalIndent(obj, "", "  ")
	if err != nil {
		return nil
	}
	return result
}

func (m *Model) makeDigest() digest {
	//TODO: test this
	return digest{
		Puzzle: m.snapshot,
		Moves:  m.makeMovesDigest(),
	}
}

func (m *Model) makeMovesDigest() []digestMove {
	var result []digestMove

	//Move command cursor to the very first item in the linked list.
	currentCommand := m.commands
	if currentCommand == nil {
		return nil
	}
	for currentCommand.prev != nil {
		currentCommand = currentCommand.prev
	}

	for currentCommand != nil {

		command := currentCommand.c

		for _, subCommand := range command.SubCommands() {
			result = append(result, digestMove{
				Type: subCommand.Type(),
				//TODO: this is a hack, we just happen to know that there's only one item
				Cell:   subCommand.ModifiedCells(m)[0],
				Group:  command.GroupInfo(),
				Marks:  subCommand.Marks(),
				Number: subCommand.Number(),
			})
		}

		currentCommand = currentCommand.next
	}

	return result
}
<|endoftext|>


<commit_before>package randombytes

// #cgo pkg-config: libsodium
// #include <stdlib.h>
// #include <sodium.h>
import "C"
import "github.com/GoKillers/libsodium-go/support"
import "unsafe"

func RandomBytesSeedBytes() int {
	return int(C.randombytes_seedbytes())
}

func RandomBytes(size int) []byte {
	buf := make([]byte, size)
	RandomBytesBuf(buf)
	return buf
}

func RandomBytesBuf(buf []byte) {
	if len(buf) > 0 {
		C.randombytes_buf(unsafe.Pointer(&buf[0]), C.size_t(len(buf)))
	}
}

func RandomBytesBufDeterministic(buf []byte, seed []byte) {
	support.CheckSize(seed, RandomBytesSeedBytes(), "seed")
	if len(buf) > 0 {
		C.randombytes_buf_deterministic(
			unsafe.Pointer(&buf[0]),
			C.size_t(len(buf)),
			(*C.uchar)(&seed[0]))
	}
}

func RandomBytesRandom() uint32 {
	return uint32(C.randombytes_random())
}

func RandomBytesUniform(upperBound uint32) uint32 {
	return uint32(C.randombytes_uniform(C.uint32_t(upperBound)))
}

func RandomBytesStir() {
	C.randombytes_stir()
}

func RandomBytesClose() {
	C.randombytes_close()
}

func RandomBytesSetImplementation(impl *C.struct_randombytes_implementation) int {
	return int(C.randombytes_set_implementation(impl))
}

func RandomBytesImplementationName() string {
	return C.GoString(C.randombytes_implementation_name())
}

// From randombytes_salsa20_random.h
var RandomBytesSalsa20Implementation *C.struct_randombytes_implementation = &C.randombytes_salsa20_implementation

// From randombytes_sysrandom.h
var RandomBytesSysRandomImplementation *C.struct_randombytes_implementation = &C.randombytes_sysrandom_implementation
<commit_msg>Add comments to randombytes<commit_after>package randombytes

// #cgo pkg-config: libsodium
// #include <stdlib.h>
// #include <sodium.h>
import "C"
import "github.com/GoKillers/libsodium-go/support"
import "unsafe"

// RandomBytesSeedBytes returns the number of bytes required
// for seeding RandomBytesBufDeterministic.
func RandomBytesSeedBytes() int {
	return int(C.randombytes_seedbytes())
}

// RandomBytes returns a specified number of random bytes.
// It is essentially a wrapper around RandomBytesBuf for convenience.
// Note that this behaviour is different than in NaCl and libsodium,
// where this function behaves the same as RandomBytesBuf.
func RandomBytes(size int) []byte {
	buf := make([]byte, size)
	RandomBytesBuf(buf)
	return buf
}

// RandomBytesBuf fills a buffer with random bytes.
func RandomBytesBuf(buf []byte) {
	if len(buf) > 0 {
		C.randombytes_buf(unsafe.Pointer(&buf[0]), C.size_t(len(buf)))
	}
}

// RandomBytesBufDeterministic fills a buffer with bytes that are
// indistinguishable from random bytes without knowing seed.
func RandomBytesBufDeterministic(buf []byte, seed []byte) {
	support.CheckSize(seed, RandomBytesSeedBytes(), "seed")
	if len(buf) > 0 {
		C.randombytes_buf_deterministic(
			unsafe.Pointer(&buf[0]),
			C.size_t(len(buf)),
			(*C.uchar)(&seed[0]))
	}
}

// RandomBytesRandom returns a random 32 bit unsigned integer.
func RandomBytesRandom() uint32 {
	return uint32(C.randombytes_random())
}

// RandomBytesUniform returns a random number between 0 and an upper bound.
// The generated bytes have a uniform distribution between 0 and the upper bound.
func RandomBytesUniform(upperBound uint32) uint32 {
	return uint32(C.randombytes_uniform(C.uint32_t(upperBound)))
}

// RandomBytesStir reseeds the random number generator.
func RandomBytesStir() {
	C.randombytes_stir()
}

// RandomBytesClose deallocates the resources used by the random number generator.
func RandomBytesClose() {
	C.randombytes_close()
}

// RandomBytesSetImplementation sets the implementation of the random number generator.
func RandomBytesSetImplementation(impl *C.struct_randombytes_implementation) int {
	return int(C.randombytes_set_implementation(impl))
}

// RandomBytesImplementationName returns the name of the random number
// generator that is being used.
func RandomBytesImplementationName() string {
	return C.GoString(C.randombytes_implementation_name())
}

// RandomBytesSalsa20Implementation contains a pointer to C.randombytes_salsa20_implementation
// This means that it can be used as an argument to RandomBytesSetImplementation
var RandomBytesSalsa20Implementation *C.struct_randombytes_implementation = &C.randombytes_salsa20_implementation

// RandomBytesSysRandomImplementation contains a pointer to C.randombytes_sysrandom_implementation
// This means that it can be used as an argument to RandomBytesSetImplementation
var RandomBytesSysRandomImplementation *C.struct_randombytes_implementation = &C.randombytes_sysrandom_implementation
<|endoftext|>


<commit_before>package api

import (
	"fmt"
	"mime"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/system"
	"github.com/docker/engine-api/types"
	"github.com/docker/libtrust"
)

// Common constants for daemon and client.
const (
	// Version of Current REST API
	DefaultVersion string = "1.25"

	// MinVersion represents Minimum REST API version supported
	MinVersion string = "1.12"

	// NoBaseImageSpecifier is the symbol used by the FROM
	// command to specify that no base image is to be used.
	NoBaseImageSpecifier string = "scratch"
)

// byPortInfo is a temporary type used to sort types.Port by its fields
type byPortInfo []types.Port

func (r byPortInfo) Len() int      { return len(r) }
func (r byPortInfo) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r byPortInfo) Less(i, j int) bool {
	if r[i].PrivatePort != r[j].PrivatePort {
		return r[i].PrivatePort < r[j].PrivatePort
	}

	if r[i].IP != r[j].IP {
		return r[i].IP < r[j].IP
	}

	if r[i].PublicPort != r[j].PublicPort {
		return r[i].PublicPort < r[j].PublicPort
	}

	return r[i].Type < r[j].Type
}

// DisplayablePorts returns formatted string representing open ports of container
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
// it's used by command 'docker ps'
func DisplayablePorts(ports []types.Port) string {
	type portGroup struct {
		first int
		last  int
	}
	groupMap := make(map[string]*portGroup)
	var result []string
	var hostMappings []string
	var groupMapKeys []string
	sort.Sort(byPortInfo(ports))
	for _, port := range ports {
		current := port.PrivatePort
		portKey := port.Type
		if port.IP != "" {
			if port.PublicPort != current {
				hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
				continue
			}
			portKey = fmt.Sprintf("%s/%s", port.IP, port.Type)
		}
		group := groupMap[portKey]

		if group == nil {
			groupMap[portKey] = &portGroup{first: current, last: current}
			// record order that groupMap keys are created
			groupMapKeys = append(groupMapKeys, portKey)
			continue
		}
		if current == (group.last + 1) {
			group.last = current
			continue
		}

		result = append(result, formGroup(portKey, group.first, group.last))
		groupMap[portKey] = &portGroup{first: current, last: current}
	}
	for _, portKey := range groupMapKeys {
		g := groupMap[portKey]
		result = append(result, formGroup(portKey, g.first, g.last))
	}
	result = append(result, hostMappings...)
	return strings.Join(result, ", ")
}

func formGroup(key string, start, last int) string {
	parts := strings.Split(key, "/")
	groupType := parts[0]
	var ip string
	if len(parts) > 1 {
		ip = parts[0]
		groupType = parts[1]
	}
	group := strconv.Itoa(start)
	if start != last {
		group = fmt.Sprintf("%s-%d", group, last)
	}
	if ip != "" {
		group = fmt.Sprintf("%s:%s->%s", ip, group, group)
	}
	return fmt.Sprintf("%s/%s", group, groupType)
}

// MatchesContentType validates the content type against the expected one
func MatchesContentType(contentType, expectedType string) bool {
	mimetype, _, err := mime.ParseMediaType(contentType)
	if err != nil {
		logrus.Errorf("Error parsing media type: %s error: %v", contentType, err)
	}
	return err == nil && mimetype == expectedType
}

// LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
// otherwise generates a new one
func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700)
	if err != nil {
		return nil, err
	}
	trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
	if err == libtrust.ErrKeyFileDoesNotExist {
		trustKey, err = libtrust.GenerateECP256PrivateKey()
		if err != nil {
			return nil, fmt.Errorf("Error generating key: %s", err)
		}
		if err := libtrust.SaveKey(trustKeyPath, trustKey); err != nil {
			return nil, fmt.Errorf("Error saving key file: %s", err)
		}
	} else if err != nil {
		return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
	}
	return trustKey, nil
}
<commit_msg>Atomically save libtrust key file<commit_after>package api

import (
	"encoding/json"
	"encoding/pem"
	"fmt"
	"mime"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/docker/pkg/system"
	"github.com/docker/engine-api/types"
	"github.com/docker/libtrust"
)

// Common constants for daemon and client.
const (
	// Version of Current REST API
	DefaultVersion string = "1.25"

	// MinVersion represents Minimum REST API version supported
	MinVersion string = "1.12"

	// NoBaseImageSpecifier is the symbol used by the FROM
	// command to specify that no base image is to be used.
	NoBaseImageSpecifier string = "scratch"
)

// byPortInfo is a temporary type used to sort types.Port by its fields
type byPortInfo []types.Port

func (r byPortInfo) Len() int      { return len(r) }
func (r byPortInfo) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r byPortInfo) Less(i, j int) bool {
	if r[i].PrivatePort != r[j].PrivatePort {
		return r[i].PrivatePort < r[j].PrivatePort
	}

	if r[i].IP != r[j].IP {
		return r[i].IP < r[j].IP
	}

	if r[i].PublicPort != r[j].PublicPort {
		return r[i].PublicPort < r[j].PublicPort
	}

	return r[i].Type < r[j].Type
}

// DisplayablePorts returns formatted string representing open ports of container
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
// it's used by command 'docker ps'
func DisplayablePorts(ports []types.Port) string {
	type portGroup struct {
		first int
		last  int
	}
	groupMap := make(map[string]*portGroup)
	var result []string
	var hostMappings []string
	var groupMapKeys []string
	sort.Sort(byPortInfo(ports))
	for _, port := range ports {
		current := port.PrivatePort
		portKey := port.Type
		if port.IP != "" {
			if port.PublicPort != current {
				hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
				continue
			}
			portKey = fmt.Sprintf("%s/%s", port.IP, port.Type)
		}
		group := groupMap[portKey]

		if group == nil {
			groupMap[portKey] = &portGroup{first: current, last: current}
			// record order that groupMap keys are created
			groupMapKeys = append(groupMapKeys, portKey)
			continue
		}
		if current == (group.last + 1) {
			group.last = current
			continue
		}

		result = append(result, formGroup(portKey, group.first, group.last))
		groupMap[portKey] = &portGroup{first: current, last: current}
	}
	for _, portKey := range groupMapKeys {
		g := groupMap[portKey]
		result = append(result, formGroup(portKey, g.first, g.last))
	}
	result = append(result, hostMappings...)
	return strings.Join(result, ", ")
}

func formGroup(key string, start, last int) string {
	parts := strings.Split(key, "/")
	groupType := parts[0]
	var ip string
	if len(parts) > 1 {
		ip = parts[0]
		groupType = parts[1]
	}
	group := strconv.Itoa(start)
	if start != last {
		group = fmt.Sprintf("%s-%d", group, last)
	}
	if ip != "" {
		group = fmt.Sprintf("%s:%s->%s", ip, group, group)
	}
	return fmt.Sprintf("%s/%s", group, groupType)
}

// MatchesContentType validates the content type against the expected one
func MatchesContentType(contentType, expectedType string) bool {
	mimetype, _, err := mime.ParseMediaType(contentType)
	if err != nil {
		logrus.Errorf("Error parsing media type: %s error: %v", contentType, err)
	}
	return err == nil && mimetype == expectedType
}

// LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
// otherwise generates a new one
func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700)
	if err != nil {
		return nil, err
	}
	trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
	if err == libtrust.ErrKeyFileDoesNotExist {
		trustKey, err = libtrust.GenerateECP256PrivateKey()
		if err != nil {
			return nil, fmt.Errorf("Error generating key: %s", err)
		}
		encodedKey, err := serializePrivateKey(trustKey, filepath.Ext(trustKeyPath))
		if err != nil {
			return nil, fmt.Errorf("Error serializing key: %s", err)
		}
		if err := ioutils.AtomicWriteFile(trustKeyPath, encodedKey, os.FileMode(0600)); err != nil {
			return nil, fmt.Errorf("Error saving key file: %s", err)
		}
	} else if err != nil {
		return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
	}
	return trustKey, nil
}

func serializePrivateKey(key libtrust.PrivateKey, ext string) (encoded []byte, err error) {
	if ext == ".json" || ext == ".jwk" {
		encoded, err = json.Marshal(key)
		if err != nil {
			return nil, fmt.Errorf("unable to encode private key JWK: %s", err)
		}
	} else {
		pemBlock, err := key.PEMBlock()
		if err != nil {
			return nil, fmt.Errorf("unable to encode private key PEM: %s", err)
		}
		encoded = pem.EncodeToMemory(pemBlock)
	}
	return
}
<|endoftext|>


<commit_before>package self_test

import (
	"crypto/tls"
	"fmt"
	"io"
	"io/ioutil"
	"sync"
	"time"

	"github.com/lucas-clemente/quic-go/integrationtests/tools/testserver"

	quic "github.com/lucas-clemente/quic-go"
	"github.com/lucas-clemente/quic-go/internal/testdata"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Stream tests", func() {
	var server quic.Listener
	const numStreams = 300

	BeforeEach(func() {
		var err error
		server, err = quic.ListenAddr("localhost:0", testdata.GetTLSConfig(), nil)
		Expect(err).ToNot(HaveOccurred())
	})

	AfterEach(func() {
		server.Close()
	})

	runSendingPeer := func(sess quic.Session) {
		var wg sync.WaitGroup
		wg.Add(numStreams)
		for i := 0; i < numStreams; i++ {
			str, err := sess.OpenStream()
			Expect(err).ToNot(HaveOccurred())
			data := testserver.GeneratePRData(25 * i)
			_, err = str.Write(data)
			Expect(err).ToNot(HaveOccurred())
			Expect(str.Close()).To(Succeed())
			go func() {
				defer GinkgoRecover()
				defer wg.Done()
				dataRead, err := ioutil.ReadAll(str)
				Expect(err).ToNot(HaveOccurred())
				Expect(dataRead).To(Equal(data))
			}()
			time.Sleep(5 * time.Millisecond)
		}
		wg.Wait()
	}

	runReceivingPeer := func(sess quic.Session) {
		var wg sync.WaitGroup
		wg.Add(numStreams)
		for i := 0; i < numStreams; i++ {
			str, err := sess.AcceptStream()
			Expect(err).ToNot(HaveOccurred())
			go func() {
				defer GinkgoRecover()
				defer wg.Done()
				_, err := io.Copy(str, str)
				Expect(err).ToNot(HaveOccurred())
				Expect(str.Close()).To(Succeed())
			}()
		}
		wg.Wait()
	}

	It(fmt.Sprintf("client opening %d streams to a client", numStreams), func() {
		done := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			sess, err := server.Accept()
			Expect(err).ToNot(HaveOccurred())
			runReceivingPeer(sess)
			close(done)
		}()

		client, err := quic.DialAddr(server.Addr().String(), &tls.Config{InsecureSkipVerify: true}, nil)
		Expect(err).ToNot(HaveOccurred())
		runSendingPeer(client)
		<-done
	})

	It(fmt.Sprintf("server opening %d streams to a client", numStreams), func() {
		done := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			sess, err := server.Accept()
			Expect(err).ToNot(HaveOccurred())
			runSendingPeer(sess)
			close(done)
		}()

		client, err := quic.DialAddr(server.Addr().String(), &tls.Config{InsecureSkipVerify: true}, nil)
		Expect(err).ToNot(HaveOccurred())
		runReceivingPeer(client)
		<-done
	})

	It(fmt.Sprintf("client and server opening %d each and sending data to the peer", numStreams), func() {
		done1 := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			sess, err := server.Accept()
			Expect(err).ToNot(HaveOccurred())
			done := make(chan struct{})
			go func() {
				defer GinkgoRecover()
				runReceivingPeer(sess)
				close(done)
			}()
			runSendingPeer(sess)
			<-done
			close(done1)
		}()

		client, err := quic.DialAddr(server.Addr().String(), &tls.Config{InsecureSkipVerify: true}, nil)
		Expect(err).ToNot(HaveOccurred())
		done2 := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			runSendingPeer(client)
			close(done2)
		}()
		runReceivingPeer(client)
		<-done1
		<-done2
	})
})
<commit_msg>fix concurrent streams integration test<commit_after>package self_test

import (
	"crypto/tls"
	"fmt"
	"io"
	"io/ioutil"
	"sync"

	"github.com/lucas-clemente/quic-go/integrationtests/tools/testserver"

	quic "github.com/lucas-clemente/quic-go"
	"github.com/lucas-clemente/quic-go/internal/testdata"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Stream tests", func() {
	var server quic.Listener
	const numStreams = 300

	BeforeEach(func() {
		var err error
		server, err = quic.ListenAddr("localhost:0", testdata.GetTLSConfig(), nil)
		Expect(err).ToNot(HaveOccurred())
	})

	AfterEach(func() {
		server.Close()
	})

	runSendingPeer := func(sess quic.Session) {
		var wg sync.WaitGroup
		wg.Add(numStreams)
		for i := 0; i < numStreams; i++ {
			str, err := sess.OpenStreamSync()
			Expect(err).ToNot(HaveOccurred())
			data := testserver.GeneratePRData(25 * i)
			go func() {
				defer GinkgoRecover()
				_, err := str.Write(data)
				Expect(err).ToNot(HaveOccurred())
				Expect(str.Close()).To(Succeed())
			}()
			go func() {
				defer GinkgoRecover()
				defer wg.Done()
				dataRead, err := ioutil.ReadAll(str)
				Expect(err).ToNot(HaveOccurred())
				Expect(dataRead).To(Equal(data))
			}()
		}
		wg.Wait()
	}

	runReceivingPeer := func(sess quic.Session) {
		var wg sync.WaitGroup
		wg.Add(numStreams)
		for i := 0; i < numStreams; i++ {
			str, err := sess.AcceptStream()
			Expect(err).ToNot(HaveOccurred())
			go func() {
				defer GinkgoRecover()
				defer wg.Done()
				_, err := io.Copy(str, str)
				Expect(err).ToNot(HaveOccurred())
				Expect(str.Close()).To(Succeed())
			}()
		}
		wg.Wait()
	}

	It(fmt.Sprintf("client opening %d streams to a client", numStreams), func() {
		done := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			sess, err := server.Accept()
			Expect(err).ToNot(HaveOccurred())
			runReceivingPeer(sess)
			close(done)
		}()

		client, err := quic.DialAddr(server.Addr().String(), &tls.Config{InsecureSkipVerify: true}, nil)
		Expect(err).ToNot(HaveOccurred())
		runSendingPeer(client)
		<-done
	})

	It(fmt.Sprintf("server opening %d streams to a client", numStreams), func() {
		done := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			sess, err := server.Accept()
			Expect(err).ToNot(HaveOccurred())
			runSendingPeer(sess)
			close(done)
		}()

		client, err := quic.DialAddr(server.Addr().String(), &tls.Config{InsecureSkipVerify: true}, nil)
		Expect(err).ToNot(HaveOccurred())
		runReceivingPeer(client)
		<-done
	})

	It(fmt.Sprintf("client and server opening %d each and sending data to the peer", numStreams), func() {
		done1 := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			sess, err := server.Accept()
			Expect(err).ToNot(HaveOccurred())
			done := make(chan struct{})
			go func() {
				defer GinkgoRecover()
				runReceivingPeer(sess)
				close(done)
			}()
			runSendingPeer(sess)
			<-done
			close(done1)
		}()

		client, err := quic.DialAddr(server.Addr().String(), &tls.Config{InsecureSkipVerify: true}, nil)
		Expect(err).ToNot(HaveOccurred())
		done2 := make(chan struct{})
		go func() {
			defer GinkgoRecover()
			runSendingPeer(client)
			close(done2)
		}()
		runReceivingPeer(client)
		<-done1
		<-done2
	})
})
<|endoftext|>


<commit_before>package net

import (
	"fmt"
	"net"
	"syscall"

	"github.com/vishvananda/netlink"
)

// Wait for an interface to come up.
func EnsureInterface(ifaceName string) (*net.Interface, error) {
	iface, err := ensureInterface(ifaceName)
	if err != nil {
		return nil, err
	}
	return iface, err
}

func ensureInterface(ifaceName string) (*net.Interface, error) {
	ch := make(chan netlink.LinkUpdate)
	done := make(chan struct{})
	defer close(done)
	if err := netlink.LinkSubscribe(ch, done); err != nil {
		return nil, err
	}
	// check for currently-existing interface after subscribing, to avoid race
	if iface, err := findInterface(ifaceName); err == nil {
		return iface, nil
	}
	for update := range ch {
		if ifaceName == update.Link.Attrs().Name && update.IfInfomsg.Flags&syscall.IFF_UP != 0 {
			break
		}
	}
	iface, err := findInterface(ifaceName)
	return iface, err
}

// Wait for an interface to come up and have a route added to the multicast subnet.
// This matches the behaviour in 'weave attach', which is the only context in which
// we expect this to be called.  If you change one, change the other to match.
func EnsureInterfaceAndMcastRoute(ifaceName string) (*net.Interface, error) {
	iface, err := ensureInterface(ifaceName)
	if err != nil {
		return nil, err
	}
	ch := make(chan netlink.RouteUpdate)
	done := make(chan struct{})
	defer close(done)
	if err := netlink.RouteSubscribe(ch, done); err != nil {
		return nil, err
	}
	dest := net.IPv4(224, 0, 0, 0)
	check := func(route netlink.Route) bool {
		return route.LinkIndex == iface.Index && route.Dst.IP.Equal(dest)
	}
	// check for currently-existing route after subscribing, to avoid race
	routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
	if err != nil {
		return nil, err
	}
	for _, route := range routes {
		if check(route) {
			return iface, nil
		}
	}
	for update := range ch {
		if check(update.Route) {
			return iface, nil
		}
	}
	// should never get here
	return iface, nil
}

func findInterface(ifaceName string) (iface *net.Interface, err error) {
	if iface, err = net.InterfaceByName(ifaceName); err != nil {
		return iface, fmt.Errorf("Unable to find interface %s", ifaceName)
	}
	if 0 == (net.FlagUp & iface.Flags) {
		return iface, fmt.Errorf("Interface %s is not up", ifaceName)
	}
	return
}
<commit_msg>cope with nil route.Dst<commit_after>package net

import (
	"fmt"
	"net"
	"syscall"

	"github.com/vishvananda/netlink"
)

// Wait for an interface to come up.
func EnsureInterface(ifaceName string) (*net.Interface, error) {
	iface, err := ensureInterface(ifaceName)
	if err != nil {
		return nil, err
	}
	return iface, err
}

func ensureInterface(ifaceName string) (*net.Interface, error) {
	ch := make(chan netlink.LinkUpdate)
	done := make(chan struct{})
	defer close(done)
	if err := netlink.LinkSubscribe(ch, done); err != nil {
		return nil, err
	}
	// check for currently-existing interface after subscribing, to avoid race
	if iface, err := findInterface(ifaceName); err == nil {
		return iface, nil
	}
	for update := range ch {
		if ifaceName == update.Link.Attrs().Name && update.IfInfomsg.Flags&syscall.IFF_UP != 0 {
			break
		}
	}
	iface, err := findInterface(ifaceName)
	return iface, err
}

// Wait for an interface to come up and have a route added to the multicast subnet.
// This matches the behaviour in 'weave attach', which is the only context in which
// we expect this to be called.  If you change one, change the other to match.
func EnsureInterfaceAndMcastRoute(ifaceName string) (*net.Interface, error) {
	iface, err := ensureInterface(ifaceName)
	if err != nil {
		return nil, err
	}
	ch := make(chan netlink.RouteUpdate)
	done := make(chan struct{})
	defer close(done)
	if err := netlink.RouteSubscribe(ch, done); err != nil {
		return nil, err
	}
	dest := net.IPv4(224, 0, 0, 0)
	check := func(route netlink.Route) bool {
		return route.LinkIndex == iface.Index && route.Dst != nil && route.Dst.IP.Equal(dest)
	}
	// check for currently-existing route after subscribing, to avoid race
	routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
	if err != nil {
		return nil, err
	}
	for _, route := range routes {
		if check(route) {
			return iface, nil
		}
	}
	for update := range ch {
		if check(update.Route) {
			return iface, nil
		}
	}
	// should never get here
	return iface, nil
}

func findInterface(ifaceName string) (iface *net.Interface, err error) {
	if iface, err = net.InterfaceByName(ifaceName); err != nil {
		return iface, fmt.Errorf("Unable to find interface %s", ifaceName)
	}
	if 0 == (net.FlagUp & iface.Flags) {
		return iface, fmt.Errorf("Interface %s is not up", ifaceName)
	}
	return
}
<|endoftext|>