<commit_before>package glutton

import (
	"bufio"
	"log"
	"math/rand"
	"net"
	"regexp"
	"strings"
)

// ConnID is used to relate logs in a connection
var connID int64

// Based on https://github.com/CymmetriaResearch/MTPot/blob/master/mirai_conf.json
var miraiCom = map[string][]string{
	"ps":                                              []string{"1 pts/21   00:00:00 init"},
	"cat /proc/mounts":                                []string{"tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3231524k,mode=755 0 0"},
	"echo -e \\x6b\\x61\\x6d\\x69/dev > /dev/.nippon": []string{""},
	"cat /dev/.nippon":                                []string{"kami/dev"},
	"rm /dev/.nippon":                                 []string{""},
	"echo -e \\x6b\\x61\\x6d\\x69/run > /run/.nippon": []string{""},
	"cat /run/.nippon":                                []string{"kami/run"},
	"rm /run/.nippon":                                 []string{""},
}

func writeMsg(conn net.Conn, msg string) error {
	_, err := conn.Write([]byte(msg))
	log.Printf("[%v] [TCP] [TELNET -> %v] Payload: %q", connID, conn.RemoteAddr(), msg)
	return err
}

func readMsg(conn net.Conn) (string, error) {
	message, err := bufio.NewReader(conn).ReadString('\n')
	if err != nil {
		return "", err
	}
	log.Printf("[%v] [TCP] [%v -> TELNET] Payload: %v", connID, conn.RemoteAddr(), message)
	return message, err
}

func handleTelnet(id int64, conn net.Conn) error {
	defer conn.Close()
	connID = id

	writeMsg(conn, "Username: ")
	_, err := readMsg(conn)
	if err != nil {
		return err
	}
	writeMsg(conn, "Password: ")
	_, err = readMsg(conn)
	if err != nil {
		return err
	}

	writeMsg(conn, "welcome\n> ")
	for {
		msg, err := readMsg(conn)
		if err != nil {
			return err
		}
		respMsg := ""
		for _, cmd := range strings.Split(msg, ";") {
			if resp := miraiCom[strings.TrimSpace(cmd)]; len(resp) > 0 {
				respMsg += resp[rand.Intn(len(resp))] + "\n"
			} else {
				re := regexp.MustCompile(`\/bin\/busybox (?P<applet>[A-Z]+)`)
				match := re.FindStringSubmatch(cmd)
				if len(match) > 1 {
					respMsg += match[1] + ": applet not found\n"
				}
			}
		}
		writeMsg(conn, respMsg)
		writeMsg(conn, "> ")
	}
}
<commit_msg>proper line feed<commit_after>package glutton

import (
	"bufio"
	"log"
	"math/rand"
	"net"
	"regexp"
	"strings"
)

// ConnID is used to relate logs in a connection
var connID int64

// Based on https://github.com/CymmetriaResearch/MTPot/blob/master/mirai_conf.json
var miraiCom = map[string][]string{
	"ps":                                              []string{"1 pts/21   00:00:00 init"},
	"cat /proc/mounts":                                []string{"tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3231524k,mode=755 0 0"},
	"echo -e \\x6b\\x61\\x6d\\x69/dev > /dev/.nippon": []string{""},
	"cat /dev/.nippon":                                []string{"kami/dev"},
	"rm /dev/.nippon":                                 []string{""},
	"echo -e \\x6b\\x61\\x6d\\x69/run > /run/.nippon": []string{""},
	"cat /run/.nippon":                                []string{"kami/run"},
	"rm /run/.nippon":                                 []string{""},
}

func writeMsg(conn net.Conn, msg string) error {
	_, err := conn.Write([]byte(msg))
	log.Printf("[%v] [TCP] [TELNET -> %v] Payload: %q", connID, conn.RemoteAddr(), msg)
	return err
}

func readMsg(conn net.Conn) (string, error) {
	message, err := bufio.NewReader(conn).ReadString('\n')
	if err != nil {
		return "", err
	}
	log.Printf("[%v] [TCP] [%v -> TELNET] Payload: %v", connID, conn.RemoteAddr(), message)
	return message, err
}

func handleTelnet(id int64, conn net.Conn) error {
	defer conn.Close()
	connID = id

	writeMsg(conn, "Username: ")
	_, err := readMsg(conn)
	if err != nil {
		return err
	}
	writeMsg(conn, "Password: ")
	_, err = readMsg(conn)
	if err != nil {
		return err
	}

	writeMsg(conn, "welcome\r\n> ")
	for {
		msg, err := readMsg(conn)
		if err != nil {
			return err
		}
		respMsg := ""
		for _, cmd := range strings.Split(msg, ";") {
			if resp := miraiCom[strings.TrimSpace(cmd)]; len(resp) > 0 {
				respMsg += resp[rand.Intn(len(resp))] + "\r\n"
			} else {
				re := regexp.MustCompile(`\/bin\/busybox (?P<applet>[A-Z]+)`)
				match := re.FindStringSubmatch(cmd)
				if len(match) > 1 {
					respMsg += match[1] + ": applet not found\r\n"
				}
			}
		}
		writeMsg(conn, respMsg)
		writeMsg(conn, "> ")
	}
}
<|endoftext|>


<commit_before>package commands

import (
	"io"
	"strings"

	cmds "github.com/jbenet/go-ipfs/commands"
	evlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
)

var log = evlog.Logger("core/commands")

type TestOutput struct {
	Foo string
	Bar int
}

var Root = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "global p2p merkle-dag filesystem",
		Synopsis: `
ipfs [<flags>] <command> [<arg>] ...
`,
		ShortDescription: `
BASIC COMMANDS

    init          Initialize ipfs local configuration
    add <path>    Add an object to ipfs
    cat <ref>     Show ipfs object data
    get <ref>     Download ipfs objects
    ls <ref>      List links from an object
    refs <ref>    List hashes of links from an object

DATA STRUCTURE COMMANDS

    block         Interact with raw blocks in the datastore
    object        Interact with raw dag nodes

ADVANCED COMMANDS

    daemon        Start a long-running daemon process
    mount         Mount an ipfs read-only mountpoint
    name          Publish or resolve IPNS names
    pin           Pin objects to local storage
    gc            Garbage collect unpinned objects

NETWORK COMMANDS

    id            Show info about ipfs peers
    bootstrap     Add or remove bootstrap peers
    swarm         Manage connections to the p2p network
    dht           Query the dht for values or peers
    ping          Measure the latency of a connection
    diag          Print diagnostics

TOOL COMMANDS

    config        Manage configuration
    version       Show ipfs version information
    update        Download and apply go-ipfs updates
    commands      List all available commands

Use 'ipfs <command> --help' to learn more about each command.
`,
	},
	Options: []cmds.Option{
		cmds.StringOption("config", "c", "Path to the configuration file to use"),
		cmds.BoolOption("debug", "D", "Operate in debug mode"),
		cmds.BoolOption("help", "Show the full command help text"),
		cmds.BoolOption("h", "Show a short version of the command help text"),
		cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon"),
	},
}

// commandsDaemonCmd is the "ipfs commands" command for daemon
var CommandsDaemonCmd = CommandsCmd(Root)

var rootSubcommands = map[string]*cmds.Command{
	"add":       AddCmd,
	"block":     BlockCmd,
	"bootstrap": BootstrapCmd,
	"cat":       CatCmd,
	"commands":  CommandsDaemonCmd,
	"config":    ConfigCmd,
	"dht":       DhtCmd,
	"diag":      DiagCmd,
	"get":       GetCmd,
	"id":        IDCmd,
	"log":       LogCmd,
	"ls":        LsCmd,
	"mount":     MountCmd,
	"name":      NameCmd,
	"object":    ObjectCmd,
	"pin":       PinCmd,
	"ping":      PingCmd,
	"refs":      RefsCmd,
	"repo":      RepoCmd,
	"swarm":     SwarmCmd,
	"update":    UpdateCmd,
	"version":   VersionCmd,
	"bitswap":   BitswapCmd,
}

func init() {
	Root.Subcommands = rootSubcommands
}

type MessageOutput struct {
	Message string
}

func MessageTextMarshaler(res cmds.Response) (io.Reader, error) {
	return strings.NewReader(res.Output().(*MessageOutput).Message), nil
}
<commit_msg>`gc` is actually `repo gc`, reflect in docs<commit_after>package commands

import (
	"io"
	"strings"

	cmds "github.com/jbenet/go-ipfs/commands"
	evlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
)

var log = evlog.Logger("core/commands")

type TestOutput struct {
	Foo string
	Bar int
}

var Root = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "global p2p merkle-dag filesystem",
		Synopsis: `
ipfs [<flags>] <command> [<arg>] ...
`,
		ShortDescription: `
BASIC COMMANDS

    init          Initialize ipfs local configuration
    add <path>    Add an object to ipfs
    cat <ref>     Show ipfs object data
    get <ref>     Download ipfs objects
    ls <ref>      List links from an object
    refs <ref>    List hashes of links from an object

DATA STRUCTURE COMMANDS

    block         Interact with raw blocks in the datastore
    object        Interact with raw dag nodes

ADVANCED COMMANDS

    daemon        Start a long-running daemon process
    mount         Mount an ipfs read-only mountpoint
    name          Publish or resolve IPNS names
    pin           Pin objects to local storage
    repo gc       Garbage collect unpinned objects

NETWORK COMMANDS

    id            Show info about ipfs peers
    bootstrap     Add or remove bootstrap peers
    swarm         Manage connections to the p2p network
    dht           Query the dht for values or peers
    ping          Measure the latency of a connection
    diag          Print diagnostics

TOOL COMMANDS

    config        Manage configuration
    version       Show ipfs version information
    update        Download and apply go-ipfs updates
    commands      List all available commands

Use 'ipfs <command> --help' to learn more about each command.
`,
	},
	Options: []cmds.Option{
		cmds.StringOption("config", "c", "Path to the configuration file to use"),
		cmds.BoolOption("debug", "D", "Operate in debug mode"),
		cmds.BoolOption("help", "Show the full command help text"),
		cmds.BoolOption("h", "Show a short version of the command help text"),
		cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon"),
	},
}

// commandsDaemonCmd is the "ipfs commands" command for daemon
var CommandsDaemonCmd = CommandsCmd(Root)

var rootSubcommands = map[string]*cmds.Command{
	"add":       AddCmd,
	"block":     BlockCmd,
	"bootstrap": BootstrapCmd,
	"cat":       CatCmd,
	"commands":  CommandsDaemonCmd,
	"config":    ConfigCmd,
	"dht":       DhtCmd,
	"diag":      DiagCmd,
	"get":       GetCmd,
	"id":        IDCmd,
	"log":       LogCmd,
	"ls":        LsCmd,
	"mount":     MountCmd,
	"name":      NameCmd,
	"object":    ObjectCmd,
	"pin":       PinCmd,
	"ping":      PingCmd,
	"refs":      RefsCmd,
	"repo":      RepoCmd,
	"swarm":     SwarmCmd,
	"update":    UpdateCmd,
	"version":   VersionCmd,
	"bitswap":   BitswapCmd,
}

func init() {
	Root.Subcommands = rootSubcommands
}

type MessageOutput struct {
	Message string
}

func MessageTextMarshaler(res cmds.Response) (io.Reader, error) {
	return strings.NewReader(res.Output().(*MessageOutput).Message), nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 shawn1m. All rights reserved.
// Use of this source code is governed by The MIT License (MIT) that can be
// found in the LICENSE file.

package config

import (
	"bufio"
	"encoding/json"
	"io"
	"io/ioutil"
	"net"
	"os"
	"strconv"
	"strings"

	log "github.com/sirupsen/logrus"

	"github.com/shawn1m/overture/core/cache"
	"github.com/shawn1m/overture/core/common"
	"github.com/shawn1m/overture/core/hosts"
	"github.com/shawn1m/overture/core/matcher"
	"github.com/shawn1m/overture/core/matcher/full"
	"github.com/shawn1m/overture/core/matcher/mix"
	"github.com/shawn1m/overture/core/matcher/regex"
	"github.com/shawn1m/overture/core/matcher/suffix"
)

type Config struct {
	BindAddress           string
	DebugHTTPAddress      string
	PrimaryDNS            []*common.DNSUpstream
	AlternativeDNS        []*common.DNSUpstream
	OnlyPrimaryDNS        bool
	IPv6UseAlternativeDNS bool
	IPNetworkFile         struct {
		Primary     string
		Alternative string
	}
	DomainFile struct {
		Primary     string
		Alternative string
		Matcher     string
	}
	HostsFile     string
	MinimumTTL    int
	DomainTTLFile string
	CacheSize     int
	RejectQType   []uint16

	DomainTTLMap                map[string]uint32
	DomainPrimaryList           matcher.Matcher
	DomainAlternativeList       matcher.Matcher
	WhenPrimaryDNSAnswerNoneUse string
	IPNetworkPrimaryList        []*net.IPNet
	IPNetworkAlternativeList    []*net.IPNet
	Hosts                       *hosts.Hosts
	Cache                       *cache.Cache
}

// New config with json file and do some other initiate works
func NewConfig(configFile string) *Config {
	config := parseJson(configFile)

	config.DomainTTLMap = getDomainTTLMap(config.DomainTTLFile)

	config.DomainPrimaryList = initDomainMatcher(config.DomainFile.Primary, config.DomainFile.Matcher)
	config.DomainAlternativeList = initDomainMatcher(config.DomainFile.Alternative, config.DomainFile.Matcher)

	config.IPNetworkPrimaryList = getIPNetworkList(config.IPNetworkFile.Primary)
	config.IPNetworkAlternativeList = getIPNetworkList(config.IPNetworkFile.Alternative)

	if config.MinimumTTL > 0 {
		log.Infof("Minimum TTL has been set to %d", config.MinimumTTL)
	} else {
		log.Info("Minimum TTL is disabled")
	}

	config.Cache = cache.New(config.CacheSize)
	if config.CacheSize > 0 {
		log.Infof("CacheSize is %d", config.CacheSize)
	} else {
		log.Info("Cache is disabled")
	}

	h, err := hosts.New(config.HostsFile)
	if err != nil {
		log.Warnf("Failed to load hosts file: %s", err)
	} else {
		config.Hosts = h
		log.Info("Hosts file has been loaded successfully")
	}

	return config
}

func parseJson(path string) *Config {
	b, err := ioutil.ReadFile(path)
	if err != nil {
		log.Fatalf("Failed to read config file: %s", err)
		os.Exit(1)
	}

	j := new(Config)
	err = json.Unmarshal(b, j)
	if err != nil {
		log.Fatalf("Failed to parse config file: %s", err)
		os.Exit(1)
	}

	return j
}

func getDomainTTLMap(file string) map[string]uint32 {
	if file == "" {
		return map[string]uint32{}
	}

	f, err := os.Open(file)
	if err != nil {
		log.Errorf("Failed to open domain TTL file %s: %s", file, err)
		return nil
	}
	defer f.Close()

	successes := 0
	failures := 0
	var failedLines []string

	dtl := map[string]uint32{}

	reader := bufio.NewReader(f)

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Errorf("Failed to read domain TTL file %s: %s", file, err)
			} else {
				log.Debugf("Reading domain TTL file %s reached EOF", file)
			}
			break
		}

		if line != "" {
			words := strings.Fields(line)
			if len(words) > 1 {
				tempInt64, err := strconv.ParseUint(words[1], 10, 32)
				dtl[words[0]] = uint32(tempInt64)
				if err != nil {
					log.WithFields(log.Fields{"domain": words[0], "ttl": words[1]}).Warnf("Invalid TTL for domain %s: %s", words[0], words[1])
					failures++
					failedLines = append(failedLines, line)
				}
				successes++
			} else {
				failedLines = append(failedLines, line)
				failures++
			}
		}
	}

	if len(dtl) > 0 {
		log.Infof("Domain TTL file %s has been loaded with %d records (%d failed)", file, successes, failures)
		if len(failedLines) > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	} else {
		log.Warnf("No element has been loaded from domain TTL file: %s", file)
		if len(failedLines) > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	}

	return dtl
}

func getDomainMatcher(name string) (m matcher.Matcher) {
	switch name {
	case "suffix-tree":
		return suffix.DefaultDomainTree()
	case "full-map":
		return &full.Map{DataMap: make(map[string]struct{}, 100)}
	case "full-list":
		return &full.List{}
	case "regex-list":
		return &regex.List{}
	case "mix-list":
		return &mix.List{}
	default:
		log.Warnf("Matcher %s does not exist, using regex-list matcher as default", name)
		return &regex.List{}
	}
}

func initDomainMatcher(file string, name string) (m matcher.Matcher) {
	m = getDomainMatcher(name)

	if file == "" {
		return
	}

	f, err := os.Open(file)
	if err != nil {
		log.Errorf("Failed to open domain file %s: %s", file, err)
		return nil
	}
	defer f.Close()

	lines := 0
	reader := bufio.NewReader(f)

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Errorf("Failed to read domain file %s: %s", file, err)
			} else {
				log.Debugf("Reading domain file %s reached EOF", file)
			}
			break
		}

		line = strings.TrimSpace(line)
		if line != "" {
			_ = m.Insert(line)
			lines++
		}
	}

	if lines > 0 {
		log.Infof("Domain file %s has been loaded with %d records (%s)", file, lines, m.Name())
	} else {
		log.Warnf("No element has been loaded from domain file: %s", file)
	}

	return
}

func getIPNetworkList(file string) []*net.IPNet {
	ipNetList := make([]*net.IPNet, 0)

	f, err := os.Open(file)
	if err != nil {
		log.Errorf("Failed to open IP network file: %s", err)
		return nil
	}
	defer f.Close()

	successes := 0
	failures := 0
	var failedLines []string

	reader := bufio.NewReader(f)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Errorf("Failed to read IP network file %s: %s", file, err)
			} else {
				log.Debugf("Reading IP network file %s has reached EOF", file)
			}
			break
		}

		if line != "" {
			_, ipNet, err := net.ParseCIDR(line)
			if err != nil {
				log.Errorf("Error parsing IP network CIDR %s: %s", line, err)
				failures++
				failedLines = append(failedLines, line)
				continue
			}
			ipNetList = append(ipNetList, ipNet)
			successes++
		}
	}

	if len(ipNetList) > 0 {
		log.Infof("IP network file %s has been loaded with %d records", file, successes)
		if failures > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	} else {
		log.Warnf("No element has been loaded from IP network file: %s", file)
		if failures > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	}

	return ipNetList
}
<commit_msg>fix the read ip list txt bug. the bug error message as following: (#170)<commit_after>// Copyright (c) 2016 shawn1m. All rights reserved.
// Use of this source code is governed by The MIT License (MIT) that can be
// found in the LICENSE file.

package config

import (
	"bufio"
	"encoding/json"
	"io"
	"io/ioutil"
	"net"
	"os"
	"strconv"
	"strings"

	log "github.com/sirupsen/logrus"

	"github.com/shawn1m/overture/core/cache"
	"github.com/shawn1m/overture/core/common"
	"github.com/shawn1m/overture/core/hosts"
	"github.com/shawn1m/overture/core/matcher"
	"github.com/shawn1m/overture/core/matcher/full"
	"github.com/shawn1m/overture/core/matcher/mix"
	"github.com/shawn1m/overture/core/matcher/regex"
	"github.com/shawn1m/overture/core/matcher/suffix"
)

type Config struct {
	BindAddress           string
	DebugHTTPAddress      string
	PrimaryDNS            []*common.DNSUpstream
	AlternativeDNS        []*common.DNSUpstream
	OnlyPrimaryDNS        bool
	IPv6UseAlternativeDNS bool
	IPNetworkFile         struct {
		Primary     string
		Alternative string
	}
	DomainFile struct {
		Primary     string
		Alternative string
		Matcher     string
	}
	HostsFile     string
	MinimumTTL    int
	DomainTTLFile string
	CacheSize     int
	RejectQType   []uint16

	DomainTTLMap                map[string]uint32
	DomainPrimaryList           matcher.Matcher
	DomainAlternativeList       matcher.Matcher
	WhenPrimaryDNSAnswerNoneUse string
	IPNetworkPrimaryList        []*net.IPNet
	IPNetworkAlternativeList    []*net.IPNet
	Hosts                       *hosts.Hosts
	Cache                       *cache.Cache
}

// New config with json file and do some other initiate works
func NewConfig(configFile string) *Config {
	config := parseJson(configFile)

	config.DomainTTLMap = getDomainTTLMap(config.DomainTTLFile)

	config.DomainPrimaryList = initDomainMatcher(config.DomainFile.Primary, config.DomainFile.Matcher)
	config.DomainAlternativeList = initDomainMatcher(config.DomainFile.Alternative, config.DomainFile.Matcher)

	config.IPNetworkPrimaryList = getIPNetworkList(config.IPNetworkFile.Primary)
	config.IPNetworkAlternativeList = getIPNetworkList(config.IPNetworkFile.Alternative)

	if config.MinimumTTL > 0 {
		log.Infof("Minimum TTL has been set to %d", config.MinimumTTL)
	} else {
		log.Info("Minimum TTL is disabled")
	}

	config.Cache = cache.New(config.CacheSize)
	if config.CacheSize > 0 {
		log.Infof("CacheSize is %d", config.CacheSize)
	} else {
		log.Info("Cache is disabled")
	}

	h, err := hosts.New(config.HostsFile)
	if err != nil {
		log.Warnf("Failed to load hosts file: %s", err)
	} else {
		config.Hosts = h
		log.Info("Hosts file has been loaded successfully")
	}

	return config
}

func parseJson(path string) *Config {
	b, err := ioutil.ReadFile(path)
	if err != nil {
		log.Fatalf("Failed to read config file: %s", err)
		os.Exit(1)
	}

	j := new(Config)
	err = json.Unmarshal(b, j)
	if err != nil {
		log.Fatalf("Failed to parse config file: %s", err)
		os.Exit(1)
	}

	return j
}

func getDomainTTLMap(file string) map[string]uint32 {
	if file == "" {
		return map[string]uint32{}
	}

	f, err := os.Open(file)
	if err != nil {
		log.Errorf("Failed to open domain TTL file %s: %s", file, err)
		return nil
	}
	defer f.Close()

	successes := 0
	failures := 0
	var failedLines []string

	dtl := map[string]uint32{}

	reader := bufio.NewReader(f)

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Errorf("Failed to read domain TTL file %s: %s", file, err)
			} else {
				log.Debugf("Reading domain TTL file %s reached EOF", file)
			}
			break
		}

		if line != "" {
			words := strings.Fields(line)
			if len(words) > 1 {
				tempInt64, err := strconv.ParseUint(words[1], 10, 32)
				dtl[words[0]] = uint32(tempInt64)
				if err != nil {
					log.WithFields(log.Fields{"domain": words[0], "ttl": words[1]}).Warnf("Invalid TTL for domain %s: %s", words[0], words[1])
					failures++
					failedLines = append(failedLines, line)
				}
				successes++
			} else {
				failedLines = append(failedLines, line)
				failures++
			}
		}
	}

	if len(dtl) > 0 {
		log.Infof("Domain TTL file %s has been loaded with %d records (%d failed)", file, successes, failures)
		if len(failedLines) > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	} else {
		log.Warnf("No element has been loaded from domain TTL file: %s", file)
		if len(failedLines) > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	}

	return dtl
}

func getDomainMatcher(name string) (m matcher.Matcher) {
	switch name {
	case "suffix-tree":
		return suffix.DefaultDomainTree()
	case "full-map":
		return &full.Map{DataMap: make(map[string]struct{}, 100)}
	case "full-list":
		return &full.List{}
	case "regex-list":
		return &regex.List{}
	case "mix-list":
		return &mix.List{}
	default:
		log.Warnf("Matcher %s does not exist, using regex-list matcher as default", name)
		return &regex.List{}
	}
}

func initDomainMatcher(file string, name string) (m matcher.Matcher) {
	m = getDomainMatcher(name)

	if file == "" {
		return
	}

	f, err := os.Open(file)
	if err != nil {
		log.Errorf("Failed to open domain file %s: %s", file, err)
		return nil
	}
	defer f.Close()

	lines := 0
	reader := bufio.NewReader(f)

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Errorf("Failed to read domain file %s: %s", file, err)
			} else {
				log.Debugf("Reading domain file %s reached EOF", file)
			}
			break
		}

		line = strings.TrimSpace(line)
		if line != "" {
			_ = m.Insert(line)
			lines++
		}
	}

	if lines > 0 {
		log.Infof("Domain file %s has been loaded with %d records (%s)", file, lines, m.Name())
	} else {
		log.Warnf("No element has been loaded from domain file: %s", file)
	}

	return
}

func getIPNetworkList(file string) []*net.IPNet {
	ipNetList := make([]*net.IPNet, 0)

	f, err := os.Open(file)
	if err != nil {
		log.Errorf("Failed to open IP network file: %s", err)
		return nil
	}
	defer f.Close()

	successes := 0
	failures := 0
	var failedLines []string

	reader := bufio.NewReader(f)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Errorf("Failed to read IP network file %s: %s", file, err)
			} else {
				log.Debugf("Reading IP network file %s has reached EOF", file)
			}
			break
		}

		if line != "" {
			_, ipNet, err := net.ParseCIDR(strings.TrimSuffix(line, "\n"))
			if err != nil {
				log.Errorf("Error parsing IP network CIDR %s: %s", line, err)
				failures++
				failedLines = append(failedLines, line)
				continue
			}
			ipNetList = append(ipNetList, ipNet)
			successes++
		}
	}

	if len(ipNetList) > 0 {
		log.Infof("IP network file %s has been loaded with %d records", file, successes)
		if failures > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	} else {
		log.Warnf("No element has been loaded from IP network file: %s", file)
		if failures > 0 {
			log.Debugf("Failed lines (%s):", file)
			for _, line := range failedLines {
				log.Debug(line)
			}
		}
	}

	return ipNetList
}
<|endoftext|>


<commit_before>package s3

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"time"
)

// Represents AWS credentials and config.
type Credentials struct {
	Region string
	Bucket string
	AccessKeyID string
	SecretAccessKey string
}

// Represents presigned POST information.
type PresignedPOST struct {
	Key string         `json:"key"`
	Policy string      `json:"policy"`
	Signature string   `json:"signature"`
	Action string      `json:"action"`
	Credential string  `json:"credential"`
	Date string        `json:"date"`
}

// Creates a new presigned POST.
func NewPresignedPOST(key string, c *Credentials) (*PresignedPOST, error) {
	p := NewPolicy(key, c)
	b64Policy := p.Base64()
	signature := createSignature(p.C, p.Date[:8], b64Policy)
	action := fmt.Sprintf("https://%s.s3.amazonaws.com/", p.Bucket)
	post := &PresignedPOST{
		Key: p.Key,
		Policy: b64Policy,
		Signature: signature,
		Action: action,
		Credential: p.Credential,
		Date: p.Date,
	}
	return post, nil
}

// Creates the signature for a string.
func createSignature(c *Credentials, formattedShortTime, stringToSign string) string {
	h1 := makeHmac([]byte("AWS4"+c.SecretAccessKey), []byte(formattedShortTime))
	h2 := makeHmac(h1, []byte(c.Region))
	h3 := makeHmac(h2, []byte("s3"))
	h4 := makeHmac(h3, []byte("aws4_request"))
	signature := makeHmac(h4, []byte(stringToSign))
	return hex.EncodeToString(signature)
}

// Helper to make the HMAC-SHA256.
func makeHmac(key []byte, data []byte) []byte {
	hash := hmac.New(sha256.New, key)
	hash.Write(data)
	return hash.Sum(nil)
}

// Policy template.
const policyDocument = `
{ "expiration": "%s",
  "conditions": [
    {"bucket": "%s"},
    ["starts-with", "$key", "%s"],
    {"acl": "public-read"},
    ["starts-with", "$x-amz-meta-tag", ""],
    ["content-length-range", 1, 524288],

    {"x-amz-credential": "%s"},
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    {"x-amz-date": "%s" }
  ]
}
`

const (
	expirationFormat = "2006-01-02T15:04:05.000Z"
	timeFormat = "20060102T150405Z"
	shortTimeFormat = "20060102"
)

// Represents a new policy for uploading sounds.
type policy struct {
	Expiration string
	Region string
	Bucket string
	Key string
	Credential string
	Date string
	C *Credentials
}

// Creates a new policy.
func NewPolicy(key string, c *Credentials) *policy {
	// expires in 5 minutes
	t := time.Now().Add(time.Minute * 5)
	formattedShortTime := t.UTC().Format(shortTimeFormat)
	date := t.UTC().Format(timeFormat)
	cred := fmt.Sprintf("%s/%s/%s/s3/aws4_request", c.AccessKeyID, formattedShortTime, c.Region)
	return &policy{
		Expiration: t.UTC().Format(expirationFormat),
		Region: c.Region,
		Bucket: c.Bucket,
		Key: key,
		Credential: cred,
		Date: date,
		C: c,
	}
}

// Returns the policy as a string.
func (p *policy) String() string {
	return fmt.Sprintf(policyDocument,
		p.Expiration,
		p.Bucket,
		p.Key,
		p.Credential,
		p.Date,
	)
}

// Returns the policy as a base64 encoded string.
func (p *policy) Base64() string {
	return base64.StdEncoding.EncodeToString([]byte(p.String()))
}
<commit_msg>Removes meta from policy.<commit_after>package s3

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"time"
)

// Represents AWS credentials and config.
type Credentials struct {
	Region string
	Bucket string
	AccessKeyID string
	SecretAccessKey string
}

// Represents presigned POST information.
type PresignedPOST struct {
	Key string         `json:"key"`
	Policy string      `json:"policy"`
	Signature string   `json:"signature"`
	Action string      `json:"action"`
	Credential string  `json:"credential"`
	Date string        `json:"date"`
}

// Creates a new presigned POST.
func NewPresignedPOST(key string, c *Credentials) (*PresignedPOST, error) {
	p := NewPolicy(key, c)
	b64Policy := p.Base64()
	signature := createSignature(p.C, p.Date[:8], b64Policy)
	action := fmt.Sprintf("https://%s.s3.amazonaws.com/", p.Bucket)
	post := &PresignedPOST{
		Key: p.Key,
		Policy: b64Policy,
		Signature: signature,
		Action: action,
		Credential: p.Credential,
		Date: p.Date,
	}
	return post, nil
}

// Creates the signature for a string.
func createSignature(c *Credentials, formattedShortTime, stringToSign string) string {
	h1 := makeHmac([]byte("AWS4"+c.SecretAccessKey), []byte(formattedShortTime))
	h2 := makeHmac(h1, []byte(c.Region))
	h3 := makeHmac(h2, []byte("s3"))
	h4 := makeHmac(h3, []byte("aws4_request"))
	signature := makeHmac(h4, []byte(stringToSign))
	return hex.EncodeToString(signature)
}

// Helper to make the HMAC-SHA256.
func makeHmac(key []byte, data []byte) []byte {
	hash := hmac.New(sha256.New, key)
	hash.Write(data)
	return hash.Sum(nil)
}

// Policy template.
const policyDocument = `
{ "expiration": "%s",
  "conditions": [
    {"bucket": "%s"},
    ["starts-with", "$key", "%s"],
    {"acl": "public-read"},
    ["content-length-range", 1, 524288],

    {"x-amz-credential": "%s"},
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    {"x-amz-date": "%s" }
  ]
}
`

const (
	expirationFormat = "2006-01-02T15:04:05.000Z"
	timeFormat = "20060102T150405Z"
	shortTimeFormat = "20060102"
)

// Represents a new policy for uploading sounds.
type policy struct {
	Expiration string
	Region string
	Bucket string
	Key string
	Credential string
	Date string
	C *Credentials
}

// Creates a new policy.
func NewPolicy(key string, c *Credentials) *policy {
	// expires in 5 minutes
	t := time.Now().Add(time.Minute * 5)
	formattedShortTime := t.UTC().Format(shortTimeFormat)
	date := t.UTC().Format(timeFormat)
	cred := fmt.Sprintf("%s/%s/%s/s3/aws4_request", c.AccessKeyID, formattedShortTime, c.Region)
	return &policy{
		Expiration: t.UTC().Format(expirationFormat),
		Region: c.Region,
		Bucket: c.Bucket,
		Key: key,
		Credential: cred,
		Date: date,
		C: c,
	}
}

// Returns the policy as a string.
func (p *policy) String() string {
	return fmt.Sprintf(policyDocument,
		p.Expiration,
		p.Bucket,
		p.Key,
		p.Credential,
		p.Date,
	)
}

// Returns the policy as a base64 encoded string.
func (p *policy) Base64() string {
	return base64.StdEncoding.EncodeToString([]byte(p.String()))
}
<|endoftext|>


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

package mat64

import (
	"github.com/gonum/blas"
	"github.com/gonum/lapack/lapack64"
)

// Solve solves a minimum-norm solution to a system of linear equations defined
// by the matrices A and B. If A is singular or near-singular a Condition error
// is returned. Please see the documentation for Condition for more information.
//
// The minimization problem solved depends on the input parameters.
//  1. If m >= n and trans == false, find X such that || A*X - B||_2 is minimized.
//  2. If m < n and trans == false, find the minimum norm solution of A * X = B.
//  3. If m >= n and trans == true, find the minimum norm solution of A^T * X = B.
//  4. If m < n and trans == true, find X such that || A*X - B||_2 is minimized.
// The solution matrix, X, is stored in place into the receiver.
func (m *Dense) Solve(a, b Matrix) error {
	ar, ac := a.Dims()
	br, bc := b.Dims()
	if ar != br {
		panic(ErrShape)
	}

	aMat, _ := untranspose(a)
	bMat, _ := untranspose(b)
	m.reuseAs(ac, bc)
	var restore func()
	if m == aMat {
		m, restore = m.isolatedWorkspace(aMat)
		defer restore()
	} else if m == bMat {
		m, restore = m.isolatedWorkspace(bMat)
		defer restore()
	}
	// TODO(btracey): Add a test for the condition number of A.
	// TODO(btracey): Add special cases for TriDense, SymDense, etc.
	switch {
	case ar == ac:
		// Solve using an LU decomposition.
		var lu LU
		lu.Factorize(a)
		if lu.Det() == 0 {
			return ErrSingular
		}
		m.Copy(b)
		lapack64.Getrs(blas.NoTrans, lu.lu.mat, m.mat, lu.pivot)
		return nil
	default:
		// Solve using QR/LQ.

		// Copy a since the corresponding LAPACK argument is modified during
		// the call.
		var aCopy Dense
		aCopy.Clone(a)

		x := getWorkspace(max(ar, ac), bc, false)
		x.Copy(b)

		work := make([]float64, 1)
		lapack64.Gels(blas.NoTrans, aCopy.mat, x.mat, work, -1)
		work = make([]float64, int(work[0]))
		ok := lapack64.Gels(blas.NoTrans, aCopy.mat, x.mat, work, len(work))
		if !ok {
			return ErrSingular
		}
		m.Copy(x)
		return nil
	}
}

// SolveVec solves a minimum-norm solution to a system of linear equations defined
// by the matrices A and B. If A is singular or near-singular a Condition error
// is returned. Please see the documentation for more information.
func (v *Vector) SolveVec(a Matrix, b *Vector) error {
	_, c := a.Dims()
	// The Solve implementation is non-trivial, so rather than duplicate the code,
	// instead recast the Vectors as Dense and call the matrix code.
	v.reuseAs(c)
	m := vecAsDense(v)
	bm := vecAsDense(b)
	return m.Solve(a, bm)
}
<commit_msg>Fix comment<commit_after>// Copyright ©2015 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package mat64

import (
	"github.com/gonum/blas"
	"github.com/gonum/lapack/lapack64"
)

// Solve solves a minimum-norm solution to a system of linear equations defined
// by the matrices a and b. If a is singular or near-singular a Condition error
// is returned. Please see the documentation for Condition for more information.
//
// The minimization problem solved depends on the input parameters.
//  1. If m >= n and trans == false, find x such that || a*x - b||_2 is minimized.
//  2. If m < n and trans == false, find the minimum norm solution of a * x = b.
//  3. If m >= n and trans == true, find the minimum norm solution of a^T * x = b.
//  4. If m < n and trans == true, find X such that || a*x - b||_2 is minimized.
// The solution matrix, x, is stored in place into the receiver.
func (m *Dense) Solve(a, b Matrix) error {
	ar, ac := a.Dims()
	br, bc := b.Dims()
	if ar != br {
		panic(ErrShape)
	}

	aMat, _ := untranspose(a)
	bMat, _ := untranspose(b)
	m.reuseAs(ac, bc)
	var restore func()
	if m == aMat {
		m, restore = m.isolatedWorkspace(aMat)
		defer restore()
	} else if m == bMat {
		m, restore = m.isolatedWorkspace(bMat)
		defer restore()
	}
	// TODO(btracey): Add a test for the condition number of A.
	// TODO(btracey): Add special cases for TriDense, SymDense, etc.
	switch {
	case ar == ac:
		// Solve using an LU decomposition.
		var lu LU
		lu.Factorize(a)
		if lu.Det() == 0 {
			return ErrSingular
		}
		m.Copy(b)
		lapack64.Getrs(blas.NoTrans, lu.lu.mat, m.mat, lu.pivot)
		return nil
	default:
		// Solve using QR/LQ.

		// Copy a since the corresponding LAPACK argument is modified during
		// the call.
		var aCopy Dense
		aCopy.Clone(a)

		x := getWorkspace(max(ar, ac), bc, false)
		x.Copy(b)

		work := make([]float64, 1)
		lapack64.Gels(blas.NoTrans, aCopy.mat, x.mat, work, -1)
		work = make([]float64, int(work[0]))
		ok := lapack64.Gels(blas.NoTrans, aCopy.mat, x.mat, work, len(work))
		if !ok {
			return ErrSingular
		}
		m.Copy(x)
		return nil
	}
}

// SolveVec solves a minimum-norm solution to a system of linear equations defined
// by the matrices A and B. If A is singular or near-singular a Condition error
// is returned. Please see the documentation for more information.
func (v *Vector) SolveVec(a Matrix, b *Vector) error {
	_, c := a.Dims()
	// The Solve implementation is non-trivial, so rather than duplicate the code,
	// instead recast the Vectors as Dense and call the matrix code.
	v.reuseAs(c)
	m := vecAsDense(v)
	bm := vecAsDense(b)
	return m.Solve(a, bm)
}
<|endoftext|>


<commit_before>package vegeta

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

// Attacker is an attack executor which wraps an http.Client
type Attacker struct {
	dialer *net.Dialer
	client http.Client
}

var (
	// DefaultRedirects represents the number of times the DefaultAttacker
	// follows redirects
	DefaultRedirects = 10
	// DefaultTimeout represents the amount of time the DefaultAttacker waits
	// for a request before it times out
	DefaultTimeout = 30 * time.Second
	// DefaultLocalAddr is the local IP address the DefaultAttacker uses in its
	// requests
	DefaultLocalAddr = net.IPAddr{IP: net.IPv4zero}
	// DefaultTLSConfig is the default tls.Config the DefaultAttacker uses in its
	// requests
	DefaultTLSConfig = &tls.Config{InsecureSkipVerify: true}
)

// NewAttacker returns a new Attacker with default options which are overridden
// by the optionally provided opts.
func NewAttacker(opts ...func(*Attacker)) *Attacker {
	a := &Attacker{}
	a.dialer = &net.Dialer{
		LocalAddr: &net.TCPAddr{IP: DefaultLocalAddr.IP, Zone: DefaultLocalAddr.Zone},
		KeepAlive: 30 * time.Second,
		Timeout:   DefaultTimeout,
	}
	a.client = http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			Dial:  a.dialer.Dial,
			ResponseHeaderTimeout: DefaultTimeout,
			TLSClientConfig:       DefaultTLSConfig,
			TLSHandshakeTimeout:   10 * time.Second,
		},
	}
	for _, opt := range opts {
		opt(a)
	}
	return a
}

// Redirects returns a functional option which sets the maximum
// number of redirects an Attacker will follow.
func Redirects(n int) func(*Attacker) {
	return func(a *Attacker) {
		a.client.CheckRedirect = func(_ *http.Request, via []*http.Request) error {
			if len(via) > n {
				return fmt.Errorf("stopped after %d redirects", n)
			}
			return nil
		}
	}
}

// Timeout returns a functional option which sets the maximum amount of time
// an Attacker will wait for a request to be responded to.
func Timeout(d time.Duration) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.ResponseHeaderTimeout = d
		a.dialer.Timeout = d
		tr.Dial = a.dialer.Dial
		a.client.Transport = tr
	}
}

// LocalAddr returns a functional option which sets the local address
// an Attacker will use with its requests.
func LocalAddr(addr net.IPAddr) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		a.dialer.LocalAddr = &net.TCPAddr{IP: addr.IP, Zone: addr.Zone}
		tr.Dial = a.dialer.Dial
		a.client.Transport = tr
	}
}

// TLSConfig returns a functional option which sets the *tls.Config for a
// Attacker to use with its requests.
func TLSConfig(c *tls.Config) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.TLSClientConfig = c
		a.client.Transport = tr
	}
}

// Attack reads its Targets from the passed Targeter and attacks them at
// the rate specified for duration time. Results are put into the returned channel
// as soon as they arrive.
//
// The number of workers used in the attack is specified by wrk.
// If wrk is zero or greater than the total number of hits, it will be capped
// to that maximum.
func (a *Attacker) Attack(tr Targeter, rate uint64, du time.Duration, wrk uint64) chan *Result {
	resc := make(chan *Result)
	throttle := time.NewTicker(time.Duration(1e9 / rate))
	hits := rate * uint64(du.Seconds())
	if wrk == 0 || wrk > hits {
		wrk = hits
	}
	share := hits / wrk

	var wg sync.WaitGroup
	for i := uint64(0); i < wrk; i++ {
		wg.Add(1)
		go func(share uint64) {
			for j := uint64(0); j < share; j++ {
				<-throttle.C
				resc <- a.hit(tr)
			}
			wg.Done()
		}(share)
	}

	go func() {
		wg.Wait()
		close(resc)
		throttle.Stop()
	}()

	return resc
}

func (a *Attacker) hit(tr Targeter) *Result {
	tgt, err := tr()
	if err != nil {
		return &Result{Error: err.Error()}
	}

	res := new(Result)
	req, err := tgt.Request()
	if err != nil {
		res.Error = err.Error()
		return res
	}

	res.Timestamp = time.Now()
	r, err := a.client.Do(req)
	res.Latency = time.Since(res.Timestamp)
	if err != nil {
		res.Error = err.Error()
		return res
	}
	defer r.Body.Close()

	res.BytesOut = uint64(req.ContentLength)
	res.Code = uint16(r.StatusCode)
	if body, err := ioutil.ReadAll(r.Body); err != nil {
		if res.Code < 200 || res.Code >= 300 {
			res.Error = string(body)
		}
	} else {
		res.BytesIn = uint64(len(body))
	}
	res.Latency = time.Since(res.Timestamp)

	return res
}
<commit_msg>Update documentation of defaults<commit_after>package vegeta

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

// Attacker is an attack executor which wraps an http.Client
type Attacker struct {
	dialer *net.Dialer
	client http.Client
}

var (
	// DefaultRedirects is the default number of times an Attacker follows
	// redirects.
	DefaultRedirects = 10
	// DefaultTimeout is the default amount of time an Attacker waits for a request
	// before it times out.
	DefaultTimeout = 30 * time.Second
	// DefaultLocalAddr is the default local IP address an Attacker uses.
	DefaultLocalAddr = net.IPAddr{IP: net.IPv4zero}
	// DefaultTLSConfig is the default tls.Config an Attacker uses.
	DefaultTLSConfig = &tls.Config{InsecureSkipVerify: true}
)

// NewAttacker returns a new Attacker with default options which are overridden
// by the optionally provided opts.
func NewAttacker(opts ...func(*Attacker)) *Attacker {
	a := &Attacker{}
	a.dialer = &net.Dialer{
		LocalAddr: &net.TCPAddr{IP: DefaultLocalAddr.IP, Zone: DefaultLocalAddr.Zone},
		KeepAlive: 30 * time.Second,
		Timeout:   DefaultTimeout,
	}
	a.client = http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			Dial:  a.dialer.Dial,
			ResponseHeaderTimeout: DefaultTimeout,
			TLSClientConfig:       DefaultTLSConfig,
			TLSHandshakeTimeout:   10 * time.Second,
		},
	}
	for _, opt := range opts {
		opt(a)
	}
	return a
}

// Redirects returns a functional option which sets the maximum
// number of redirects an Attacker will follow.
func Redirects(n int) func(*Attacker) {
	return func(a *Attacker) {
		a.client.CheckRedirect = func(_ *http.Request, via []*http.Request) error {
			if len(via) > n {
				return fmt.Errorf("stopped after %d redirects", n)
			}
			return nil
		}
	}
}

// Timeout returns a functional option which sets the maximum amount of time
// an Attacker will wait for a request to be responded to.
func Timeout(d time.Duration) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.ResponseHeaderTimeout = d
		a.dialer.Timeout = d
		tr.Dial = a.dialer.Dial
		a.client.Transport = tr
	}
}

// LocalAddr returns a functional option which sets the local address
// an Attacker will use with its requests.
func LocalAddr(addr net.IPAddr) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		a.dialer.LocalAddr = &net.TCPAddr{IP: addr.IP, Zone: addr.Zone}
		tr.Dial = a.dialer.Dial
		a.client.Transport = tr
	}
}

// TLSConfig returns a functional option which sets the *tls.Config for a
// Attacker to use with its requests.
func TLSConfig(c *tls.Config) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.TLSClientConfig = c
		a.client.Transport = tr
	}
}

// Attack reads its Targets from the passed Targeter and attacks them at
// the rate specified for duration time. Results are put into the returned channel
// as soon as they arrive.
//
// The number of workers used in the attack is specified by wrk.
// If wrk is zero or greater than the total number of hits, it will be capped
// to that maximum.
func (a *Attacker) Attack(tr Targeter, rate uint64, du time.Duration, wrk uint64) chan *Result {
	resc := make(chan *Result)
	throttle := time.NewTicker(time.Duration(1e9 / rate))
	hits := rate * uint64(du.Seconds())
	if wrk == 0 || wrk > hits {
		wrk = hits
	}
	share := hits / wrk

	var wg sync.WaitGroup
	for i := uint64(0); i < wrk; i++ {
		wg.Add(1)
		go func(share uint64) {
			for j := uint64(0); j < share; j++ {
				<-throttle.C
				resc <- a.hit(tr)
			}
			wg.Done()
		}(share)
	}

	go func() {
		wg.Wait()
		close(resc)
		throttle.Stop()
	}()

	return resc
}

func (a *Attacker) hit(tr Targeter) *Result {
	tgt, err := tr()
	if err != nil {
		return &Result{Error: err.Error()}
	}

	res := new(Result)
	req, err := tgt.Request()
	if err != nil {
		res.Error = err.Error()
		return res
	}

	res.Timestamp = time.Now()
	r, err := a.client.Do(req)
	res.Latency = time.Since(res.Timestamp)
	if err != nil {
		res.Error = err.Error()
		return res
	}
	defer r.Body.Close()

	res.BytesOut = uint64(req.ContentLength)
	res.Code = uint16(r.StatusCode)
	if body, err := ioutil.ReadAll(r.Body); err != nil {
		if res.Code < 200 || res.Code >= 300 {
			res.Error = string(body)
		}
	} else {
		res.BytesIn = uint64(len(body))
	}
	res.Latency = time.Since(res.Timestamp)

	return res
}
<|endoftext|>


<commit_before>package vegeta

import (
	"crypto/tls"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"
)

// Attacker is an attack executor which wraps an http.Client
type Attacker struct {
	dialer    *net.Dialer
	client    http.Client
	stopch    chan struct{}
	workers   uint64
	redirects int
}

const (
	// DefaultRedirects is the default number of times an Attacker follows
	// redirects.
	DefaultRedirects = 10
	// DefaultTimeout is the default amount of time an Attacker waits for a request
	// before it times out.
	DefaultTimeout = 30 * time.Second
	// DefaultConnections is the default amount of max open idle connections per
	// target host.
	DefaultConnections = 10000
	// NoFollow is the value when redirects are not followed but marked successful
	NoFollow = -1
)

var (
	// DefaultLocalAddr is the default local IP address an Attacker uses.
	DefaultLocalAddr = net.IPAddr{IP: net.IPv4zero}
	// DefaultTLSConfig is the default tls.Config an Attacker uses.
	DefaultTLSConfig = &tls.Config{InsecureSkipVerify: true}
)

// NewAttacker returns a new Attacker with default options which are overridden
// by the optionally provided opts.
func NewAttacker(opts ...func(*Attacker)) *Attacker {
	a := &Attacker{stopch: make(chan struct{})}
	a.dialer = &net.Dialer{
		LocalAddr: &net.TCPAddr{IP: DefaultLocalAddr.IP, Zone: DefaultLocalAddr.Zone},
		KeepAlive: 30 * time.Second,
		Timeout:   DefaultTimeout,
	}
	a.client = http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			Dial:  a.dialer.Dial,
			ResponseHeaderTimeout: DefaultTimeout,
			TLSClientConfig:       DefaultTLSConfig,
			TLSHandshakeTimeout:   10 * time.Second,
			MaxIdleConnsPerHost:   DefaultConnections,
		},
	}
	for _, opt := range opts {
		opt(a)
	}
	return a
}

// Workers returns a functional option which sets the initial number of workers
// an Attacker uses to hit its targets. More workers may be spawned dynamically
// to sustain the requested rate in the face of slow responses and errors.
//
// If zero or greater than an attack's rate, workers will be set to that rate.
func Workers(n uint64) func(*Attacker) {
	return func(a *Attacker) { a.workers = n }
}

// Connections returns a functional option which sets the number of maximum idle
// open connections per target host.
func Connections(n int) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.MaxIdleConnsPerHost = n
	}
}

// Redirects returns a functional option which sets the maximum
// number of redirects an Attacker will follow.
func Redirects(n int) func(*Attacker) {
	return func(a *Attacker) {
		a.redirects = n
		a.client.CheckRedirect = func(_ *http.Request, via []*http.Request) error {
			if len(via) > n {
				return fmt.Errorf("stopped after %d redirects", n)
			}
			return nil
		}
	}
}

// Timeout returns a functional option which sets the maximum amount of time
// an Attacker will wait for a request to be responded to.
func Timeout(d time.Duration) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.ResponseHeaderTimeout = d
		a.dialer.Timeout = d
		tr.Dial = a.dialer.Dial
	}
}

// LocalAddr returns a functional option which sets the local address
// an Attacker will use with its requests.
func LocalAddr(addr net.IPAddr) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		a.dialer.LocalAddr = &net.TCPAddr{IP: addr.IP, Zone: addr.Zone}
		tr.Dial = a.dialer.Dial
	}
}

// KeepAlive returns a functional option which toggles KeepAlive
// connections on the dialer and transport.
func KeepAlive(keepalive bool) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.DisableKeepAlives = !keepalive
		if !keepalive {
			a.dialer.KeepAlive = 0
			tr.Dial = a.dialer.Dial
		}
	}
}

// TLSConfig returns a functional option which sets the *tls.Config for a
// Attacker to use with its requests.
func TLSConfig(c *tls.Config) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.TLSClientConfig = c
	}
}

// Attack reads its Targets from the passed Targeter and attacks them at
// the rate specified for duration time. Results are put into the returned channel
// as soon as they arrive.
func (a *Attacker) Attack(tr Targeter, rate uint64, du time.Duration) chan *Result {
	hits := rate * uint64(du.Seconds())
	wrk := a.workers
	if wrk == 0 || wrk > rate {
		wrk = rate
	}

	workers := &sync.WaitGroup{}
	results := make(chan *Result)
	ticks := make(chan time.Time)
	for i := uint64(0); i < wrk; i++ {
		go a.attack(tr, workers, ticks, results)
	}

	go func() {
		defer close(results)
		defer workers.Wait()
		defer close(ticks)
		interval := 1e9 / rate
		for began, done := time.Now(), uint64(0); done < hits; done++ {
			next := began.Add(time.Duration(done * interval))
			time.Sleep(next.Sub(time.Now()))
			select {
			case ticks <- next:
			case <-a.stopch:
				return
			default: // all workers are blocked. start one more and try again
				go a.attack(tr, workers, ticks, results)
				done--
			}
		}
	}()

	return results
}

// Stop stops the current attack.
func (a *Attacker) Stop() { close(a.stopch) }

func (a *Attacker) attack(tr Targeter, workers *sync.WaitGroup, ticks <-chan time.Time, results chan<- *Result) {
	workers.Add(1)
	defer workers.Done()
	for tm := range ticks {
		results <- a.hit(tr, tm)
	}
}

func (a *Attacker) hit(tr Targeter, tm time.Time) *Result {
	var (
		res = Result{Timestamp: tm}
		err error
	)

	defer func() {
		res.Latency = time.Since(tm)
		if err != nil {
			res.Error = err.Error()
		}
	}()

	tgt, err := tr()
	if err != nil {
		return &res
	}

	req, err := tgt.Request()
	if err != nil {
		return &res
	}

	r, err := a.client.Do(req)
	if err != nil {
		// ignore redirect errors when the user set --redirects=NoFollow
		if a.redirects == NoFollow && strings.Contains(err.Error(), "stopped after") {
			err = nil
		}
		return &res
	}
	defer r.Body.Close()

	in, err := io.Copy(ioutil.Discard, r.Body)
	if err != nil {
		return &res
	}
	res.BytesIn = uint64(in)

	if req.ContentLength != -1 {
		res.BytesOut = uint64(req.ContentLength)
	}

	if res.Code = uint16(r.StatusCode); res.Code < 200 || res.Code >= 400 {
		res.Error = r.Status
	}

	return &res
}
<commit_msg>Use current time for tick when lagging behind<commit_after>package vegeta

import (
	"crypto/tls"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"strings"
	"sync"
	"time"
)

// Attacker is an attack executor which wraps an http.Client
type Attacker struct {
	dialer    *net.Dialer
	client    http.Client
	stopch    chan struct{}
	workers   uint64
	redirects int
}

const (
	// DefaultRedirects is the default number of times an Attacker follows
	// redirects.
	DefaultRedirects = 10
	// DefaultTimeout is the default amount of time an Attacker waits for a request
	// before it times out.
	DefaultTimeout = 30 * time.Second
	// DefaultConnections is the default amount of max open idle connections per
	// target host.
	DefaultConnections = 10000
	// NoFollow is the value when redirects are not followed but marked successful
	NoFollow = -1
)

var (
	// DefaultLocalAddr is the default local IP address an Attacker uses.
	DefaultLocalAddr = net.IPAddr{IP: net.IPv4zero}
	// DefaultTLSConfig is the default tls.Config an Attacker uses.
	DefaultTLSConfig = &tls.Config{InsecureSkipVerify: true}
)

// NewAttacker returns a new Attacker with default options which are overridden
// by the optionally provided opts.
func NewAttacker(opts ...func(*Attacker)) *Attacker {
	a := &Attacker{stopch: make(chan struct{})}
	a.dialer = &net.Dialer{
		LocalAddr: &net.TCPAddr{IP: DefaultLocalAddr.IP, Zone: DefaultLocalAddr.Zone},
		KeepAlive: 30 * time.Second,
		Timeout:   DefaultTimeout,
	}
	a.client = http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			Dial:  a.dialer.Dial,
			ResponseHeaderTimeout: DefaultTimeout,
			TLSClientConfig:       DefaultTLSConfig,
			TLSHandshakeTimeout:   10 * time.Second,
			MaxIdleConnsPerHost:   DefaultConnections,
		},
	}
	for _, opt := range opts {
		opt(a)
	}
	return a
}

// Workers returns a functional option which sets the initial number of workers
// an Attacker uses to hit its targets. More workers may be spawned dynamically
// to sustain the requested rate in the face of slow responses and errors.
//
// If zero or greater than an attack's rate, workers will be set to that rate.
func Workers(n uint64) func(*Attacker) {
	return func(a *Attacker) { a.workers = n }
}

// Connections returns a functional option which sets the number of maximum idle
// open connections per target host.
func Connections(n int) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.MaxIdleConnsPerHost = n
	}
}

// Redirects returns a functional option which sets the maximum
// number of redirects an Attacker will follow.
func Redirects(n int) func(*Attacker) {
	return func(a *Attacker) {
		a.redirects = n
		a.client.CheckRedirect = func(_ *http.Request, via []*http.Request) error {
			if len(via) > n {
				return fmt.Errorf("stopped after %d redirects", n)
			}
			return nil
		}
	}
}

// Timeout returns a functional option which sets the maximum amount of time
// an Attacker will wait for a request to be responded to.
func Timeout(d time.Duration) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.ResponseHeaderTimeout = d
		a.dialer.Timeout = d
		tr.Dial = a.dialer.Dial
	}
}

// LocalAddr returns a functional option which sets the local address
// an Attacker will use with its requests.
func LocalAddr(addr net.IPAddr) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		a.dialer.LocalAddr = &net.TCPAddr{IP: addr.IP, Zone: addr.Zone}
		tr.Dial = a.dialer.Dial
	}
}

// KeepAlive returns a functional option which toggles KeepAlive
// connections on the dialer and transport.
func KeepAlive(keepalive bool) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.DisableKeepAlives = !keepalive
		if !keepalive {
			a.dialer.KeepAlive = 0
			tr.Dial = a.dialer.Dial
		}
	}
}

// TLSConfig returns a functional option which sets the *tls.Config for a
// Attacker to use with its requests.
func TLSConfig(c *tls.Config) func(*Attacker) {
	return func(a *Attacker) {
		tr := a.client.Transport.(*http.Transport)
		tr.TLSClientConfig = c
	}
}

// Attack reads its Targets from the passed Targeter and attacks them at
// the rate specified for duration time. Results are put into the returned channel
// as soon as they arrive.
func (a *Attacker) Attack(tr Targeter, rate uint64, du time.Duration) chan *Result {
	hits := rate * uint64(du.Seconds())
	wrk := a.workers
	if wrk == 0 || wrk > rate {
		wrk = rate
	}

	workers := &sync.WaitGroup{}
	results := make(chan *Result)
	ticks := make(chan time.Time)
	for i := uint64(0); i < wrk; i++ {
		go a.attack(tr, workers, ticks, results)
	}

	go func() {
		defer close(results)
		defer workers.Wait()
		defer close(ticks)
		interval := 1e9 / rate
		for began, done := time.Now(), uint64(0); done < hits; done++ {
			now, next := time.Now(), began.Add(time.Duration(done*interval))
			time.Sleep(next.Sub(now))
			select {
			case ticks <- max(next, now):
			case <-a.stopch:
				return
			default: // all workers are blocked. start one more and try again
				go a.attack(tr, workers, ticks, results)
				done--
			}
		}
	}()

	return results
}

// Stop stops the current attack.
func (a *Attacker) Stop() { close(a.stopch) }

func (a *Attacker) attack(tr Targeter, workers *sync.WaitGroup, ticks <-chan time.Time, results chan<- *Result) {
	workers.Add(1)
	defer workers.Done()
	for tm := range ticks {
		results <- a.hit(tr, tm)
	}
}

func (a *Attacker) hit(tr Targeter, tm time.Time) *Result {
	var (
		res = Result{Timestamp: tm}
		err error
	)

	defer func() {
		res.Latency = time.Since(tm)
		if err != nil {
			res.Error = err.Error()
		}
	}()

	tgt, err := tr()
	if err != nil {
		return &res
	}

	req, err := tgt.Request()
	if err != nil {
		return &res
	}

	r, err := a.client.Do(req)
	if err != nil {
		// ignore redirect errors when the user set --redirects=NoFollow
		if a.redirects == NoFollow && strings.Contains(err.Error(), "stopped after") {
			err = nil
		}
		return &res
	}
	defer r.Body.Close()

	in, err := io.Copy(ioutil.Discard, r.Body)
	if err != nil {
		return &res
	}
	res.BytesIn = uint64(in)

	if req.ContentLength != -1 {
		res.BytesOut = uint64(req.ContentLength)
	}

	if res.Code = uint16(r.StatusCode); res.Code < 200 || res.Code >= 400 {
		res.Error = r.Status
	}

	return &res
}

func max(a, b time.Time) time.Time {
	if a.After(b) {
		return a
	}
	return b
}
<|endoftext|>


<commit_before>package less

import (
	"os/exec"
	"bytes"
	"fmt"
)

func Compile(path string, w *bytes.Buffer, paths...string)error {
	var cmd *exec.Cmd
	l := len(paths)
	if paths != nil && l > 0 {
		pathBuffer := new(bytes.Buffer)
		for i, p := range paths {
			pathBuffer.WriteString(p)
			if i >= 0 && l-1 != i {
				pathBuffer.WriteString(":")
			}
		}
		cmd = exec.Command("lessc", path, "--paths", pathBuffer.String())
	} else {
		cmd = exec.Command("lessc", path)
	}
	cmdOut, err := cmd.Output()
	if err != nil {
		fmt.Println(err)
		fmt.Println(cmdOut)
		return err
	}
	_, err = w.Write(cmdOut)
	return err
}<commit_msg>update<commit_after>package less

import (
	"os/exec"
	"bytes"
	"fmt"
)

func Compile(path string, w *bytes.Buffer, paths...string)error {
	var cmd *exec.Cmd
	l := len(paths)
	if paths != nil && l > 0 {
		pathBuffer := new(bytes.Buffer)
		for i, p := range paths {
			pathBuffer.WriteString(p)
			if i >= 0 && l-1 != i {
				pathBuffer.WriteString(":")
			}
		}
		cmd = exec.Command("lessc", path, "--paths", pathBuffer.String())
	} else {
		cmd = exec.Command("lessc", path)
	}
	cmdOut, err := cmd.Output()
	if err != nil {
		return err
	}
	_, err = w.Write(cmdOut)
	return err
}<|endoftext|>


<commit_before>package pixur

import (
	"bytes"
	"database/sql"
	"fmt"
	"image"
	"image/gif"
	"io/ioutil"
	"os"
	"sync"
	"testing"

	ptest "pixur.org/pixur/testing"
)

var (
	pixPath           string
	uploadedImagePath string
	uploadedImageSize int64
)

type container struct {
	t  *testing.T
	db *sql.DB
}

func (c *container) mustFindTagByName(name string) *Tag {
	tag, err := c.findTagByName(name)
	if err != nil {
		c.t.Fatal(err)
	}

	return tag
}

func (c *container) findTagByName(name string) (*Tag, error) {
	tx, err := c.db.Begin()
	if err != nil {
		c.t.Fatal(err)
	}
	defer tx.Rollback()

	t, err := findTagByName(name, tx)
	return t, err
}

func (c *container) createTag(name string) *Tag {
	tag := &Tag{
		Name: name,
	}
	tx, err := c.db.Begin()
	if err != nil {
		c.t.Fatal(err)
	}
	defer tx.Rollback()

	if tag, err := findTagByName(name, tx); err == nil {
		return tag
	}

	if err := tag.Insert(tx); err != nil {
		c.t.Fatal(err)
	}
	if err := tx.Commit(); err != nil {
		c.t.Fatal(err)
	}

	return tag
}

func (c *container) createTagExp(name string) *Tag {
	tag := &Tag{
		Name: name,
	}
	tx, err := c.db.Begin()
	if err != nil {
		c.t.Fatal(err)
	}
	defer tx.Rollback()

	tags, err := findTags(tx, "SELECT * FROM tags WHERE name = ? FOR UPDATE;", name)
	if err != nil {
		c.t.Fatal(err)
	}

	if len(tags) == 0 {
		// gaplock?
		if err := tag.Insert(tx); err != nil {
			c.t.Fatal(err)
		}
		if err := tx.Commit(); err != nil {
			c.t.Fatal(err)
		}
	} else if len(tags) == 1 {

		tag = tags[0]
		tag.Count++
		if err := tag.Update(tx); err != nil {
			c.t.Fatal(err)
		}
		if err := tx.Commit(); err != nil {
			c.t.Fatal(err)
		}

	} else {
		c.t.Fatal("Too many tags!", tags)
	}
	return tag
}

func init() {
	BeforeTestSuite(func() error {
		if path, err := ioutil.TempDir("", "pixPath"); err != nil {
			return err
		} else {
			pixPath = path
		}
		AfterTestSuite(func() error {
			return os.RemoveAll(pixPath)
		})

		return nil
	})

	BeforeTestSuite(func() error {
		f, err := ioutil.TempFile(pixPath, "")
		if err != nil {
			return err
		}
		uploadedImagePath = f.Name()
		defer f.Close()
		AfterTestSuite(func() error {
			return os.RemoveAll(uploadedImagePath)
		})

		img := image.NewGray(image.Rect(0, 0, 5, 10))

		if err := gif.Encode(f, img, &gif.Options{}); err != nil {
			return err
		}
		if fi, err := f.Stat(); err != nil {
			return err
		} else {
			uploadedImageSize = fi.Size()
		}
		return nil
	})
}

func TestWorkflowFileUpload(t *testing.T) {
	if err := func() error {
		imgData, err := os.Open(uploadedImagePath)
		if err != nil {
			return err
		}
		task := &CreatePicTask{
			db:       testDB,
			pixPath:  pixPath,
			FileData: imgData,
		}
		if err := task.Run(); err != nil {
			task.Reset()
			return err
		}

		expected := Pic{
			FileSize: uploadedImageSize,
			Mime:     Mime_GIF,
			Width:    5,
			Height:   10,
		}
		actual := *task.CreatedPic

		if _, err := os.Stat(actual.Path(pixPath)); err != nil {
			return fmt.Errorf("Image was not moved: %s", err)
		}
		if _, err := os.Stat(actual.ThumbnailPath(pixPath)); err != nil {
			return fmt.Errorf("Thumbnail not created: %s", err)
		}

		// Zero out these, since they can change from test to test
		actual.Id = 0
		ptest.AssertEquals(actual.CreatedTime, actual.ModifiedTime, t)
		actual.CreatedTime = 0
		actual.ModifiedTime = 0

		ptest.AssertEquals(actual, expected, t)
		return nil
	}(); err != nil {
		t.Fatal(err)
	}
}

func _TestWorkflowAllTagsAdded(t *testing.T) {
	ctnr := &container{
		t:  t,
		db: testDB,
	}

	imgData, err := os.Open(uploadedImagePath)
	if err != nil {
		t.Fatal(err)
	}
	task := &CreatePicTask{
		db:       testDB,
		pixPath:  pixPath,
		FileData: imgData,
		TagNames: []string{"foo", "bar"},
	}
	if err := task.Run(); err != nil {
		task.Reset()
		t.Fatal(err)
	}

	fooTag := ctnr.mustFindTagByName("foo")
	barTag := ctnr.mustFindTagByName("bar")

	picTags, err := findPicTagsByPicId(task.CreatedPic.Id, testDB)
	if err != nil {
		t.Fatal(err)
	}
	if len(picTags) != 2 {
		t.Fatal(fmt.Errorf("Wrong number of pic tags", picTags))
	}
	var picTagsGroupedByName = groupPicTagsByTagName(picTags)
	if picTagsGroupedByName["foo"].TagId != fooTag.Id {
		t.Fatal(fmt.Errorf("Tag ID does not match PicTag TagId", fooTag.Id))
	}
	if picTagsGroupedByName["bar"].TagId != barTag.Id {
		t.Fatal(fmt.Errorf("Tag ID does not match PicTag TagId", barTag.Id))
	}
}

// Disabled until I implement retry
func _TestWorkflowAlreadyExistingTags(t *testing.T) {
	ctnr := &container{
		t:  t,
		db: testDB,
	}
	imgData, err := os.Open(uploadedImagePath)
	if err != nil {
		t.Fatal(err)
	}
	//ctnr.createTag("bars")

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			ctnr.createTagExp("bars")
		}()
	}
	wg.Wait()

	fmt.Println(ctnr.mustFindTagByName("bars"))

	bazTag := ctnr.createTag("baz")
	quxTag := ctnr.createTag("qux")

	task := &CreatePicTask{
		db:       testDB,
		pixPath:  pixPath,
		FileData: imgData,
		TagNames: []string{"baz", "qux"},
	}
	if err := task.Run(); err != nil {
		task.Reset()
		t.Fatal(err)
	}

	picTags, err := findPicTagsByPicId(task.CreatedPic.Id, testDB)
	if err != nil {
		t.Fatal(err)
	}
	if len(picTags) != 2 {
		t.Fatal("Wrong number of pic tags", picTags)
	}
	var picTagsGroupedByName = groupPicTagsByTagName(picTags)
	if picTagsGroupedByName["baz"].TagId != bazTag.Id {
		t.Fatal("Tag ID does not match PicTag TagId", bazTag.Id)
	}
	if picTagsGroupedByName["qux"].TagId != quxTag.Id {
		t.Fatal("Tag ID does not match PicTag TagId", quxTag.Id)
	}
}

func TestWorkflowTrimAndCollapseDuplicateTags(t *testing.T) {
	if err := func() error {
		imgData, err := os.Open(uploadedImagePath)
		if err != nil {
			return err
		}

		task := &CreatePicTask{
			db:       testDB,
			pixPath:  pixPath,
			FileData: imgData,
			// All of these are the same
			TagNames: []string{"foo", "foo", "  foo", "foo  "},
		}
		if err := task.Run(); err != nil {
			task.Reset()
			return err
		}

		tx, err := testDB.Begin()
		if err != nil {
			return err
		}
		fooTag, err := findTagByName("foo", tx)
		if err != nil {
			return err
		}

		picTags, err := findPicTagsByPicId(task.CreatedPic.Id, testDB)
		if err != nil {
			return err
		}
		if len(picTags) != 1 {
			return fmt.Errorf("Wrong number of pic tags", picTags)
		}
		if picTags[0].TagId != fooTag.Id {
			return fmt.Errorf("Tag ID does not match PicTag TagId", fooTag.Id)
		}
		return nil
	}(); err != nil {
		t.Fatal(err)
	}
}

func TestCleanTagNames(t *testing.T) {
	var unclean = []string{
		"   ",
		" ", // should collapse with the above
		"",  // should also collapse"
		"a",
		"   a",
		"a   ",
		"b b",
		"c\nc",
		"pokémon",
	}
	var expected = []string{
		"a",
		"b b",
		"cc",
		"pokémon",
	}
	cleaned := cleanTagNames(unclean)
	if len(cleaned) != len(expected) {
		t.Fatal("Size mismatch", cleaned, expected)
	}
	for i, tagName := range cleaned {
		if tagName != expected[i] {
			t.Fatal("tag mismatch", cleaned, expected)
		}
	}
}

func BenchmarkCreation(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if err := func() error {
			imgData, err := os.Open(uploadedImagePath)
			if err != nil {
				return err
			}

			task := &CreatePicTask{
				db:       testDB,
				pixPath:  pixPath,
				FileData: imgData,
				TagNames: []string{"foo", "bar"},
			}
			if err := task.Run(); err != nil {
				task.Reset()
				return err
			}
			return nil
		}(); err != nil {
			b.Fatal(err)
		}
	}
}

func TestMoveUploadedFile(t *testing.T) {
	if err := func() error {
		imgData, err := os.Open(uploadedImagePath)
		if err != nil {
			return err
		}

		expected, err := ioutil.ReadFile(uploadedImagePath)
		if err != nil {
			return err
		}
		task := &CreatePicTask{
			FileData: imgData,
		}

		var destBuffer bytes.Buffer
		var p Pic

		if err := task.moveUploadedFile(&destBuffer, &p); err != nil {
			return err
		}
		if res := destBuffer.String(); res != string(expected) {
			t.Fatal("String data not moved: ", res)
		}
		if int(p.FileSize) != len(expected) {
			t.Fatal("Filesize doesn't match", p.FileSize)
		}
		return nil
	}(); err != nil {
		t.Fatal(err)
	}
}
<commit_msg>Re enable test<commit_after>package pixur

import (
	"bytes"
	"database/sql"
	"fmt"
	"image"
	"image/gif"
	"io/ioutil"
	"os"
	"testing"

	ptest "pixur.org/pixur/testing"
)

var (
	pixPath           string
	uploadedImagePath string
	uploadedImageSize int64
)

type container struct {
	t  *testing.T
	db *sql.DB
}

func (c *container) mustFindTagByName(name string) *Tag {
	tag, err := c.findTagByName(name)
	if err != nil {
		c.t.Fatal(err)
	}

	return tag
}

func (c *container) findTagByName(name string) (*Tag, error) {
	tx, err := c.db.Begin()
	if err != nil {
		c.t.Fatal(err)
	}
	defer tx.Rollback()

	t, err := findTagByName(name, tx)
	return t, err
}

func (c *container) createTag(name string) *Tag {
	tag := &Tag{
		Name: name,
	}
	tx, err := c.db.Begin()
	if err != nil {
		c.t.Fatal(err)
	}
	defer tx.Rollback()

	if tag, err := findTagByName(name, tx); err == nil {
		return tag
	}

	if err := tag.Insert(tx); err != nil {
		c.t.Fatal(err)
	}
	if err := tx.Commit(); err != nil {
		c.t.Fatal(err)
	}

	return tag
}

func (c *container) createTagExp(name string) *Tag {
	tag := &Tag{
		Name: name,
	}
	tx, err := c.db.Begin()
	if err != nil {
		c.t.Fatal(err)
	}
	defer tx.Rollback()

	tags, err := findTags(tx, "SELECT * FROM tags WHERE name = ? FOR UPDATE;", name)
	if err != nil {
		c.t.Fatal(err)
	}

	if len(tags) == 0 {
		// gaplock?
		if err := tag.Insert(tx); err != nil {
			c.t.Fatal(err)
		}
		if err := tx.Commit(); err != nil {
			c.t.Fatal(err)
		}
	} else if len(tags) == 1 {

		tag = tags[0]
		tag.Count++
		if err := tag.Update(tx); err != nil {
			c.t.Fatal(err)
		}
		if err := tx.Commit(); err != nil {
			c.t.Fatal(err)
		}

	} else {
		c.t.Fatal("Too many tags!", tags)
	}
	return tag
}

func init() {
	BeforeTestSuite(func() error {
		if path, err := ioutil.TempDir("", "pixPath"); err != nil {
			return err
		} else {
			pixPath = path
		}
		AfterTestSuite(func() error {
			return os.RemoveAll(pixPath)
		})

		return nil
	})

	BeforeTestSuite(func() error {
		f, err := ioutil.TempFile(pixPath, "")
		if err != nil {
			return err
		}
		uploadedImagePath = f.Name()
		defer f.Close()
		AfterTestSuite(func() error {
			return os.RemoveAll(uploadedImagePath)
		})

		img := image.NewGray(image.Rect(0, 0, 5, 10))

		if err := gif.Encode(f, img, &gif.Options{}); err != nil {
			return err
		}
		if fi, err := f.Stat(); err != nil {
			return err
		} else {
			uploadedImageSize = fi.Size()
		}
		return nil
	})
}

func TestWorkflowFileUpload(t *testing.T) {
	if err := func() error {
		imgData, err := os.Open(uploadedImagePath)
		if err != nil {
			return err
		}
		task := &CreatePicTask{
			db:       testDB,
			pixPath:  pixPath,
			FileData: imgData,
		}
		if err := task.Run(); err != nil {
			task.Reset()
			return err
		}

		expected := Pic{
			FileSize: uploadedImageSize,
			Mime:     Mime_GIF,
			Width:    5,
			Height:   10,
		}
		actual := *task.CreatedPic

		if _, err := os.Stat(actual.Path(pixPath)); err != nil {
			return fmt.Errorf("Image was not moved: %s", err)
		}
		if _, err := os.Stat(actual.ThumbnailPath(pixPath)); err != nil {
			return fmt.Errorf("Thumbnail not created: %s", err)
		}

		// Zero out these, since they can change from test to test
		actual.Id = 0
		ptest.AssertEquals(actual.CreatedTime, actual.ModifiedTime, t)
		actual.CreatedTime = 0
		actual.ModifiedTime = 0

		ptest.AssertEquals(actual, expected, t)
		return nil
	}(); err != nil {
		t.Fatal(err)
	}
}

func _TestWorkflowAllTagsAdded(t *testing.T) {
	ctnr := &container{
		t:  t,
		db: testDB,
	}

	imgData, err := os.Open(uploadedImagePath)
	if err != nil {
		t.Fatal(err)
	}
	task := &CreatePicTask{
		db:       testDB,
		pixPath:  pixPath,
		FileData: imgData,
		TagNames: []string{"foo", "bar"},
	}
	if err := task.Run(); err != nil {
		task.Reset()
		t.Fatal(err)
	}

	fooTag := ctnr.mustFindTagByName("foo")
	barTag := ctnr.mustFindTagByName("bar")

	picTags, err := findPicTagsByPicId(task.CreatedPic.Id, testDB)
	if err != nil {
		t.Fatal(err)
	}
	if len(picTags) != 2 {
		t.Fatal(fmt.Errorf("Wrong number of pic tags", picTags))
	}
	var picTagsGroupedByName = groupPicTagsByTagName(picTags)
	if picTagsGroupedByName["foo"].TagId != fooTag.Id {
		t.Fatal(fmt.Errorf("Tag ID does not match PicTag TagId", fooTag.Id))
	}
	if picTagsGroupedByName["bar"].TagId != barTag.Id {
		t.Fatal(fmt.Errorf("Tag ID does not match PicTag TagId", barTag.Id))
	}
}

func TestWorkflowAlreadyExistingTags(t *testing.T) {
	ctnr := &container{
		t:  t,
		db: testDB,
	}
	imgData, err := os.Open(uploadedImagePath)
	if err != nil {
		t.Fatal(err)
	}

	bazTag := ctnr.createTag("baz")
	quxTag := ctnr.createTag("qux")

	task := &CreatePicTask{
		db:       testDB,
		pixPath:  pixPath,
		FileData: imgData,
		TagNames: []string{"baz", "qux"},
	}
	if err := task.Run(); err != nil {
		task.Reset()
		t.Fatal(err)
	}

	picTags, err := findPicTagsByPicId(task.CreatedPic.Id, testDB)
	if err != nil {
		t.Fatal(err)
	}
	if len(picTags) != 2 {
		t.Fatal("Wrong number of pic tags", picTags)
	}
	var picTagsGroupedByName = groupPicTagsByTagName(picTags)
	if picTagsGroupedByName["baz"].TagId != bazTag.Id {
		t.Fatal("Tag ID does not match PicTag TagId", bazTag.Id)
	}
	if picTagsGroupedByName["qux"].TagId != quxTag.Id {
		t.Fatal("Tag ID does not match PicTag TagId", quxTag.Id)
	}
}

func TestWorkflowTrimAndCollapseDuplicateTags(t *testing.T) {
	if err := func() error {
		imgData, err := os.Open(uploadedImagePath)
		if err != nil {
			return err
		}

		task := &CreatePicTask{
			db:       testDB,
			pixPath:  pixPath,
			FileData: imgData,
			// All of these are the same
			TagNames: []string{"foo", "foo", "  foo", "foo  "},
		}
		if err := task.Run(); err != nil {
			task.Reset()
			return err
		}

		tx, err := testDB.Begin()
		if err != nil {
			return err
		}
		fooTag, err := findTagByName("foo", tx)
		if err != nil {
			return err
		}

		picTags, err := findPicTagsByPicId(task.CreatedPic.Id, testDB)
		if err != nil {
			return err
		}
		if len(picTags) != 1 {
			return fmt.Errorf("Wrong number of pic tags", picTags)
		}
		if picTags[0].TagId != fooTag.Id {
			return fmt.Errorf("Tag ID does not match PicTag TagId", fooTag.Id)
		}
		return nil
	}(); err != nil {
		t.Fatal(err)
	}
}

func TestCleanTagNames(t *testing.T) {
	var unclean = []string{
		"   ",
		" ", // should collapse with the above
		"",  // should also collapse"
		"a",
		"   a",
		"a   ",
		"b b",
		"c\nc",
		"pokémon",
	}
	var expected = []string{
		"a",
		"b b",
		"cc",
		"pokémon",
	}
	cleaned := cleanTagNames(unclean)
	if len(cleaned) != len(expected) {
		t.Fatal("Size mismatch", cleaned, expected)
	}
	for i, tagName := range cleaned {
		if tagName != expected[i] {
			t.Fatal("tag mismatch", cleaned, expected)
		}
	}
}

func BenchmarkCreation(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if err := func() error {
			imgData, err := os.Open(uploadedImagePath)
			if err != nil {
				return err
			}

			task := &CreatePicTask{
				db:       testDB,
				pixPath:  pixPath,
				FileData: imgData,
				TagNames: []string{"foo", "bar"},
			}
			if err := task.Run(); err != nil {
				task.Reset()
				return err
			}
			return nil
		}(); err != nil {
			b.Fatal(err)
		}
	}
}

func TestMoveUploadedFile(t *testing.T) {
	if err := func() error {
		imgData, err := os.Open(uploadedImagePath)
		if err != nil {
			return err
		}

		expected, err := ioutil.ReadFile(uploadedImagePath)
		if err != nil {
			return err
		}
		task := &CreatePicTask{
			FileData: imgData,
		}

		var destBuffer bytes.Buffer
		var p Pic

		if err := task.moveUploadedFile(&destBuffer, &p); err != nil {
			return err
		}
		if res := destBuffer.String(); res != string(expected) {
			t.Fatal("String data not moved: ", res)
		}
		if int(p.FileSize) != len(expected) {
			t.Fatal("Filesize doesn't match", p.FileSize)
		}
		return nil
	}(); err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package irc_test

import (
	. "github.com/jriddick/geoffrey/irc"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Irc", func() {
	var (
		client *IRC
		cfg    Config
		emp    Config
	)

	BeforeEach(func() {
		cfg = Config{
			Hostname:           "localhost",
			Port:               6697,
			Secure:             false,
			InsecureSkipVerify: false,
		}
		emp = Config{}
		client = NewIRC(cfg)
	})

	AfterEach(func() {
		client.Disconnect()
	})

	It("should be able to create an irc client", func() {
		Expect(NewIRC(cfg)).NotTo(BeNil())
	})

	It("should be able to connect", func() {
		Expect(client.Connect()).NotTo(HaveOccurred())
	})

	It("should not be able to connect with an empty configuration", func() {
		Expect(NewIRC(emp).Connect()).To(HaveOccurred())
	})

	It("should be able to read from the server", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("getting the reader")
		reader := client.Reader()
		Expect(reader).NotTo(BeNil())

		msg := <-reader
		Expect(msg).NotTo(BeNil())
		Expect(msg.String()).NotTo(BeEmpty())

		close(done)
	}, 5)

	It("should be able to register to the server", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("getting the reader and writer")
		reader := client.Reader()
		Expect(reader).NotTo(BeNil())
		writer := client.Writer()
		Expect(writer).NotTo(BeNil())

		By("sending nick and user")
		writer <- "NICK geoffrey"
		writer <- "USER geoffrey 0 * :geoffrey"

		for {
			line := <-reader

			if line.Command == RPL_WELCOME {
				break
			}
		}

		close(done)
	}, 5)

	It("should be able to reconnect to the server", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("reading from the server")
		Expect(<-client.Reader()).NotTo(BeNil())

		By("reconnecting")
		Expect(client.Reconnect()).NotTo(HaveOccurred())

		By("reading from the server")
		Expect(<-client.Reader()).NotTo(BeNil())

		close(done)
	}, 5)

	It("should not be able to send empty messages", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("sending an empty message")
		client.Writer() <- ""

		Expect(<-client.Errors()).NotTo(BeNil())

		close(done)
	}, 5)
})
<commit_msg>check for nil in registration test case<commit_after>package irc_test

import (
	. "github.com/jriddick/geoffrey/irc"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Irc", func() {
	var (
		client *IRC
		cfg    Config
		emp    Config
	)

	BeforeEach(func() {
		cfg = Config{
			Hostname:           "localhost",
			Port:               6697,
			Secure:             false,
			InsecureSkipVerify: false,
		}
		emp = Config{}
		client = NewIRC(cfg)
	})

	AfterEach(func() {
		client.Disconnect()
	})

	It("should be able to create an irc client", func() {
		Expect(NewIRC(cfg)).NotTo(BeNil())
	})

	It("should be able to connect", func() {
		Expect(client.Connect()).NotTo(HaveOccurred())
	})

	It("should not be able to connect with an empty configuration", func() {
		Expect(NewIRC(emp).Connect()).To(HaveOccurred())
	})

	It("should be able to read from the server", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("getting the reader")
		reader := client.Reader()
		Expect(reader).NotTo(BeNil())

		msg := <-reader
		Expect(msg).NotTo(BeNil())
		Expect(msg.String()).NotTo(BeEmpty())

		close(done)
	}, 5)

	It("should be able to register to the server", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("getting the reader and writer")
		reader := client.Reader()
		Expect(reader).NotTo(BeNil())
		writer := client.Writer()
		Expect(writer).NotTo(BeNil())

		By("sending nick and user")
		writer <- "NICK geoffrey"
		writer <- "USER geoffrey 0 * :geoffrey"

		for {
			line := <-reader

			if line != nil && line.Command == RPL_WELCOME {
				break
			}
		}

		close(done)
	}, 5)

	It("should be able to reconnect to the server", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("reading from the server")
		Expect(<-client.Reader()).NotTo(BeNil())

		By("reconnecting")
		Expect(client.Reconnect()).NotTo(HaveOccurred())

		By("reading from the server")
		Expect(<-client.Reader()).NotTo(BeNil())

		close(done)
	}, 5)

	It("should not be able to send empty messages", func(done Done) {
		By("connecting to the server")
		Expect(client.Connect()).NotTo(HaveOccurred())

		By("sending an empty message")
		client.Writer() <- ""

		Expect(<-client.Errors()).NotTo(BeNil())

		close(done)
	}, 5)
})
<|endoftext|>


<commit_before>package qoutes

import (
	"errors"
	"net/http"
	"strconv"
	"time"

	"github.com/labstack/echo"
	"github.com/shamsher31/stay-motivated-server/db"
	"github.com/shamsher31/stay-motivated-server/utils"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type StatusType int

const (
	PENDING StatusType = iota
	APPROVED
	REJECTED
)

var ErrInvalidStatusType = errors.New("Invalid StatusType")

// Quote defines structure of quote
type Quote struct {
	ID        bson.ObjectId `json:"-" bson:"_id,omitempty"`
	Title     string        `json:"title" bson:"title"`
	Author    string        `json:"author" bson:"author,omitempty"`
	Status    StatusType    `json:"status" bson:"status"`
	Tag       []string      `json:"tag" bson:"tag"`
	Timestamp time.Time     `json:"timestamp" bson:"timestamp"`
}

func CreateQoute(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	title := c.FormValue("title")
	author := c.FormValue("author")

	id := db.GenerateID()
	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Insert(&Quote{
		ID:        id,
		Title:     title,
		Author:    author,
		Status:    PENDING,
		Timestamp: time.Now(),
	})

	utils.CheckError(err)

	return c.JSON(http.StatusOK, id)
}

func GetAllQoutes(c echo.Context) error {

	var results []Quote

	session := db.ConnectDB()
	defer session.Close()

	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Find(bson.M{}).One(&results)

	utils.CheckError(err)
	return c.JSON(http.StatusOK, results)
}

func GetQoute(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	result := Quote{}
	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Find(bson.M{}).One(&result)

	utils.CheckError(err)

	return c.JSON(http.StatusOK, result)
}

func UpdateQoute(c echo.Context) error {
	session := db.ConnectDB()
	defer session.Close()

	id := db.GetHexID(c.Param("id"))

	var qoute Quote

	qoutes := db.GetCollection(session, "qoutes")

	change := mgo.Change{
		Update: bson.M{"$set": bson.M{
			"title":  c.FormValue("title"),
			"author": c.FormValue("author"),
		}},
		ReturnNew: true,
	}

	info, err := qoutes.Find(bson.M{"_id": id}).Apply(change, &qoute)

	utils.CheckError(err)

	return c.JSON(http.StatusOK, info)
}

func DeleteQoute(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	id := db.GetHexID(c.Param("id"))

	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Remove(bson.M{"_id": id})

	utils.CheckError(err)

	return c.JSON(http.StatusOK, qoutes)

}

func UpdateStatus(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	id := db.GetHexID(c.Param("id"))
	status, err := ValidateStatusType(c.Param("status"))

	utils.CheckError(err)

	qoutes := db.GetCollection(session, "qoutes")
	err = qoutes.Update(
		bson.M{"_id": id},
		bson.M{"$set": bson.M{"status": status}})

	utils.CheckError(err)

	return c.JSON(http.StatusOK, id)
}

func ValidateStatusType(status string) (int, error) {
	i, err := strconv.Atoi(string(status))

	utils.CheckError(err)

	v := StatusType(i)

	if v < PENDING || v > REJECTED {
		return 0, ErrInvalidStatusType
	}

	return i, nil
}
<commit_msg>Use custome type StatusType as a return value<commit_after>package qoutes

import (
	"errors"
	"net/http"
	"strconv"
	"time"

	"github.com/labstack/echo"
	"github.com/shamsher31/stay-motivated-server/db"
	"github.com/shamsher31/stay-motivated-server/utils"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type StatusType int

const (
	PENDING StatusType = iota
	APPROVED
	REJECTED
)

var ErrInvalidStatusType = errors.New("Invalid StatusType")

// Quote defines structure of quote
type Quote struct {
	ID        bson.ObjectId `json:"-" bson:"_id,omitempty"`
	Title     string        `json:"title" bson:"title"`
	Author    string        `json:"author" bson:"author,omitempty"`
	Status    StatusType    `json:"status" bson:"status"`
	Tag       []string      `json:"tag" bson:"tag"`
	Timestamp time.Time     `json:"timestamp" bson:"timestamp"`
}

func CreateQoute(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	title := c.FormValue("title")
	author := c.FormValue("author")

	id := db.GenerateID()
	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Insert(&Quote{
		ID:        id,
		Title:     title,
		Author:    author,
		Status:    PENDING,
		Timestamp: time.Now(),
	})

	utils.CheckError(err)

	return c.JSON(http.StatusOK, id)
}

func GetAllQoutes(c echo.Context) error {

	var results []Quote

	session := db.ConnectDB()
	defer session.Close()

	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Find(bson.M{}).One(&results)

	utils.CheckError(err)
	return c.JSON(http.StatusOK, results)
}

func GetQoute(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	result := Quote{}
	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Find(bson.M{}).One(&result)

	utils.CheckError(err)

	return c.JSON(http.StatusOK, result)
}

func UpdateQoute(c echo.Context) error {
	session := db.ConnectDB()
	defer session.Close()

	id := db.GetHexID(c.Param("id"))

	var qoute Quote

	qoutes := db.GetCollection(session, "qoutes")

	change := mgo.Change{
		Update: bson.M{"$set": bson.M{
			"title":  c.FormValue("title"),
			"author": c.FormValue("author"),
		}},
		ReturnNew: true,
	}

	info, err := qoutes.Find(bson.M{"_id": id}).Apply(change, &qoute)

	utils.CheckError(err)

	return c.JSON(http.StatusOK, info)
}

func DeleteQoute(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	id := db.GetHexID(c.Param("id"))

	qoutes := db.GetCollection(session, "qoutes")
	err := qoutes.Remove(bson.M{"_id": id})

	utils.CheckError(err)

	return c.JSON(http.StatusOK, qoutes)

}

func UpdateStatus(c echo.Context) error {

	session := db.ConnectDB()
	defer session.Close()

	id := db.GetHexID(c.Param("id"))
	status, err := ValidateStatusType(c.Param("status"))

	utils.CheckError(err)

	qoutes := db.GetCollection(session, "qoutes")
	err = qoutes.Update(
		bson.M{"_id": id},
		bson.M{"$set": bson.M{"status": status}})

	utils.CheckError(err)

	return c.JSON(http.StatusOK, id)
}

func ValidateStatusType(status string) (StatusType, error) {
	i, err := strconv.Atoi(string(status))

	utils.CheckError(err)

	v := StatusType(i)

	if v < PENDING || v > REJECTED {
		return 0, ErrInvalidStatusType
	}

	return v, nil
}
<|endoftext|>


<commit_before>package lib

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"
)

type CompileResponse struct {
	Errors string
	Events []map[string]interface{}
}

func (c CompileResponse) Message() interface{} {

	for i := 0; i < len(c.Events); i++ {
		for k, v := range c.Events[i] {
			if k == "Message" {
				return v
			}
		}
	}
	return nil

}

func ParseCompileResponse(data []byte) (CompileResponse, error) {
	var cr CompileResponse
	err := json.Unmarshal(data, &cr)
	if err != nil {
		return cr, err
	}
	return cr, nil
}

func Compile(body string) ([]byte, error) {

	resp, err := http.PostForm("http://golang.org/compile",
		url.Values{"version": {"2"}, "body": {body}})

	if err != nil {
		return nil, err
	}
	data, err := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if err != nil {
		return nil, err
	}
	return data, nil
}
<commit_msg>edit(compile): add user agent header<commit_after>package lib

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"
)

type CompileResponse struct {
	Errors string
	Events []map[string]interface{}
}

func (c CompileResponse) Message() interface{} {

	for i := 0; i < len(c.Events); i++ {
		for k, v := range c.Events[i] {
			if k == "Message" {
				return v
			}
		}
	}
	return nil

}

func ParseCompileResponse(data []byte) (CompileResponse, error) {
	var cr CompileResponse
	err := json.Unmarshal(data, &cr)
	if err != nil {
		return cr, err
	}
	return cr, nil
}

func Compile(body string) ([]byte, error) {

	resp, err := http.PostForm("http://golang.org/compile",
		url.Values{"version": {"2"}, "body": {body}})

	resp.Header.Add("User-Agent", "Gopher-Gala-2015@julienc")

	if err != nil {
		return nil, err
	}
	data, err := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if err != nil {
		return nil, err
	}
	return data, nil
}
<|endoftext|>