<commit_before>package glacier

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/rdwilliamson/aws"
	"io/ioutil"
	"net/http"
	"time"
)

type Multipart struct {
	ArchiveDescription string
	CreationDate       time.Time
	MultipartUploadId  string
	PartSizeInBytes    uint
	VaultARN           string
}

type multipart struct {
	ArchiveDescription *string
	CreationDate       string
	MultipartUploadId  string
	PartSizeInBytes    uint
	VaultARN           string
}

type multipartList struct {
	Marker      *string
	UploadsList []multipart
}

func (c *Connection) InitiateMultipart(vault string, size uint,
	description string) (string, error) {
	request, err := http.NewRequest("POST", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads", nil)
	if err != nil {
		return "", err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	// TODO check that size is valid
	request.Header.Add("x-amz-part-size", fmt.Sprint(size))

	if description != "" {
		request.Header.Add("x-amz-archive-description", description)
	}

	err = c.Signature.Sign(request, nil, nil)
	if err != nil {
		return "", err
	}

	response, err := c.Client.Do(request)
	if err != nil {
		return "", err
	}

	if response.StatusCode != 201 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return "", err
		}
		err = response.Body.Close()
		if err != nil {
			return "", err
		}

		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return "", err
		}
		return "", e
	}

	return response.Header.Get("x-amz-multipart-upload-id"), nil
}

// reader or []byte?
func (c *Connection) UploadMultipart(vault, uploadId string, start uint,
	data []byte) error {
	// TODO check that data size and start location make sense

	body := bytes.NewReader(data)
	request, err := http.NewRequest("PUT", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads/"+
		uploadId, body)
	if err != nil {
		return err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	request.Header.Add("Content-Range", fmt.Sprintf("bytes %d-%d/*", start,
		start+uint(len(data))-1))

	ht, hash, err := createTreeHash(body)
	if err != nil {
		return err
	}
	request.Header.Add("x-amz-content-sha256", string(toHex(hash)))
	request.Header.Add("x-amz-sha256-tree-hash", string(toHex(ht.hash[:])))

	err = c.Signature.Sign(request, nil, hash)
	if err != nil {
		return err
	}

	request.ContentLength, err = body.Seek(0, 2)
	if err != nil {
		return err
	}
	_, err = body.Seek(0, 0)
	if err != nil {
		return err
	}

	response, err := c.Client.Do(request)
	if err != nil {
		return err
	}

	if response.StatusCode != 204 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return err
		}
		err = response.Body.Close()
		if err != nil {
			return err
		}
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return err
		}
		return e
	}

	return nil
}

func (c *Connection) CompleteMultipart(vault, uploadId, treeHash string, size uint) (string, error) {
	request, err := http.NewRequest("POST", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads/"+
		uploadId, nil)
	if err != nil {
		return "", err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	request.Header.Add("x-amz-sha256-tree-hash", treeHash)
	request.Header.Add("x-amz-archive-size", fmt.Sprint(size))

	err = c.Signature.Sign(request, nil, nil)
	if err != nil {
		return "", err
	}

	response, err := c.Client.Do(request)
	if err != nil {
		return "", err
	}

	if response.StatusCode != 201 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return "", err
		}
		response.Body.Close()
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return "", err
		}
		return "", e
	}

	return response.Header.Get("x-amz-archive-id"), nil
}

func (c *Connection) AbortMultipart(vault, uploadId string) error {
	request, err := http.NewRequest("DELETE", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads/"+
		uploadId, nil)
	if err != nil {
		return err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	c.Signature.Sign(request, nil, nil)

	response, err := c.Client.Do(request)
	if err != nil {
		return err
	}

	if response.StatusCode != 204 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return err
		}
		response.Body.Close()
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return err
		}
		return e
	}

	return nil
}

func (c *Connection) ListMultipartParts() error {
	return nil
}

func (c *Connection) ListMultipartUploads(vault, marker string, limit int) ([]Multipart, string, error) {
	request, err := http.NewRequest("GET", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads",
		nil)
	if err != nil {
		return nil, "", err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	// TODO validate limit
	if limit > 0 {
		request.Header.Add("limit", fmt.Sprint(limit))
	}
	if marker != "" {
		request.Header.Add("marker", marker)
	}

	c.Signature.Sign(request, nil, nil)

	response, err := c.Client.Do(request)
	if err != nil {
		return nil, "", err
	}

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, "", err
	}
	err1 := response.Body.Close()

	if response.StatusCode != 200 {
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return nil, "", err
		}
		return nil, "", &e
	}

	var list multipartList
	err = json.Unmarshal(body, &list)
	if err != nil {
		return nil, "", err
	}

	parts := make([]Multipart, len(list.UploadsList))
	for i, v := range list.UploadsList {
		if v.ArchiveDescription != nil {
			parts[i].ArchiveDescription = *v.ArchiveDescription
		}
		parts[i].CreationDate, err = time.Parse(time.RFC3339, v.CreationDate)
		if err != nil && err1 == nil {
			err1 = err
		}
		parts[i].MultipartUploadId = v.MultipartUploadId
		parts[i].PartSizeInBytes = v.PartSizeInBytes
		parts[i].VaultARN = v.VaultARN
	}

	var m string
	if list.Marker != nil {
		m = *list.Marker
	}

	return parts, m, nil
}
<commit_msg>Uploading a multipart now takes a reader.<commit_after>package glacier

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/rdwilliamson/aws"
	"io/ioutil"
	"net/http"
	"time"
)

type Multipart struct {
	ArchiveDescription string
	CreationDate       time.Time
	MultipartUploadId  string
	PartSizeInBytes    uint
	VaultARN           string
}

type multipart struct {
	ArchiveDescription *string
	CreationDate       string
	MultipartUploadId  string
	PartSizeInBytes    uint
	VaultARN           string
}

type multipartList struct {
	Marker      *string
	UploadsList []multipart
}

func (c *Connection) InitiateMultipart(vault string, size uint,
	description string) (string, error) {
	request, err := http.NewRequest("POST", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads", nil)
	if err != nil {
		return "", err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	// TODO check that size is valid
	request.Header.Add("x-amz-part-size", fmt.Sprint(size))

	if description != "" {
		request.Header.Add("x-amz-archive-description", description)
	}

	err = c.Signature.Sign(request, nil, nil)
	if err != nil {
		return "", err
	}

	response, err := c.Client.Do(request)
	if err != nil {
		return "", err
	}

	if response.StatusCode != 201 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return "", err
		}
		err = response.Body.Close()
		if err != nil {
			return "", err
		}

		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return "", err
		}
		return "", e
	}

	return response.Header.Get("x-amz-multipart-upload-id"), nil
}

func (c *Connection) UploadMultipart(vault, uploadId string, start int64, body io.ReadSeeker) error {
	// TODO check that data size and start location make sense

	request, err := http.NewRequest("PUT", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads/"+
		uploadId, body)
	if err != nil {
		return err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	th := NewTreeHash()
	n, err := io.Copy(th, body)
	if err != nil {
		return err
	}
	th.Close()

	_, err = body.Seek(0, 0)
	if err != nil {
		return err
	}

	response, err := c.Client.Do(request)
	if err != nil {
		return err
	}

	if response.StatusCode != 204 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return err
		}
		err = response.Body.Close()
		if err != nil {
			return err
		}
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return err
		}
		return e
	}

	return nil
}

func (c *Connection) CompleteMultipart(vault, uploadId, treeHash string, size uint) (string, error) {
	request, err := http.NewRequest("POST", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads/"+
		uploadId, nil)
	if err != nil {
		return "", err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	request.Header.Add("x-amz-sha256-tree-hash", treeHash)
	request.Header.Add("x-amz-archive-size", fmt.Sprint(size))

	err = c.Signature.Sign(request, nil, nil)
	if err != nil {
		return "", err
	}

	request.Header.Add("x-amz-content-sha256", th.Hash())
	request.Header.Add("x-amz-sha256-tree-hash", th.TreeHash())
	request.Header.Add("Content-Range", fmt.Sprintf("bytes %d-%d/*", start, start+n-1))
	request.ContentLength = n

	c.Signature.Sign(request, nil, th.HashBytes())

	response, err := c.Client.Do(request)
	if err != nil {
		return "", err
	}

	if response.StatusCode != 201 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return "", err
		}
		response.Body.Close()
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return "", err
		}
		return "", e
	}

	return response.Header.Get("x-amz-archive-id"), nil
}

func (c *Connection) AbortMultipart(vault, uploadId string) error {
	request, err := http.NewRequest("DELETE", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads/"+
		uploadId, nil)
	if err != nil {
		return err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	c.Signature.Sign(request, nil, nil)

	response, err := c.Client.Do(request)
	if err != nil {
		return err
	}

	if response.StatusCode != 204 {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return err
		}
		response.Body.Close()
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return err
		}
		return e
	}

	return nil
}

func (c *Connection) ListMultipartParts() error {
	return nil
}

func (c *Connection) ListMultipartUploads(vault, marker string, limit int) ([]Multipart, string, error) {
	request, err := http.NewRequest("GET", "https://"+
		c.Signature.Region.Glacier+"/-/vaults/"+vault+"/multipart-uploads",
		nil)
	if err != nil {
		return nil, "", err
	}
	request.Header.Add("x-amz-glacier-version", "2012-06-01")

	// TODO validate limit
	if limit > 0 {
		request.Header.Add("limit", fmt.Sprint(limit))
	}
	if marker != "" {
		request.Header.Add("marker", marker)
	}

	c.Signature.Sign(request, nil, nil)

	response, err := c.Client.Do(request)
	if err != nil {
		return nil, "", err
	}

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, "", err
	}
	err1 := response.Body.Close()

	if response.StatusCode != 200 {
		var e aws.Error
		err = json.Unmarshal(body, &e)
		if err != nil {
			return nil, "", err
		}
		return nil, "", &e
	}

	var list multipartList
	err = json.Unmarshal(body, &list)
	if err != nil {
		return nil, "", err
	}

	parts := make([]Multipart, len(list.UploadsList))
	for i, v := range list.UploadsList {
		if v.ArchiveDescription != nil {
			parts[i].ArchiveDescription = *v.ArchiveDescription
		}
		parts[i].CreationDate, err = time.Parse(time.RFC3339, v.CreationDate)
		if err != nil && err1 == nil {
			err1 = err
		}
		parts[i].MultipartUploadId = v.MultipartUploadId
		parts[i].PartSizeInBytes = v.PartSizeInBytes
		parts[i].VaultARN = v.VaultARN
	}

	var m string
	if list.Marker != nil {
		m = *list.Marker
	}

	return parts, m, nil
}
<|endoftext|>


<commit_before>package antibody

import (
	"io"
	"io/ioutil"
	"os"
	"strings"
)

func DoBundle(bundle string, home string) {
	NewAntibody([]Bundle{NewGitBundle(bundle, home)}).Download()
}

func ProcessStdin(stdin io.Reader, home string) {
	entries, _ := ioutil.ReadAll(stdin)
	bundles := make([]Bundle, 0)
	for _, bundle := range strings.Split(string(entries), "\n") {
		if bundle == "" {
			continue
		}
		bundles = append(bundles, NewGitBundle(bundle, home))
	}
	NewAntibody(bundles).Download()
}

func Update(home string) {
	entries, _ := ioutil.ReadDir(home)
	bundles := make([]Bundle, 0)
	for _, bundle := range entries {
		if bundle.Mode().IsDir() && bundle.Name()[0] != '.' {
			bundles = append(bundles, NewGitBundle(bundle.Name(), home))
		}
	}
	NewAntibody(bundles).Update()
}

func ProcessArgs(args []string, home string) {
	cmd := args[0]
	if cmd == "update" {
		Update(home)
	} else if cmd == "bundle" {
		DoBundle(args[1], home)
	} else {
		panic("Invalid command: " + cmd)
	}
}

func ReadStdin() bool {
	stat, _ := os.Stdin.Stat()
	return (stat.Mode() & os.ModeCharDevice) == 0
}

func Home() string {
	home := os.Getenv("ANTIBODY_HOME")
	if home == "" {
		home = os.Getenv("HOME") + "/.antibody/"
	} else {
		if !strings.HasSuffix(home, "/") {
			home += "/"
		}
	}
	return home
}
<commit_msg>faster slice<commit_after>package antibody

import (
	"io"
	"io/ioutil"
	"os"
	"strings"
)

func DoBundle(bundle string, home string) {
	NewAntibody([]Bundle{NewGitBundle(bundle, home)}).Download()
}

func ProcessStdin(stdin io.Reader, home string) {
	entries, _ := ioutil.ReadAll(stdin)
	bundles := make([]Bundle, 0)
	for _, bundle := range strings.Split(string(entries), "\n") {
		if bundle == "" {
			continue
		}
		bundles = append(bundles, NewGitBundle(bundle, home))
	}
	NewAntibody(bundles).Download()
}

func Update(home string) {
	entries, _ := ioutil.ReadDir(home)
	var bundles []Bundle
	for _, bundle := range entries {
		if bundle.Mode().IsDir() && bundle.Name()[0] != '.' {
			bundles = append(bundles, NewGitBundle(bundle.Name(), home))
		}
	}
	NewAntibody(bundles).Update()
}

func ProcessArgs(args []string, home string) {
	cmd := args[0]
	if cmd == "update" {
		Update(home)
	} else if cmd == "bundle" {
		DoBundle(args[1], home)
	} else {
		panic("Invalid command: " + cmd)
	}
}

func ReadStdin() bool {
	stat, _ := os.Stdin.Stat()
	return (stat.Mode() & os.ModeCharDevice) == 0
}

func Home() string {
	home := os.Getenv("ANTIBODY_HOME")
	if home == "" {
		home = os.Getenv("HOME") + "/.antibody/"
	} else {
		if !strings.HasSuffix(home, "/") {
			home += "/"
		}
	}
	return home
}
<|endoftext|>


<commit_before>package helpers

import "reflect"

// Resolves the type of $v as a string
func Typeof(v interface{}) string {
    t := reflect.TypeOf(v)

    if t.Kind() == reflect.Ptr {
        return "*" + t.Elem().Name()
    } else {
        return t.Name()
    }
}
<commit_msg>Add type helpers<commit_after>package helpers

import "reflect"

// Resolves the type of $v as a string
func Typeof(v interface{}) string {
    t := reflect.TypeOf(v)

    if t.Kind() == reflect.Ptr {
        return "*" + t.Elem().Name()
    } else {
        return t.Name()
    }
}

func MapToSliceOfSlices(m map[string]string) [][]string {
    res := make([][]string, len(m))

    for idx := range res {
        for key, val := range m {
            res[idx] = append(res[idx], key)
            res[idx] = append(res[idx], val)
        }
    }

    return res
}
<|endoftext|>


<commit_before>package main

import (
	"dns"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func q(w dns.RequestWriter, m *dns.Msg) {
	w.Send(m)
	r, err := w.Receive()
	if err != nil {
		fmt.Printf("%s\n", err.Error())
	}
	w.Write(r)
}

func main() {
	dnssec := flag.Bool("dnssec", false, "request DNSSEC records")
	query := flag.Bool("question", false, "show question")
	short := flag.Bool("short", false, "abbreviate long DNSKEY and RRSIG RRs")
	port := flag.Int("port", 53, "port number to use")
	aa := flag.Bool("aa", false, "set AA flag in query")
	ad := flag.Bool("ad", false, "set AD flag in query")
	cd := flag.Bool("cd", false, "set CD flag in query")
	rd := flag.Bool("rd", true, "unset RD flag in query")
	tcp := flag.Bool("tcp", false, "TCP mode")
	nsid := flag.Bool("nsid", false, "ask for NSID")
	fp := flag.Bool("fp", false, "enable server detection")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		if k, ok := dns.Str_rr[strings.ToUpper(flag.Arg(i))]; ok {
			qtype = k
			continue Flags
		}
		// If it looks like a class, it is a class
		if k, ok := dns.Str_class[strings.ToUpper(flag.Arg(i))]; ok {
			qclass = k
			continue Flags
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)

	// ipv6 todo
	// We use the async query handling, just to show how
	// it is to be used.
	dns.HandleQueryFunc(".", q)
	dns.ListenAndQuery(nil, nil)
	c := dns.NewClient()
	if *tcp {
		c.Net = "tcp"
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec || *nsid {
		o := new(dns.RR_OPT)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		if *dnssec {
			o.SetDo()
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *nsid {
			o.SetNsid("")
		}
		m.Extra = append(m.Extra, o)
		//m.SetEdns0(dns.DefaultMsgSize, true)
	}

	if *fp {
		startParse(nameserver)
		return
	}
	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s\n", msgToFingerprint(m))
			fmt.Printf("%s\n", m.String())
		}
		c.Do(m, nameserver)
	}

	i := 0
forever:
	for {
		select {
		case r := <-dns.DefaultReplyChan:
			if r.Reply != nil {
				if r.Reply.Rcode == dns.RcodeSuccess {
					if r.Request.Id != r.Reply.Id {
						fmt.Printf("Id mismatch\n")
					}
				}
				if *short {
					r.Reply = shortMsg(r.Reply)
				}
				if *fp {
					fmt.Printf("%s\n", msgToFingerprint(r.Reply))
				}
				fmt.Printf("%v", r.Reply)
			}
			i++
			if i == len(qname) {
				break forever
			}
		}
	}
}

// Walk trough message and short Key data and Sig data
func shortMsg(in *dns.Msg) *dns.Msg {
	for i := 0; i < len(in.Answer); i++ {
		in.Answer[i] = shortRR(in.Answer[i])
	}
	for i := 0; i < len(in.Ns); i++ {
		in.Ns[i] = shortRR(in.Ns[i])
	}
	for i := 0; i < len(in.Extra); i++ {
		in.Extra[i] = shortRR(in.Extra[i])
	}
	return in
}

func shortRR(r dns.RR) dns.RR {
	switch t := r.(type) {
	case *dns.RR_DS:
		t.Digest = "..."
	case *dns.RR_DNSKEY:
		t.PublicKey = "..."
	case *dns.RR_RRSIG:
		t.Signature = "..."
		t.Inception = 0 // For easy grepping
		t.Expiration = 0
	case *dns.RR_NSEC3:
		t.Salt = "-" // Nobody cares
		if len(t.TypeBitMap) > 5 {
			t.TypeBitMap = t.TypeBitMap[1:5]
		}
	}
	return r
}
<commit_msg>Prepare a new feature in key<commit_after>package main

import (
	"dns"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func q(w dns.RequestWriter, m *dns.Msg) {
	w.Send(m)
	r, err := w.Receive()
	if err != nil {
		fmt.Printf("%s\n", err.Error())
	}
	w.Write(r)
}

func main() {
	dnssec := flag.Bool("dnssec", false, "request DNSSEC records")
	query := flag.Bool("question", false, "show question")
	short := flag.Bool("short", false, "abbreviate long DNSKEY and RRSIG RRs")
        check := flag.Bool("check", false, "check internal DNSSEC consistency")
	port := flag.Int("port", 53, "port number to use")
	aa := flag.Bool("aa", false, "set AA flag in query")
	ad := flag.Bool("ad", false, "set AD flag in query")
	cd := flag.Bool("cd", false, "set CD flag in query")
	rd := flag.Bool("rd", true, "unset RD flag in query")
	tcp := flag.Bool("tcp", false, "TCP mode")
	nsid := flag.Bool("nsid", false, "ask for NSID")
	fp := flag.Bool("fp", false, "enable server detection")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		if k, ok := dns.Str_rr[strings.ToUpper(flag.Arg(i))]; ok {
			qtype = k
			continue Flags
		}
		// If it looks like a class, it is a class
		if k, ok := dns.Str_class[strings.ToUpper(flag.Arg(i))]; ok {
			qclass = k
			continue Flags
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)

	// ipv6 todo
	// We use the async query handling, just to show how
	// it is to be used.
	dns.HandleQueryFunc(".", q)
	dns.ListenAndQuery(nil, nil)
	c := dns.NewClient()
	if *tcp {
		c.Net = "tcp"
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec || *nsid {
		o := new(dns.RR_OPT)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		if *dnssec {
			o.SetDo()
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *nsid {
			o.SetNsid("")
		}
		m.Extra = append(m.Extra, o)
	}

	if *fp {
		startParse(nameserver)
		return
	}
	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s\n", msgToFingerprint(m))
			fmt.Printf("%s\n", m.String())
		}
		c.Do(m, nameserver)
	}

	i := 0
forever:
	for {
		select {
		case r := <-dns.DefaultReplyChan:
			if r.Reply != nil {
				if r.Reply.Rcode == dns.RcodeSuccess {
					if r.Request.Id != r.Reply.Id {
						fmt.Printf("Id mismatch\n")
					}
				}
				if *short {
					r.Reply = shortMsg(r.Reply)
				}
                                if *check {
                                        // Get the signatures from the message
                                        // Get the keys mentioned from the internet
                                        // Validate it

                                }
				fmt.Printf("%v", r.Reply)
			}
			i++
			if i == len(qname) {
				break forever
			}
		}
	}
}

// Walk trough message and short Key data and Sig data
func shortMsg(in *dns.Msg) *dns.Msg {
	for i := 0; i < len(in.Answer); i++ {
		in.Answer[i] = shortRR(in.Answer[i])
	}
	for i := 0; i < len(in.Ns); i++ {
		in.Ns[i] = shortRR(in.Ns[i])
	}
	for i := 0; i < len(in.Extra); i++ {
		in.Extra[i] = shortRR(in.Extra[i])
	}
	return in
}

func shortRR(r dns.RR) dns.RR {
	switch t := r.(type) {
	case *dns.RR_DS:
		t.Digest = "..."
	case *dns.RR_DNSKEY:
		t.PublicKey = "..."
	case *dns.RR_RRSIG:
		t.Signature = "..."
		t.Inception = 0 // For easy grepping
		t.Expiration = 0
	case *dns.RR_NSEC3:
		t.Salt = "-" // Nobody cares
		if len(t.TypeBitMap) > 5 {
			t.TypeBitMap = t.TypeBitMap[1:5]
		}
	}
	return r
}
<|endoftext|>


<commit_before>package tuplespace

import (
	"reflect"
	"testing"
)

var testTupleTwoFields Tuple
var testTupleFourFields Tuple

func init() {
	// Create simple tuple with four fields.
	testTupleTwoFields = CreateTuple("Field 1", true)
	testTupleFourFields = CreateTuple("Field1", 2, 3.3, false)
}

// Test to see if tuple is creating correct.
func TestCreateTuple(t *testing.T) {
	// Create tuple with different kind of types, manually.
	fields := make([]interface{}, 4)
	fields[0] = "Field1"
	fields[1] = 2
	fields[2] = 3.3
	fields[3] = false
	var testTuple = Tuple{fields}

	// Test the manually created tuple against the tuple created by the method.
	if !reflect.DeepEqual(testTuple, testTupleFourFields) {
		t.Errorf("CreateTuple() gave %q, should be %q", testTupleFourFields, testTuple)
	}
}

// Test to see if tuple has correct length.
func TestTupleLength(t *testing.T) {
	// Create tuple with same length as defined by variable.
	var tupleLength = 4
	var testTuple = CreateTuple("Field1", 2, 3.3, false)
	testTupleLength := testTuple.Length()
	if tupleLength != testTupleLength {
		t.Errorf("Length(%q) == %q, should be %q", testTuple, testTupleLength, tupleLength)
	}
}

// Test to see if the correct tuple field is returned.
func TestTupleGetFieldAt(t *testing.T) {
	var wantedField = 2
	var testTuple = CreateTuple("Field1", 2, 3.3, false)
	tupleField := testTuple.GetFieldAt(1)
	if wantedField != tupleField {
		t.Errorf("GetFieldAt(%q) == %q, should be %q", testTuple, tupleField, wantedField)
	}
}

// Test to see if the correct tuple field is set.
func TestSetFieldAt(t *testing.T) {
	newField := "val"

	var testTuple = CreateTuple("Field1", 2, 3.3, false)
	testTuple.SetFieldAt(1, newField)

	newTupleField := testTuple.GetFieldAt(1)

	if newField != newTupleField {
		t.Errorf("SetFieldAt(%d, %q) == %q, should be %q", 1, newField, newTupleField, newField)
	}
}

func TestMatchSameLengthAndMatchingNumberOfFields(t *testing.T) {
	var testTemplate = CreateTemplate("Field1", 2, 3.3, false)
	var testTuple = CreateTuple("Field1", 2, 3.3, false)

	if !testTuple.match(testTemplate) {
		t.Errorf("TestMatchSameLengthAndMatchingNumberOfFields should be true")
	}
}

func TestMatchSameLengthNotMatchingNumberOfFields(t *testing.T) {
	var testTemplate = CreateTemplate("Field1", 2)
	var testTuple = CreateTuple("Field1", 2, 3.3, false)

	if testTuple.match(testTemplate) {
		t.Errorf("TestMatchSameLengthNotMatchingNumberOfFields should be false")
	}
}

func TestMatchNotSameLengthAndNotMatchingNumberOfFields(t *testing.T) {
	var testTemplate = CreateTemplate("Field1", 2, 3.3, false)
	testTemplate.DontMatchNumberOfFields()
	var testTuple = CreateTuple("Field1", 2, 3.3, false)

	if !testTuple.match(testTemplate) {
		t.Errorf("TestMatchNotSameLengthAndNotMatchingNumberOfFields should be true")
	}
}

func TestMatchNotSameLengthTemplateLongerNotMatchingNumberOfFields(t *testing.T) {
	var testTemplate = CreateTemplate("Field1", 2, 3.3, false, "extra field")
	testTemplate.DontMatchNumberOfFields()
	var testTuple = CreateTuple("Field1", 2, 3.3, false)

	if testTuple.match(testTemplate) {
		t.Errorf("TestMatchNotSameLengthTemplateLongerNotMatchingNumberOfFields should be false")
	}
}

func TestMatchFieldsOfSameType(t *testing.T) {
	var testTemplate = CreateTemplate(reflect.TypeOf("string"), reflect.TypeOf(32), reflect.TypeOf(3.14), reflect.TypeOf(true))
	testTemplate.DontMatchNumberOfFields()
	var testTuple = CreateTuple("Field1", 2, 3.3, false)

	if !testTuple.matchFieldsOf(testTemplate) {
		t.Errorf("TestMatchFieldsOfSameType")
	}
}

func TestMatchFieldsOfDifferentType(t *testing.T) {
	var testTemplate = CreateTemplate(reflect.TypeOf(false))
	testTemplate.DontMatchNumberOfFields()
	var testTuple = CreateTuple("Field1", 2, 3.3, false)

	if testTuple.matchFieldsOf(testTemplate) {
		t.Errorf("TestMatchFieldsOfSameType")
	}
}
<commit_msg>Delete tuple_test.go<commit_after><|endoftext|>


<commit_before>/*
   Copyright 2017 Shlomi Noach, GitHub Inc.

   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 orcraft

import (
	"encoding/binary"

	"github.com/github/orchestrator/go/db"

	"github.com/hashicorp/raft"
)

// RelationalStoreimplements:
// - hashicorp/raft.StableStore
// - hashicorp/log.LogStore
type RelationalStore struct {
}

func NewRelationalStore() *RelationalStore {
	return &RelationalStore{}
}

func (relStore *RelationalStore) Set(key []byte, val []byte) error {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return err
	}
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	stmt, err := tx.Prepare(`delete from raft_store where store_key = ?`)
	if err != nil {
		return err
	}
	_, err = stmt.Exec(key)
	if err != nil {
		tx.Rollback()
		return err
	}
	stmt, err = tx.Prepare(`insert into raft_store (store_key, store_value) values (?, ?)`)
	if err != nil {
		tx.Rollback()
		return err
	}
	_, err = stmt.Exec(key, val)
	if err != nil {
		tx.Rollback()
		return err
	}
	err = tx.Commit()

	return err
}

// Get returns the value for key, or an empty byte slice if key was not found.
func (relStore *RelationalStore) Get(key []byte) (val []byte, err error) {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return val, err
	}
	err = db.QueryRow("select min(store_value) from raft_store where store_key = ?", key).Scan(&val)
	return val, err
}

func (relStore *RelationalStore) SetUint64(key []byte, val uint64) error {
	b := make([]byte, 8)
	binary.LittleEndian.PutUint64(b, val)

	return relStore.Set(key, b)
}

// GetUint64 returns the uint64 value for key, or 0 if key was not found.
func (relStore *RelationalStore) GetUint64(key []byte) (uint64, error) {
	b, err := relStore.Get(key)
	if err != nil {
		return 0, err
	}
	if len(b) == 0 {
		// Not found
		return 0, nil
	}
	i := binary.LittleEndian.Uint64(b)
	return i, nil
}

func (relStore *RelationalStore) FirstIndex() (idx uint64, err error) {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return idx, err
	}
	err = db.QueryRow("select ifnull(min(log_index), 0) from raft_log").Scan(&idx)
	return idx, err
}

// LastIndex returns the last index written. 0 for no entries.
func (relStore *RelationalStore) LastIndex() (idx uint64, err error) {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return idx, err
	}
	err = db.QueryRow("select ifnull(max(log_index), 0) from raft_log").Scan(&idx)
	return idx, err
}

// GetLog gets a log entry at a given index.
func (relStore *RelationalStore) GetLog(index uint64, log *raft.Log) error {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return err
	}
	err = db.QueryRow(`
    select log_index, term, log_type, data
      from raft_log
      where log_index = ?
    `, index).Scan(&log.Index, &log.Term, &log.Type, &log.Data)
	return err
}

// StoreLog stores a log entry.
func (relStore *RelationalStore) StoreLog(log *raft.Log) error {
	return relStore.StoreLogs([]*raft.Log{log})
}

// StoreLogs stores multiple log entries.
func (relStore *RelationalStore) StoreLogs(logs []*raft.Log) error {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return err
	}
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	stmt, err := tx.Prepare(`
    replace into raft_log (
      log_index, term, log_type, data
    ) values (
      ?, ?, ?, ?
    )`)
	if err != nil {
		return err
	}
	for _, raftLog := range logs {
		_, err = stmt.Exec(raftLog.Index, raftLog.Term, int(raftLog.Type), raftLog.Data)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	return tx.Commit()
}

// DeleteRange deletes a range of log entries. The range is inclusive.
func (relStore *RelationalStore) DeleteRange(min, max uint64) error {
	_, err := db.ExecOrchestrator("delete from raft_log where log_index >= ? and log_index <= ?", min, max)
	return err
}
<commit_msg>investigating installSnapshot<commit_after>/*
   Copyright 2017 Shlomi Noach, GitHub Inc.

   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 orcraft

import (
	"database/sql"
	"encoding/binary"

	"github.com/github/orchestrator/go/db"

	"github.com/hashicorp/raft"
)

// RelationalStoreimplements:
// - hashicorp/raft.StableStore
// - hashicorp/log.LogStore
type RelationalStore struct {
}

func NewRelationalStore() *RelationalStore {
	return &RelationalStore{}
}

func (relStore *RelationalStore) Set(key []byte, val []byte) error {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return err
	}
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	stmt, err := tx.Prepare(`delete from raft_store where store_key = ?`)
	if err != nil {
		return err
	}
	_, err = stmt.Exec(key)
	if err != nil {
		tx.Rollback()
		return err
	}
	stmt, err = tx.Prepare(`insert into raft_store (store_key, store_value) values (?, ?)`)
	if err != nil {
		tx.Rollback()
		return err
	}
	_, err = stmt.Exec(key, val)
	if err != nil {
		tx.Rollback()
		return err
	}
	err = tx.Commit()

	return err
}

// Get returns the value for key, or an empty byte slice if key was not found.
func (relStore *RelationalStore) Get(key []byte) (val []byte, err error) {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return val, err
	}
	err = db.QueryRow("select min(store_value) from raft_store where store_key = ?", key).Scan(&val)
	return val, err
}

func (relStore *RelationalStore) SetUint64(key []byte, val uint64) error {
	b := make([]byte, 8)
	binary.LittleEndian.PutUint64(b, val)

	return relStore.Set(key, b)
}

// GetUint64 returns the uint64 value for key, or 0 if key was not found.
func (relStore *RelationalStore) GetUint64(key []byte) (uint64, error) {
	b, err := relStore.Get(key)
	if err != nil {
		return 0, err
	}
	if len(b) == 0 {
		// Not found
		return 0, nil
	}
	i := binary.LittleEndian.Uint64(b)
	return i, nil
}

func (relStore *RelationalStore) FirstIndex() (idx uint64, err error) {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return idx, err
	}
	err = db.QueryRow("select ifnull(min(log_index), 0) from raft_log").Scan(&idx)
	return idx, err
}

// LastIndex returns the last index written. 0 for no entries.
func (relStore *RelationalStore) LastIndex() (idx uint64, err error) {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return idx, err
	}
	err = db.QueryRow("select ifnull(max(log_index), 0) from raft_log").Scan(&idx)
	return idx, err
}

// GetLog gets a log entry at a given index.
func (relStore *RelationalStore) GetLog(index uint64, log *raft.Log) error {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return err
	}
	err = db.QueryRow(`
    select log_index, term, log_type, data
      from raft_log
      where log_index = ?
    `, index).Scan(&log.Index, &log.Term, &log.Type, &log.Data)
	if err == sql.ErrNoRows {
		return raft.ErrLogNotFound
	}
	return err
}

// StoreLog stores a log entry.
func (relStore *RelationalStore) StoreLog(log *raft.Log) error {
	return relStore.StoreLogs([]*raft.Log{log})
}

// StoreLogs stores multiple log entries.
func (relStore *RelationalStore) StoreLogs(logs []*raft.Log) error {
	db, err := db.OpenOrchestrator()
	if err != nil {
		return err
	}
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	stmt, err := tx.Prepare(`
    replace into raft_log (
      log_index, term, log_type, data
    ) values (
      ?, ?, ?, ?
    )`)
	if err != nil {
		return err
	}
	for _, raftLog := range logs {
		_, err = stmt.Exec(raftLog.Index, raftLog.Term, int(raftLog.Type), raftLog.Data)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	return tx.Commit()
}

// DeleteRange deletes a range of log entries. The range is inclusive.
func (relStore *RelationalStore) DeleteRange(min, max uint64) error {
	_, err := db.ExecOrchestrator("delete from raft_log where log_index >= ? and log_index <= ?", min, max)
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"

	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/dom"
)

func main() {

	js.Global.Call("addEventListener", "load", func() {
		doc := dom.GetWindow().Document()
		canvas := doc.GetElementByID("canvas").(*dom.HTMLCanvasElement)
		ctx := canvas.GetContext2d()
		img := doc.GetElementByID("img_elephant").(*dom.HTMLImageElement)

		println(img)
		var x = 1
		var aniFrm func(t time.Duration)
		aniFrm = func(t time.Duration) {
			ctx.FillStyle = "black"
			ctx.FillRect(0, 0, 640, 480)
			ctx.FillStyle = "red"
			s := fmt.Sprint(t)
			ctx.FillText(s, x, 100, 300)

			ctx.Call("drawImage", img.Object, x, 100, 100, 100)

			x++
			if x > 640 {
				x = 0
			}
			dom.GetWindow().RequestAnimationFrame(aniFrm)
		}
		dom.GetWindow().RequestAnimationFrame(aniFrm)
	})
}
<commit_msg>adding helper funtions<commit_after>package main

import (
	"fmt"
	"time"

	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/dom"
)

type Canvas struct {
	ctx     *dom.CanvasRenderingContext2D
	Animate func(t time.Duration)
}

func MakeCanvas(id string) *Canvas {
	c := Canvas{}

	doc := dom.GetWindow().Document()
	canvas := doc.GetElementByID(id).(*dom.HTMLCanvasElement)
	c.ctx = canvas.GetContext2d()
	return &c
}

func main() {

	js.Global.Call("addEventListener", "load", func() {
		doc := dom.GetWindow().Document()
		img := doc.GetElementByID("img_elephant").(*dom.HTMLImageElement)
		canvas := MakeCanvas("canvas")
		println(img)
		var x = 1
		var aniFrm func(t time.Duration)
		aniFrm = func(t time.Duration) {
			canvas.ctx.FillStyle = "black"
			canvas.ctx.FillRect(0, 0, 640, 480)
			canvas.ctx.FillStyle = "red"
			s := fmt.Sprint(t)
			canvas.ctx.FillText(s, x, 100, 300)

			canvas.ctx.Call("drawImage", img.Object, x, 100, 100, 100)

			x++
			if x > 640 {
				x = 0
			}
			dom.GetWindow().RequestAnimationFrame(aniFrm)
		}
		dom.GetWindow().RequestAnimationFrame(aniFrm)
	})
}
<|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 f64

import (
	"math"
	"math/rand"
)

// newGuardedVector allocates a new slice and returns it as three subslices.
// v is a strided vector that contains elements of data at indices i*inc and
// NaN elsewhere. frontGuard and backGuard are filled with NaN values, and
// their backing arrays are directly adjacent to v in memory. The three slices
// can be used to detect invalid memory reads and writes.
func newGuardedVector(data []float64, inc int) (v, frontGuard, backGuard []float64) {
	if inc < 0 {
		inc = -inc
	}
	guard := 2 * inc
	size := (len(data)-1)*inc + 1
	whole := make([]float64, size+2*guard)
	v = whole[guard : len(whole)-guard]
	for i := range whole {
		whole[i] = math.NaN()
	}
	for i, d := range data {
		v[i*inc] = d
	}
	return v, whole[:guard], whole[len(whole)-guard:]
}

// allNaN returns true if x contains only NaN values, and false otherwise.
func allNaN(x []float64) bool {
	for _, v := range x {
		if !math.IsNaN(v) {
			return false
		}
	}
	return true
}

// equalStrided returns true if the strided vector x contains elements of the
// dense vector ref at indices i*inc, false otherwise.
func equalStrided(ref, x []float64, inc int) bool {
	if inc < 0 {
		inc = -inc
	}
	for i, v := range ref {
		if !same(x[i*inc], v) {
			return false
		}
	}
	return true
}

// nonStridedWrite returns false if all elements of x at non-stride indices are
// equal to NaN, true otherwise.
func nonStridedWrite(x []float64, inc int) bool {
	if inc < 0 {
		inc = -inc
	}
	for i, v := range x {
		if i%inc != 0 && !math.IsNaN(v) {
			return true
		}
	}
	return false
}

type incSet struct {
	x, y int
}

func genInc(inc []int) []incSet {
	n := len(inc)
	is := make([]incSet, n*n)
	for x := range inc {
		for y := range inc {
			is[x*n+y] = incSet{inc[x], inc[y]}
		}
	}
	return is
}

type incToSet struct {
	dst, x, y int
}

func genIncTo(inc []int) []incToSet {
	n := len(inc)
	is := make([]incToSet, n*n)
	for dst := range inc {
		for x := range inc {
			for y := range inc {
				is[x*n+y] = incToSet{inc[dst], inc[x], inc[y]}
			}
		}
	}
	return is
}

var gs []float64

func randomSlice(n, inc int) []float64 {
	if inc < 0 {
		inc = -inc
	}
	x := make([]float64, (n-1)*inc+1)
	for i := range x {
		x[i] = rand.Float64()
	}
	return x
}
<commit_msg>asm/f64: Added alignment offset sets for testing.<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 f64

import (
	"math"
	"math/rand"
)

// newGuardedVector allocates a new slice and returns it as three subslices.
// v is a strided vector that contains elements of data at indices i*inc and
// NaN elsewhere. frontGuard and backGuard are filled with NaN values, and
// their backing arrays are directly adjacent to v in memory. The three slices
// can be used to detect invalid memory reads and writes.
func newGuardedVector(data []float64, inc int) (v, frontGuard, backGuard []float64) {
	if inc < 0 {
		inc = -inc
	}
	guard := 2 * inc
	size := (len(data)-1)*inc + 1
	whole := make([]float64, size+2*guard)
	v = whole[guard : len(whole)-guard]
	for i := range whole {
		whole[i] = math.NaN()
	}
	for i, d := range data {
		v[i*inc] = d
	}
	return v, whole[:guard], whole[len(whole)-guard:]
}

// allNaN returns true if x contains only NaN values, and false otherwise.
func allNaN(x []float64) bool {
	for _, v := range x {
		if !math.IsNaN(v) {
			return false
		}
	}
	return true
}

// equalStrided returns true if the strided vector x contains elements of the
// dense vector ref at indices i*inc, false otherwise.
func equalStrided(ref, x []float64, inc int) bool {
	if inc < 0 {
		inc = -inc
	}
	for i, v := range ref {
		if !same(x[i*inc], v) {
			return false
		}
	}
	return true
}

// nonStridedWrite returns false if all elements of x at non-stride indices are
// equal to NaN, true otherwise.
func nonStridedWrite(x []float64, inc int) bool {
	if inc < 0 {
		inc = -inc
	}
	for i, v := range x {
		if i%inc != 0 && !math.IsNaN(v) {
			return true
		}
	}
	return false
}

var align2 = []struct{ x, y int }{{0, 0}, {0, 1}, {1, 0}, {1, 1}}
var align3 = []struct{ x, y, z int }{
	{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 1, 1}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}}

type incSet struct {
	x, y int
}

func genInc(inc []int) []incSet {
	n := len(inc)
	is := make([]incSet, n*n)
	for x := range inc {
		for y := range inc {
			is[x*n+y] = incSet{inc[x], inc[y]}
		}
	}
	return is
}

type incToSet struct {
	dst, x, y int
}

func genIncTo(inc []int) []incToSet {
	n := len(inc)
	is := make([]incToSet, n*n)
	for dst := range inc {
		for x := range inc {
			for y := range inc {
				is[x*n+y] = incToSet{inc[dst], inc[x], inc[y]}
			}
		}
	}
	return is
}

var gs []float64

func randomSlice(n, inc int) []float64 {
	if inc < 0 {
		inc = -inc
	}
	x := make([]float64, (n-1)*inc+1)
	for i := range x {
		x[i] = rand.Float64()
	}
	return x
}
<|endoftext|>


<commit_before>package assert

import (
	"errors"
	"testing"
)

func TestEqual(t *testing.T) {
	Equal(1, 1, t)
	Equal(1.0, 1.0, t)
	Equal(nil, nil, t)
	Equal([]uint32{1, 2, 3}, []uint32{1, 2, 3}, t)
}

func TestAlmostEqual(t *testing.T) {
	AlmostEqual(1.0, 1.0 + 1e-10, t)
	AlmostEqual([]float64{1, 1 + 1e-10}, []float64{1, 1}, t)
}

func TestSuccess(t *testing.T) {
	Success(nil, t)
}

func TestFailure(t *testing.T) {
	Failure(errors.New("Inherently broken."), t)
}
<commit_msg>Go fmt!<commit_after>package assert

import (
	"errors"
	"testing"
)

func TestEqual(t *testing.T) {
	Equal(1, 1, t)
	Equal(1.0, 1.0, t)
	Equal(nil, nil, t)
	Equal([]uint32{1, 2, 3}, []uint32{1, 2, 3}, t)
}

func TestAlmostEqual(t *testing.T) {
	AlmostEqual(1.0, 1.0+1e-10, t)
	AlmostEqual([]float64{1, 1 + 1e-10}, []float64{1, 1}, t)
}

func TestSuccess(t *testing.T) {
	Success(nil, t)
}

func TestFailure(t *testing.T) {
	Failure(errors.New("Inherently broken."), t)
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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 e2e_node

import (
	"fmt"
	"time"

	"k8s.io/kubernetes/pkg/api"
	apierrs "k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/client/restclient"
	client "k8s.io/kubernetes/pkg/client/unversioned"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Kubelet Container Manager", func() {
	var cl *client.Client
	BeforeEach(func() {
		// Setup the apiserver client
		cl = client.NewOrDie(&restclient.Config{Host: *apiServerAddress})
	})
	Describe("oom score adjusting", func() {
		namespace := "oom-adj"
		Context("when scheduling a busybox command that always fails in a pod", func() {
			podName := "bin-false"

			BeforeEach(func() {
				pod := &api.Pod{
					ObjectMeta: api.ObjectMeta{
						Name:      podName,
						Namespace: namespace,
					},
					Spec: api.PodSpec{
						// Force the Pod to schedule to the node without a scheduler running
						NodeName: *nodeName,
						// Don't restart the Pod since it is expected to exit
						RestartPolicy: api.RestartPolicyNever,
						Containers: []api.Container{
							{
								Image:   "gcr.io/google_containers/busybox:1.24",
								Name:    podName,
								Command: []string{"/bin/false"},
							},
						},
					},
				}

				_, err := cl.Pods(namespace).Create(pod)
				Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
			})

			It("it should have an error terminated reason", func() {
				Eventually(func() error {
					podData, err := cl.Pods(namespace).Get(podName)
					if err != nil {
						return err
					}
					if len(podData.Status.ContainerStatuses) != 1 {
						return fmt.Errorf("expected only one container in the pod %q", podName)
					}
					contTerminatedState := podData.Status.ContainerStatuses[0].State.Terminated
					if contTerminatedState == nil {
						return fmt.Errorf("expected state to be terminated. Got pod status: %+v", podData.Status)
					}
					if contTerminatedState.Reason != "Error" {
						return fmt.Errorf("expected terminated state reason to be error. Got %+v", contTerminatedState)
					}
					return nil
				}, time.Minute, time.Second*4).Should(BeNil())
			})

			It("it should be possible to delete", func() {
				err := cl.Pods(namespace).Delete(podName, &api.DeleteOptions{})
				Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err))
			})

			AfterEach(func() {
				cl.Pods(namespace).Delete(podName, &api.DeleteOptions{})
				Eventually(func() bool {
					_, err := cl.Pods(namespace).Get(podName)
					if err != nil && apierrs.IsNotFound(err) {
						return true
					}
					return false
				}, time.Minute, time.Second*4).Should(BeTrue())
			})

		})
	})

})
<commit_msg>fix #24937:  flake pod not found<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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 e2e_node

import (
	"fmt"
	"time"

	"k8s.io/kubernetes/pkg/api"
	apierrs "k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/client/restclient"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/util"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Kubelet Container Manager", func() {
	var cl *client.Client
	BeforeEach(func() {
		// Setup the apiserver client
		cl = client.NewOrDie(&restclient.Config{Host: *apiServerAddress})
	})
	Describe("oom score adjusting", func() {
		namespace := "oom-adj"
		Context("when scheduling a busybox command that always fails in a pod", func() {
			var podName string

			BeforeEach(func() {
				podName = "bin-false" + string(util.NewUUID())
				pod := &api.Pod{
					ObjectMeta: api.ObjectMeta{
						Name:      podName,
						Namespace: namespace,
					},
					Spec: api.PodSpec{
						// Force the Pod to schedule to the node without a scheduler running
						NodeName: *nodeName,
						// Don't restart the Pod since it is expected to exit
						RestartPolicy: api.RestartPolicyNever,
						Containers: []api.Container{
							{
								Image:   "gcr.io/google_containers/busybox:1.24",
								Name:    podName,
								Command: []string{"/bin/false"},
							},
						},
					},
				}

				_, err := cl.Pods(namespace).Create(pod)
				Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
			})

			It("it should have an error terminated reason", func() {
				Eventually(func() error {
					podData, err := cl.Pods(namespace).Get(podName)
					if err != nil {
						return err
					}
					if len(podData.Status.ContainerStatuses) != 1 {
						return fmt.Errorf("expected only one container in the pod %q", podName)
					}
					contTerminatedState := podData.Status.ContainerStatuses[0].State.Terminated
					if contTerminatedState == nil {
						return fmt.Errorf("expected state to be terminated. Got pod status: %+v", podData.Status)
					}
					if contTerminatedState.Reason != "Error" {
						return fmt.Errorf("expected terminated state reason to be error. Got %+v", contTerminatedState)
					}
					return nil
				}, time.Minute, time.Second*4).Should(BeNil())
			})

			It("it should be possible to delete", func() {
				err := cl.Pods(namespace).Delete(podName, &api.DeleteOptions{})
				Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err))
			})

			AfterEach(func() {
				cl.Pods(namespace).Delete(podName, &api.DeleteOptions{})
				Eventually(func() bool {
					_, err := cl.Pods(namespace).Get(podName)
					if err != nil && apierrs.IsNotFound(err) {
						return true
					}
					return false
				}, time.Minute, time.Second*4).Should(BeTrue())
			})

		})
	})

})
<|endoftext|>


<commit_before>package campaign

import (
	"github.com/supme/gonder/models"
	"time"
	"bytes"
	"strconv"
	"errors"
	"math/rand"
)

type recipient struct {
	id, to_email, to_name	string
}

// Check recipient for unsubscribe
func (r *recipient) unsubscribe(campaignId string) bool {
	var unsubscribeCount int
	models.Db.QueryRow("SELECT COUNT(*) FROM `unsubscribe` t1 INNER JOIN `campaign` t2 ON t1.group_id = t2.group_id WHERE t2.id = ? AND t1.email = ?", campaignId, r.to_email).Scan(&unsubscribeCount)
	if unsubscribeCount == 0 {
		return false
	}
	return true
}

// Send mail for recipient this campaign data
func (r recipient) send(c *campaign, iface, host string) string {
	start := time.Now()

	data := new(MailData)
	data.Iface, data.Host = iface, host
	data.From_email = c.from_email
	data.From_name = c.from_name
	data.Attachments = c.attachments
	data.To_email = r.to_email
	data.To_name = r.to_name

	message := new(models.Message)
	message.CampaignId = c.id
	message.RecipientId = r.id
	message.CampaignSubject = c.subject
	message.CampaignTemplate = c.body
	message.RecipientEmail = r.to_email
	message.RecipientName = r.to_name

	var rs string
	m, e := message.RenderMessage()
	if e == nil {
		data.Subject = message.CampaignSubject
		data.Html = m
		var extraHeader bytes.Buffer
		extraHeader.WriteString("List-Unsubscribe: " + message.UnsubscribeMailLink() + "\r\nPrecedence: bulk\r\n")
		extraHeader.WriteString("Message-ID: <" + strconv.FormatInt(time.Now().Unix(), 10) + c.id + "." + r.id +"@" + data.Host + ">" + "\r\n")
		// ToDo X-Postmaster-Msgtype: reg01 - Идентификатор (ID) письма. По нему будут группироваться одинаковые письма.
		data.Extra_header = extraHeader.String()

		var res error
		if models.Config.RealSend {
			// Send mail
			res = data.Send()
		} else {
			wait := time.Duration(rand.Int()/10000000000) * time.Nanosecond
			time.Sleep(wait)
			res = errors.New("Test send")
		}

		if res == nil {
			rs = "Ok"
		} else {
			rs = res.Error()
		}
	} else {
		rs = e.Error()
	}

	camplog.Printf("Campaign %s for recipient id %s email %s is %s send time %s", c.id, r.id, data.To_email, rs, time.Since(start))
	return rs
}
<commit_msg>Add "X-Postmaster-Msgtype" to header<commit_after>package campaign

import (
	"github.com/supme/gonder/models"
	"time"
	"bytes"
	"strconv"
	"errors"
	"math/rand"
)

type recipient struct {
	id, to_email, to_name	string
}

// Check recipient for unsubscribe
func (r *recipient) unsubscribe(campaignId string) bool {
	var unsubscribeCount int
	models.Db.QueryRow("SELECT COUNT(*) FROM `unsubscribe` t1 INNER JOIN `campaign` t2 ON t1.group_id = t2.group_id WHERE t2.id = ? AND t1.email = ?", campaignId, r.to_email).Scan(&unsubscribeCount)
	if unsubscribeCount == 0 {
		return false
	}
	return true
}

// Send mail for recipient this campaign data
func (r recipient) send(c *campaign, iface, host string) string {
	start := time.Now()

	data := new(MailData)
	data.Iface, data.Host = iface, host
	data.From_email = c.from_email
	data.From_name = c.from_name
	data.Attachments = c.attachments
	data.To_email = r.to_email
	data.To_name = r.to_name

	message := new(models.Message)
	message.CampaignId = c.id
	message.RecipientId = r.id
	message.CampaignSubject = c.subject
	message.CampaignTemplate = c.body
	message.RecipientEmail = r.to_email
	message.RecipientName = r.to_name

	var rs string
	m, e := message.RenderMessage()
	if e == nil {
		data.Subject = message.CampaignSubject
		data.Html = m
		var extraHeader bytes.Buffer
		extraHeader.WriteString("List-Unsubscribe: " + message.UnsubscribeMailLink() + "\r\nPrecedence: bulk\r\n")
		extraHeader.WriteString("Message-ID: <" + strconv.FormatInt(time.Now().Unix(), 10) + c.id + "." + r.id +"@" + data.Host + ">" + "\r\n")
		extraHeader.WriteString("X-Postmaster-Msgtype: campaign" + c.id + "\r\n")
		data.Extra_header = extraHeader.String()

		var res error
		if models.Config.RealSend {
			// Send mail
			res = data.Send()
		} else {
			wait := time.Duration(rand.Int()/10000000000) * time.Nanosecond
			time.Sleep(wait)
			res = errors.New("Test send")
		}

		if res == nil {
			rs = "Ok"
		} else {
			rs = res.Error()
		}
	} else {
		rs = e.Error()
	}

	camplog.Printf("Campaign %s for recipient id %s email %s is %s send time %s", c.id, r.id, data.To_email, rs, time.Since(start))
	return rs
}
<|endoftext|>


<commit_before>package main

import (
	"os/exec"
	"os"
	"io/ioutil"
	"gopkg.in/yaml.v2"
	"log"
	"strings"
	"bufio"
	"bytes"
	"time"
)

type config struct {
	Mailfrom string `yaml:"mailfrom"`
	Mailfromname string `yaml:"mailfromname"`
	Mailsubject string `yaml:"mailsubject"`
	Mailtos []string `yaml:"mailtos"`
	Ipaddresses []string `yaml:"ipaddresses"`
	Rechecktime int64 `yaml:"rechecktime"`
	Gracetime int64 `yaml:"gracetime"`
}

func (c *config) getConfig(configfile string) *config {
	yamlFile, readErr := ioutil.ReadFile(configfile)
	if readErr != nil {
		log.Printf("yamlFile.Get err   #%v ", readErr)
		panic(readErr)
	}

	yamlErr := yaml.Unmarshal(yamlFile, &c)
	if yamlErr != nil {
		log.Fatalf("Unmarshal: %v", yamlErr)
		panic(yamlErr)
	}

	return c
}

func getWho() string {

	var (
		whoOut []byte
		execErr error
	)

	who, lookErr := exec.LookPath("who")
	if lookErr != nil {
		panic(lookErr)
	}

	args := []string{"-u"}

	whoOut, execErr = exec.Command(who, args...).Output();
	if execErr != nil {
		panic(execErr)
	}
	return string(whoOut)
}

func isNotAllowed(address string, allowedAddresses []string) bool {
	for _, allowedAddress := range allowedAddresses {
		if allowedAddress == address {
			return false
		}
	}
	return true
}

func hostname() string {
	hostname, lookErr := exec.LookPath("hostname")
	if lookErr != nil {
		panic(lookErr)
	}

	args := []string{"-f"}

	hostfqdn, execErr := exec.Command(hostname, args...).Output();
	if execErr != nil {
		panic(execErr)
	}

	return string(hostfqdn)
}

func sendMail(recipient string, mailfrom string, mailfromname string, mailsubject string, mailbody string) {

	var sendmailBuffer bytes.Buffer

	sendmailBuffer.WriteString("Subject: ")
	sendmailBuffer.WriteString(mailsubject)
	sendmailBuffer.WriteString("\nLoginchecker triggered an alert\n")
	sendmailBuffer.WriteString("\n\n")
	sendmailBuffer.WriteString(mailbody)
	sendmailBuffer.WriteString("\n.")

	mail, lookErr := exec.LookPath("sendmail")
	if lookErr != nil {
		panic(lookErr)
	}

	args := []string{"-t", "-f", mailfrom, "-F", mailfromname, recipient}

	sendmail := exec.Command(mail, args...);
	sendmail.Stdin = strings.NewReader(sendmailBuffer.String())
	execErr := sendmail.Run()
	if execErr != nil {
		log.Fatal(execErr)
	}
}

func main () {
	var (
		config config
		line string
	)

	configfile := "./config.yml"
	if  len(os.Args) > 1 {
		arg := os.Args[1]
		configfile = arg
	}

	config.getConfig(configfile)

	recheckTime := time.Duration(config.Rechecktime) * time.Second
	graceTime := time.Duration(config.Gracetime) * time.Second
	alertMailtos := config.Mailtos
	allowedAddresses := config.Ipaddresses
	mailFrom := config.Mailfrom
	mailFromName := config.Mailfromname
	mailSubject := config.Mailsubject + " @ " + hostname()

	println(mailFrom, mailFromName, mailSubject)

	logged := make(map[string]time.Time)

	for {
		who := getWho()
		scanner := bufio.NewScanner(strings.NewReader(who))
		for scanner.Scan() {
			line = scanner.Text()
			whoIsLoggedIn := strings.Fields(line)
			username := whoIsLoggedIn[0]
			address := strings.Trim(whoIsLoggedIn[6], "(,)")
                        uniqe_user := username + address

			if isNotAllowed(address, allowedAddresses) {
				mailBody := username + " is not allowed from " + address
				sendmail := false

				timeDetected := time.Now()
				if timeLogged, ok := logged[uniqe_user]; ok {
					if (timeDetected.Sub(timeLogged) > graceTime) {
						logged[uniqe_user] = timeDetected
						sendmail = true
					}

				} else {
					logged[uniqe_user] = timeDetected
					sendmail = true
				}

				if sendmail == true {
					for _, alertMailto := range alertMailtos {
						sendMail(alertMailto, mailFrom, mailFromName, mailSubject, mailBody)
					}
				}
			}
		}
		time.Sleep(recheckTime)
	}
}<commit_msg>added test if ip address or hostname<commit_after>package main

import (
	"os/exec"
	"os"
	"io/ioutil"
	"gopkg.in/yaml.v2"
	"log"
	"strings"
	"bufio"
	"bytes"
	"time"
	"net"
)

type config struct {
	Mailfrom string `yaml:"mailfrom"`
	Mailfromname string `yaml:"mailfromname"`
	Mailsubject string `yaml:"mailsubject"`
	Mailtos []string `yaml:"mailtos"`
	Ipaddresses []string `yaml:"ipaddresses"`
	Rechecktime int64 `yaml:"rechecktime"`
	Gracetime int64 `yaml:"gracetime"`
}

func (c *config) getConfig(configfile string) *config {
	yamlFile, readErr := ioutil.ReadFile(configfile)
	if readErr != nil {
		log.Printf("yamlFile.Get err   #%v ", readErr)
		panic(readErr)
	}

	yamlErr := yaml.Unmarshal(yamlFile, &c)
	if yamlErr != nil {
		log.Fatalf("Unmarshal: %v", yamlErr)
		panic(yamlErr)
	}

	return c
}

func getWho() string {

	var (
		whoOut []byte
		execErr error
	)

	who, lookErr := exec.LookPath("who")
	if lookErr != nil {
		panic(lookErr)
	}

	args := []string{"-u"}

	whoOut, execErr = exec.Command(who, args...).Output();
	if execErr != nil {
		panic(execErr)
	}
	return string(whoOut)
}

func isNotAllowed(address string, allowedNetworks []string) bool {

	parsedAddress := net.ParseIP(address)
	if parsedAddress == nil {
		for _, allowedHostname := range allowedNetworks {
			if allowedHostname == address {
				return false
			}
		}
	} else {
		for _, allowedNetwork := range allowedNetworks {
			_, parsedAllowedNetworkCIDR, _ := net.ParseCIDR(allowedNetwork)
			if parsedAllowedNetworkCIDR == nil {
			} else {
				if parsedAllowedNetworkCIDR.Contains(parsedAddress) {
					return false
				}
			}
		}
	}
	return true
}

func hostname() string {
	hostname, lookErr := exec.LookPath("hostname")
	if lookErr != nil {
		panic(lookErr)
	}

	args := []string{"-f"}

	hostfqdn, execErr := exec.Command(hostname, args...).Output();
	if execErr != nil {
		panic(execErr)
	}

	return string(hostfqdn)
}

func sendMail(recipient string, mailfrom string, mailfromname string, mailsubject string, mailbody string) {

	var sendmailBuffer bytes.Buffer

	sendmailBuffer.WriteString("Subject: ")
	sendmailBuffer.WriteString(mailsubject)
	sendmailBuffer.WriteString("\nLoginchecker triggered an alert\n")
	sendmailBuffer.WriteString("\n\n")
	sendmailBuffer.WriteString(mailbody)
	sendmailBuffer.WriteString("\n.")

	mail, lookErr := exec.LookPath("sendmail")
	if lookErr != nil {
		panic(lookErr)
	}

	args := []string{"-t", "-f", mailfrom, "-F", mailfromname, recipient}

	sendmail := exec.Command(mail, args...);
	sendmail.Stdin = strings.NewReader(sendmailBuffer.String())
	execErr := sendmail.Run()
	if execErr != nil {
		log.Fatal(execErr)
	}
}

func main () {
	var (
		config config
		line string
	)

	configfile := "./config.yml"
	if  len(os.Args) > 1 {
		arg := os.Args[1]
		configfile = arg
	}

	config.getConfig(configfile)

	recheckTime := time.Duration(config.Rechecktime) * time.Second
	graceTime := time.Duration(config.Gracetime) * time.Second
	alertMailtos := config.Mailtos
	allowedAddresses := config.Ipaddresses
	mailFrom := config.Mailfrom
	mailFromName := config.Mailfromname
	mailSubject := config.Mailsubject + " @ " + hostname()

	println(mailFrom, mailFromName, mailSubject)

	logged := make(map[string]time.Time)

	for {
		who := getWho()
		scanner := bufio.NewScanner(strings.NewReader(who))
		for scanner.Scan() {
			line = scanner.Text()
			whoIsLoggedIn := strings.Fields(line)
			username := whoIsLoggedIn[0]
			address := strings.Trim(whoIsLoggedIn[6], "(,)")
                        uniqe_user := username + address

			if isNotAllowed(address, allowedAddresses) {
				mailBody := username + " is not allowed from " + address
				sendmail := false

				timeDetected := time.Now()
				if timeLogged, ok := logged[uniqe_user]; ok {
					if (timeDetected.Sub(timeLogged) > graceTime) {
						logged[uniqe_user] = timeDetected
						sendmail = true
					}

				} else {
					logged[uniqe_user] = timeDetected
					sendmail = true
				}

				if sendmail == true {
					for _, alertMailto := range alertMailtos {
						sendMail(alertMailto, mailFrom, mailFromName, mailSubject, mailBody)
					}
				}
			}
		}
		time.Sleep(recheckTime)
	}
}<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"net/url"
	"os"
	"os/signal"
	"time"

	"github.com/Comcast/webpa-common/concurrent"
	"github.com/Comcast/webpa-common/secure"
	"github.com/Comcast/webpa-common/secure/handler"
	"github.com/Comcast/webpa-common/secure/key"
	"github.com/Comcast/webpa-common/server"
	"github.com/Comcast/webpa-common/webhook"
	"github.com/SermoDigital/jose/jwt"
	"github.com/gorilla/mux"
	"github.com/justinas/alice"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

const (
	applicationName = "caduceus"
	DEFAULT_KEY_ID  = "current"
)

// getValidator returns validator for JWT tokens
func getValidator(v *viper.Viper) (validator secure.Validator, err error) {
	default_validators := make(secure.Validators, 0, 0)
	var jwtVals []JWTValidator

	v.UnmarshalKey("jwtValidators", &jwtVals)

	// make sure there is at least one jwtValidator supplied
	if len(jwtVals) < 1 {
		validator = default_validators
		return
	}

	// if a JWTKeys section was supplied, configure a JWS validator
	// and append it to the chain of validators
	validators := make(secure.Validators, 0, len(jwtVals))

	for _, validatorDescriptor := range jwtVals {
		var keyResolver key.Resolver
		keyResolver, err = validatorDescriptor.Keys.NewResolver()
		if err != nil {
			validator = validators
			return
		}

		validators = append(
			validators,
			secure.JWSValidator{
				DefaultKeyId:  DEFAULT_KEY_ID,
				Resolver:      keyResolver,
				JWTValidators: []*jwt.Validator{validatorDescriptor.Custom.New()},
			},
		)
	}

	// TODO: This should really be part of the unmarshalled validators somehow
	basicAuth := v.GetStringSlice("authHeader")
	for _, authValue := range basicAuth {
		validators = append(
			validators,
			secure.ExactMatchValidator(authValue),
		)
	}

	validator = validators

	return
}

// caduceus is the driver function for Caduceus.  It performs everything main() would do,
// except for obtaining the command-line arguments (which are passed to it).
func caduceus(arguments []string) int {
	totalTime := time.Now()

	var (
		f = pflag.NewFlagSet(applicationName, pflag.ContinueOnError)
		v = viper.New()

		logger, webPA, err = server.Initialize(applicationName, arguments, f, v)
	)

	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to initialize Viper environment: %s\n", err)
		return 1
	}

	logger.Info("Using configuration file: %s", v.ConfigFileUsed())

	caduceusConfig := new(CaduceusConfig)
	err = v.Unmarshal(caduceusConfig)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to unmarshal configuration data into struct: %s\n", err)
		return 1
	}

	workerPool := WorkerPoolFactory{
		NumWorkers: caduceusConfig.NumWorkerThreads,
		QueueSize:  caduceusConfig.JobQueueSize,
	}.New()

	mainCaduceusProfilerFactory := ServerProfilerFactory{
		Frequency: caduceusConfig.ProfilerFrequency,
		Duration:  caduceusConfig.ProfilerDuration,
		QueueSize: caduceusConfig.ProfilerQueueSize,
		Logger:    logger,
	}

	// here we create a profiler specifically for our main server handler
	caduceusHandlerProfiler, err := mainCaduceusProfilerFactory.New("main")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to profiler for main caduceus handler: %s\n", err)
		return 1
	}

	childCaduceusProfilerFactory := mainCaduceusProfilerFactory
	childCaduceusProfilerFactory.Parent = caduceusHandlerProfiler

	tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
	timeout := time.Duration(caduceusConfig.SenderClientTimeout) * time.Second

	// declare a new sender wrapper and pass it a profiler factory so that it can create
	// unique profilers on a per outboundSender basis
	caduceusSenderWrapper, err := SenderWrapperFactory{
		NumWorkersPerSender: caduceusConfig.SenderNumWorkersPerSender,
		QueueSizePerSender:  caduceusConfig.SenderQueueSizePerSender,
		CutOffPeriod:        time.Duration(caduceusConfig.SenderCutOffPeriod) * time.Second,
		Linger:              time.Duration(caduceusConfig.SenderLinger) * time.Second,
		ProfilerFactory:     childCaduceusProfilerFactory,
		Logger:              logger,
		Client:              &http.Client{Transport: tr, Timeout: timeout},
	}.New()

	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to initialize new caduceus sender wrapper: %s\n", err)
		return 1
	}

	serverWrapper := &ServerHandler{
		Logger: logger,
		caduceusHandler: &CaduceusHandler{
			handlerProfiler: caduceusHandlerProfiler,
			senderWrapper:   caduceusSenderWrapper,
			Logger:          logger,
		},
		doJob: workerPool.Send,
	}

	profileWrapper := &ProfileHandler{
		profilerData: caduceusHandlerProfiler,
		Logger:       logger,
	}

	validator, err := getValidator(v)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Validator error: %v\n", err)
		return 1
	}

	authHandler := handler.AuthorizationHandler{
		HeaderName:          "Authorization",
		ForbiddenStatusCode: 403,
		Validator:           validator,
		Logger:              logger,
	}

	caduceusHandler := alice.New(authHandler.Decorate)

	mux := mux.NewRouter()
	mux.Handle("/api/v1/notify", caduceusHandler.Then(serverWrapper))
	mux.Handle("/api/v1/profile", caduceusHandler.Then(profileWrapper))

	// Support the old endpoint too.
	mux.Handle("/api/v2/notify/{deviceid}/event/{eventtype:.*}", caduceusHandler.Then(serverWrapper))

	webhookFactory, err := webhook.NewFactory(v)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating new webhook factory: %s\n", err)
		return 1
	}
	webhookRegistry, webhookHandler := webhookFactory.NewRegistryAndHandler()
	webhookFactory.SetExternalUpdate(caduceusSenderWrapper.Update)

	// register webhook end points for api
	mux.Handle("/hook", caduceusHandler.ThenFunc(webhookRegistry.UpdateRegistry))
	mux.Handle("/hooks", caduceusHandler.ThenFunc(webhookRegistry.GetRegistry))

	selfURL := &url.URL{
		Scheme: "https",
		Host:   v.GetString("fqdn") + v.GetString("primary.address"),
	}

	webhookFactory.Initialize(mux, selfURL, webhookHandler, logger)

	caduceusHealth := &CaduceusHealth{}
	var runnable concurrent.Runnable

	caduceusHealth.Monitor, runnable = webPA.Prepare(logger, mux)
	serverWrapper.caduceusHealth = caduceusHealth

	waitGroup, shutdown, err := concurrent.Execute(runnable)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to start device manager: %s\n", err)
		return 1
	}

	// make sure dns is ready before preceeding
	logger.Debug("Reaching out to see if DNS is ready.")
	now := time.Now()
	dnsReadyChan := make(chan bool, 1)
	go caduceusHealth.dnsReady(selfURL.String(), dnsReadyChan)
	<-dnsReadyChan
	logger.Debug("DNS is ready. elapsed time: %v", time.Since(now))

	// todo: add message
	webhookFactory.PrepareAndStart()

	// Attempt to obtain the current listener list from current system without having to wait for listener reregistration.
	logger.Debug("Attempting to obtain current listener list from %v", v.GetString("start.apiPath"))
	now = time.Now()
	startChan := make(chan webhook.Result, 1)
	webhookFactory.Start.GetCurrentSystemsHooks(startChan)
	var webhookStartResults webhook.Result = <-startChan
	if webhookStartResults.Error != nil {
		logger.Error(webhookStartResults.Error)
	} else {
		// todo: add message
		webhookFactory.SetList(webhook.NewList(webhookStartResults.Hooks))
		caduceusSenderWrapper.Update(webhookStartResults.Hooks)
	}
	logger.Debug("current listener retrieval, elapsed time: %v", time.Since(now))

	logger.Info("Caduceus is up and running! elapsed time: %v", time.Since(now))

	var (
		signals = make(chan os.Signal, 1)
	)

	signal.Notify(signals)
	<-signals
	close(shutdown)
	waitGroup.Wait()

	// shutdown the sender wrapper gently so that all queued messages get serviced
	caduceusSenderWrapper.Shutdown(true)

	return 0
}

func main() {
	os.Exit(caduceus(os.Args))
}
<commit_msg>using correct time variable now.<commit_after>package main

import (
	"crypto/tls"
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"net/url"
	"os"
	"os/signal"
	"time"

	"github.com/Comcast/webpa-common/concurrent"
	"github.com/Comcast/webpa-common/secure"
	"github.com/Comcast/webpa-common/secure/handler"
	"github.com/Comcast/webpa-common/secure/key"
	"github.com/Comcast/webpa-common/server"
	"github.com/Comcast/webpa-common/webhook"
	"github.com/SermoDigital/jose/jwt"
	"github.com/gorilla/mux"
	"github.com/justinas/alice"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

const (
	applicationName = "caduceus"
	DEFAULT_KEY_ID  = "current"
)

// getValidator returns validator for JWT tokens
func getValidator(v *viper.Viper) (validator secure.Validator, err error) {
	default_validators := make(secure.Validators, 0, 0)
	var jwtVals []JWTValidator

	v.UnmarshalKey("jwtValidators", &jwtVals)

	// make sure there is at least one jwtValidator supplied
	if len(jwtVals) < 1 {
		validator = default_validators
		return
	}

	// if a JWTKeys section was supplied, configure a JWS validator
	// and append it to the chain of validators
	validators := make(secure.Validators, 0, len(jwtVals))

	for _, validatorDescriptor := range jwtVals {
		var keyResolver key.Resolver
		keyResolver, err = validatorDescriptor.Keys.NewResolver()
		if err != nil {
			validator = validators
			return
		}

		validators = append(
			validators,
			secure.JWSValidator{
				DefaultKeyId:  DEFAULT_KEY_ID,
				Resolver:      keyResolver,
				JWTValidators: []*jwt.Validator{validatorDescriptor.Custom.New()},
			},
		)
	}

	// TODO: This should really be part of the unmarshalled validators somehow
	basicAuth := v.GetStringSlice("authHeader")
	for _, authValue := range basicAuth {
		validators = append(
			validators,
			secure.ExactMatchValidator(authValue),
		)
	}

	validator = validators

	return
}

// caduceus is the driver function for Caduceus.  It performs everything main() would do,
// except for obtaining the command-line arguments (which are passed to it).
func caduceus(arguments []string) int {
	totalTime := time.Now()

	var (
		f = pflag.NewFlagSet(applicationName, pflag.ContinueOnError)
		v = viper.New()

		logger, webPA, err = server.Initialize(applicationName, arguments, f, v)
	)

	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to initialize Viper environment: %s\n", err)
		return 1
	}

	logger.Info("Using configuration file: %s", v.ConfigFileUsed())

	caduceusConfig := new(CaduceusConfig)
	err = v.Unmarshal(caduceusConfig)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to unmarshal configuration data into struct: %s\n", err)
		return 1
	}

	workerPool := WorkerPoolFactory{
		NumWorkers: caduceusConfig.NumWorkerThreads,
		QueueSize:  caduceusConfig.JobQueueSize,
	}.New()

	mainCaduceusProfilerFactory := ServerProfilerFactory{
		Frequency: caduceusConfig.ProfilerFrequency,
		Duration:  caduceusConfig.ProfilerDuration,
		QueueSize: caduceusConfig.ProfilerQueueSize,
		Logger:    logger,
	}

	// here we create a profiler specifically for our main server handler
	caduceusHandlerProfiler, err := mainCaduceusProfilerFactory.New("main")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to profiler for main caduceus handler: %s\n", err)
		return 1
	}

	childCaduceusProfilerFactory := mainCaduceusProfilerFactory
	childCaduceusProfilerFactory.Parent = caduceusHandlerProfiler

	tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
	timeout := time.Duration(caduceusConfig.SenderClientTimeout) * time.Second

	// declare a new sender wrapper and pass it a profiler factory so that it can create
	// unique profilers on a per outboundSender basis
	caduceusSenderWrapper, err := SenderWrapperFactory{
		NumWorkersPerSender: caduceusConfig.SenderNumWorkersPerSender,
		QueueSizePerSender:  caduceusConfig.SenderQueueSizePerSender,
		CutOffPeriod:        time.Duration(caduceusConfig.SenderCutOffPeriod) * time.Second,
		Linger:              time.Duration(caduceusConfig.SenderLinger) * time.Second,
		ProfilerFactory:     childCaduceusProfilerFactory,
		Logger:              logger,
		Client:              &http.Client{Transport: tr, Timeout: timeout},
	}.New()

	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to initialize new caduceus sender wrapper: %s\n", err)
		return 1
	}

	serverWrapper := &ServerHandler{
		Logger: logger,
		caduceusHandler: &CaduceusHandler{
			handlerProfiler: caduceusHandlerProfiler,
			senderWrapper:   caduceusSenderWrapper,
			Logger:          logger,
		},
		doJob: workerPool.Send,
	}

	profileWrapper := &ProfileHandler{
		profilerData: caduceusHandlerProfiler,
		Logger:       logger,
	}

	validator, err := getValidator(v)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Validator error: %v\n", err)
		return 1
	}

	authHandler := handler.AuthorizationHandler{
		HeaderName:          "Authorization",
		ForbiddenStatusCode: 403,
		Validator:           validator,
		Logger:              logger,
	}

	caduceusHandler := alice.New(authHandler.Decorate)

	mux := mux.NewRouter()
	mux.Handle("/api/v1/notify", caduceusHandler.Then(serverWrapper))
	mux.Handle("/api/v1/profile", caduceusHandler.Then(profileWrapper))

	// Support the old endpoint too.
	mux.Handle("/api/v2/notify/{deviceid}/event/{eventtype:.*}", caduceusHandler.Then(serverWrapper))

	webhookFactory, err := webhook.NewFactory(v)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating new webhook factory: %s\n", err)
		return 1
	}
	webhookRegistry, webhookHandler := webhookFactory.NewRegistryAndHandler()
	webhookFactory.SetExternalUpdate(caduceusSenderWrapper.Update)

	// register webhook end points for api
	mux.Handle("/hook", caduceusHandler.ThenFunc(webhookRegistry.UpdateRegistry))
	mux.Handle("/hooks", caduceusHandler.ThenFunc(webhookRegistry.GetRegistry))

	selfURL := &url.URL{
		Scheme: "https",
		Host:   v.GetString("fqdn") + v.GetString("primary.address"),
	}

	webhookFactory.Initialize(mux, selfURL, webhookHandler, logger)

	caduceusHealth := &CaduceusHealth{}
	var runnable concurrent.Runnable

	caduceusHealth.Monitor, runnable = webPA.Prepare(logger, mux)
	serverWrapper.caduceusHealth = caduceusHealth

	waitGroup, shutdown, err := concurrent.Execute(runnable)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to start device manager: %s\n", err)
		return 1
	}

	// make sure dns is ready before preceeding
	logger.Debug("Reaching out to see if DNS is ready.")
	now := time.Now()
	dnsReadyChan := make(chan bool, 1)
	go caduceusHealth.dnsReady(selfURL.String(), dnsReadyChan)
	<-dnsReadyChan
	logger.Debug("DNS is ready. elapsed time: %v", time.Since(now))

	// todo: add message
	webhookFactory.PrepareAndStart()

	// Attempt to obtain the current listener list from current system without having to wait for listener reregistration.
	logger.Debug("Attempting to obtain current listener list from %v", v.GetString("start.apiPath"))
	now = time.Now()
	startChan := make(chan webhook.Result, 1)
	webhookFactory.Start.GetCurrentSystemsHooks(startChan)
	var webhookStartResults webhook.Result = <-startChan
	if webhookStartResults.Error != nil {
		logger.Error(webhookStartResults.Error)
	} else {
		// todo: add message
		webhookFactory.SetList(webhook.NewList(webhookStartResults.Hooks))
		caduceusSenderWrapper.Update(webhookStartResults.Hooks)
	}
	logger.Debug("current listener retrieval, elapsed time: %v", time.Since(now))

	logger.Info("Caduceus is up and running! elapsed time: %v", time.Since(totalTime))

	var (
		signals = make(chan os.Signal, 1)
	)

	signal.Notify(signals)
	<-signals
	close(shutdown)
	waitGroup.Wait()

	// shutdown the sender wrapper gently so that all queued messages get serviced
	caduceusSenderWrapper.Shutdown(true)

	return 0
}

func main() {
	os.Exit(caduceus(os.Args))
}
<|endoftext|>


<commit_before>package ics

import (
	"bytes"
	"io"
	"reflect"
	"testing"
	"time"
)

type typeTest struct {
	Params map[string]string
	Data   string
	Input  interface {
		Decode(map[string]string, string) error
	}
	Match interface {
		Encode(io.Writer)
	}
	Output string
	Error  error
}

var emptyMap = make(map[string]string)

func testType(t *testing.T, tests []typeTest) {
	var buf bytes.Buffer
	for n, test := range tests {
		if test.Params == nil {
			test.Params = emptyMap
		}
		err := test.Input.Decode(test.Params, test.Data)
		if err != test.Error {
			if !reflect.DeepEqual(err, test.Error) {
				t.Errorf("test %d: expecting error %s, got %s", n+1, test.Error, err)
				continue
			}
		}
		if !reflect.DeepEqual(test.Input, test.Match) {
			t.Errorf("test %d: input does not match expected", n+1)
			continue
		}
		test.Match.Encode(&buf)
		if str := buf.String(); str != test.Output {
			t.Errorf("test %d: expecting output string %q, got %q", n+1, test.Output, str)
		}
		buf.Reset()
	}
}

func TestBinary(t *testing.T) {
	testType(t, []typeTest{
		{
			Input: &Binary{},
			Match: &Binary{},
			Error: ErrInvalidEncoding,
		},
		{
			Params: map[string]string{"ENCODING": "BASE64"},
			Data:   "MTIzNDU=",
			Input:  &Binary{},
			Match:  &Binary{'1', '2', '3', '4', '5'},
			Output: "MTIzNDU=",
		},
	})
}

func TestBoolean(t *testing.T) {
	tr := new(Boolean)
	fa := new(Boolean)
	*tr = true
	testType(t, []typeTest{
		{
			Data:   "False",
			Input:  fa,
			Match:  fa,
			Output: "FALSE",
		},
		{
			Data:   "true",
			Input:  tr,
			Match:  tr,
			Output: "TRUE",
		},
		{
			Data:   "HotDog",
			Input:  fa,
			Match:  fa,
			Output: "FALSE",
			Error:  ErrInvalidBoolean,
		},
	})
}

func TestDate(t *testing.T) {
	testType(t, []typeTest{
		{
			Data:   "20011225",
			Input:  &Date{},
			Match:  &Date{time.Date(2001, 12, 25, 0, 0, 0, 0, time.UTC)},
			Output: "20011225",
		},
		{
			Data:   "20081111",
			Input:  &Date{},
			Match:  &Date{time.Date(2008, 11, 11, 0, 0, 0, 0, time.UTC)},
			Output: "20081111",
		},
	})
}

func TestDateTime(t *testing.T) {
	l, err := time.LoadLocation("America/New_York")
	if err != nil {
		t.Errorf("unexpected error: %s", err)
		return
	}
	testType(t, []typeTest{
		{
			Data:   "20011225T131415",
			Input:  &DateTime{},
			Match:  &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, time.Local)},
			Output: "20011225T131415",
		},
		{
			Data:   "20011225T131415Z",
			Input:  &DateTime{},
			Match:  &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, time.UTC)},
			Output: "20011225T131415Z",
		},
		{
			Params: map[string]string{"TZID": "America/New_York"},
			Data:   "20011225T131415",
			Input:  &DateTime{},
			Match:  &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, l)},
			Output: "20011225T131415",
		},
	})
}
<commit_msg>added tests for Duration<commit_after>package ics

import (
	"bytes"
	"io"
	"reflect"
	"testing"
	"time"
)

type typeTest struct {
	Params map[string]string
	Data   string
	Input  interface {
		Decode(map[string]string, string) error
	}
	Match interface {
		Encode(io.Writer)
	}
	Output string
	Error  error
}

var emptyMap = make(map[string]string)

func testType(t *testing.T, tests []typeTest) {
	var buf bytes.Buffer
	for n, test := range tests {
		if test.Params == nil {
			test.Params = emptyMap
		}
		err := test.Input.Decode(test.Params, test.Data)
		if err != test.Error {
			if !reflect.DeepEqual(err, test.Error) {
				t.Errorf("test %d: expecting error %s, got %s", n+1, test.Error, err)
				continue
			}
		}
		if test.Error == nil {
			if !reflect.DeepEqual(test.Input, test.Match) {
				t.Errorf("test %d: input does not match expected", n+1)
				continue
			}
			test.Match.Encode(&buf)
			if str := buf.String(); str != test.Output {
				t.Errorf("test %d: expecting output string %q, got %q", n+1, test.Output, str)
			}
			buf.Reset()
		}
	}
}

func TestBinary(t *testing.T) {
	testType(t, []typeTest{
		{
			Input: &Binary{},
			Match: &Binary{},
			Error: ErrInvalidEncoding,
		},
		{
			Params: map[string]string{"ENCODING": "BASE64"},
			Data:   "MTIzNDU=",
			Input:  &Binary{},
			Match:  &Binary{'1', '2', '3', '4', '5'},
			Output: "MTIzNDU=",
		},
	})
}

func TestBoolean(t *testing.T) {
	tr := new(Boolean)
	fa := new(Boolean)
	*tr = true
	testType(t, []typeTest{
		{
			Data:   "False",
			Input:  fa,
			Match:  fa,
			Output: "FALSE",
		},
		{
			Data:   "true",
			Input:  tr,
			Match:  tr,
			Output: "TRUE",
		},
		{
			Data:  "HotDog",
			Input: fa,
			Error: ErrInvalidBoolean,
		},
	})
}

func TestDate(t *testing.T) {
	testType(t, []typeTest{
		{
			Data:   "20011225",
			Input:  &Date{},
			Match:  &Date{time.Date(2001, 12, 25, 0, 0, 0, 0, time.UTC)},
			Output: "20011225",
		},
		{
			Data:   "20081111",
			Input:  &Date{},
			Match:  &Date{time.Date(2008, 11, 11, 0, 0, 0, 0, time.UTC)},
			Output: "20081111",
		},
	})
}

func TestDateTime(t *testing.T) {
	l, err := time.LoadLocation("America/New_York")
	if err != nil {
		t.Errorf("unexpected error: %s", err)
		return
	}
	testType(t, []typeTest{
		{
			Data:   "20011225T131415",
			Input:  &DateTime{},
			Match:  &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, time.Local)},
			Output: "20011225T131415",
		},
		{
			Data:   "20011225T131415Z",
			Input:  &DateTime{},
			Match:  &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, time.UTC)},
			Output: "20011225T131415Z",
		},
		{
			Params: map[string]string{"TZID": "America/New_York"},
			Data:   "20011225T131415",
			Input:  &DateTime{},
			Match:  &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, l)},
			Output: "20011225T131415",
		},
	})
}

func TestDuration(t *testing.T) {
	testType(t, []typeTest{
		{
			Data:   "P1W",
			Input:  &Duration{},
			Match:  &Duration{Weeks: 1},
			Output: "P1W",
		},
		{
			Data:   "P1D",
			Input:  &Duration{},
			Match:  &Duration{Days: 1},
			Output: "P1D",
		},
		{
			Data:   "PT1H",
			Input:  &Duration{},
			Match:  &Duration{Hours: 1},
			Output: "PT1H",
		},
		{
			Data:   "PT1M",
			Input:  &Duration{},
			Match:  &Duration{Minutes: 1},
			Output: "PT1M",
		},
		{
			Data:   "PT1S",
			Input:  &Duration{},
			Match:  &Duration{Seconds: 1},
			Output: "PT1S",
		},
		{
			Data:   "P25W",
			Input:  &Duration{},
			Match:  &Duration{Weeks: 25},
			Output: "P25W",
		},
		{
			Data:  "P25W1D",
			Input: &Duration{},
			Error: ErrInvalidDuration,
		},
		{
			Data:  "P25G",
			Input: &Duration{},
			Error: ErrInvalidDuration,
		},
		{
			Data:   "P1DT2H3M4S",
			Input:  &Duration{},
			Match:  &Duration{Days: 1, Hours: 2, Minutes: 3, Seconds: 4},
			Output: "P1DT2H3M4S",
		},
		{
			Data:   "PT0S",
			Input:  &Duration{},
			Match:  &Duration{},
			Output: "PT0S",
		},
		{
			Data:   "+P1DT2H3M4S",
			Input:  &Duration{},
			Match:  &Duration{Days: 1, Hours: 2, Minutes: 3, Seconds: 4},
			Output: "P1DT2H3M4S",
		},
		{
			Data:   "-P1DT2H3M4S",
			Input:  &Duration{},
			Match:  &Duration{Negative: true, Days: 1, Hours: 2, Minutes: 3, Seconds: 4},
			Output: "-P1DT2H3M4S",
		},
	})
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, Mitchell Cooper
package main

import (
	"bytes"
	wikiclient "github.com/cooper/go-wikiclient"
	"log"
	"net/http"
	"strconv"
	"strings"
)

// master handler
func handleRoot(w http.ResponseWriter, r *http.Request) {
	var delayedWiki wikiInfo

	// try each wiki
	for _, wiki := range wikis {

		// wrong root
		wikiRoot := wiki.conf.Get("root.wiki")
		if r.URL.Path != wikiRoot && r.URL.Path != wikiRoot+"/" {
			continue
		}

		// no main page configured
		if wiki.conf.Get("main_page") == "" {
			continue
		}

		// wrong host
		if wiki.host != r.Host {

			// if the wiki host is empty, it is the fallback wiki.
			// delay it until we've checked all other wikis.
			if wiki.host == "" && delayedWiki.name == "" {
				delayedWiki = wiki
			}

			continue
		}

		// host matches
		delayedWiki = wiki
		break
	}

	// try the delayed wiki
	if delayedWiki.name != "" {
		http.Redirect(
			w, r,
			delayedWiki.conf.Get("root.page")+
				"/"+delayedWiki.conf.Get("main_page"),
			http.StatusMovedPermanently,
		)
		return
	}

	// anything else is a 404
	http.NotFound(w, r)
}

// page request
func handlePage(wiki wikiInfo, relPath string, w http.ResponseWriter, r *http.Request) {
	res, err := wiki.client.DisplayPage(relPath)

	// wikiclient error or 'not found' response
	if handleError(wiki, err, w, r) || handleError(wiki, res, w, r) {
		return
	}

	// other response
	switch res.Get("type") {

	// page redirect
	case "redirect":
		http.Redirect(w, r, res.Get("redirect"), http.StatusMovedPermanently)

	// page content
	case "page":
		renderTemplate(wiki, w, "page", wikiPageFromRes(wiki, res))

	// anything else
	default:
		http.NotFound(w, r)
	}
}

// image request
func handleImage(wiki wikiInfo, relPath string, w http.ResponseWriter, r *http.Request) {
	res, err := wiki.client.DisplayImage(relPath, 0, 0)
	if handleError(wiki, err, w, r) || handleError(wiki, res, w, r) {
		return
	}
	http.ServeFile(w, r, res.Get("path"))
}

// topic request
func handleCategoryPosts(wiki wikiInfo, relPath string, w http.ResponseWriter, r *http.Request) {

	// extract page number from relPath
	pageN := 1
	catName := relPath
	split := strings.SplitN(relPath, "/", 2)
	if len(split) == 2 {
		if i, err := strconv.Atoi(split[1]); err == nil {
			pageN = i
		}
		catName = split[0]
	}

	// error
	res, err := wiki.client.DisplayCategoryPosts(catName, pageN)
	if handleError(wiki, err, w, r) || handleError(wiki, res, w, r) {
		return
	}

	// pages is a map of page numbers to arrays of page refs
	pagesMap, ok := res.Args["pages"].(map[string]interface{})
	if !ok {
		handleError(wiki, "invalid response", w, r)
		return
	}

	// get the page with the requested number
	aSlice, ok := pagesMap[strconv.Itoa(pageN)].([]interface{})
	if !ok {
		log.Printf("problem: %+v", pagesMap[strconv.Itoa(pageN)])
		handleError(wiki, "invalid page number", w, r)
		return
	}

	// add each page
	page := wikiPageFromRes(wiki, res)
	for _, argMap := range aSlice {
		msg := wikiclient.Message{Args: argMap.(map[string]interface{})}
		page.Pages = append(page.Pages, wikiPageFromRes(wiki, msg))
	}

	renderTemplate(wiki, w, "posts", page)
}

// this is set true when calling handlePage for the error page. this way, if an
// error occurs when trying to display the error page, we don't infinitely loop
// between handleError and handlePage
var useLowLevelError bool

func handleError(wiki wikiInfo, errMaybe interface{}, w http.ResponseWriter, r *http.Request) bool {
	msg := "An unknown error has occurred"
	switch err := errMaybe.(type) {

	// if there's no error, stop
	case nil:
		return false

	// message of type "not found" is an error; otherwise, stop
	case wikiclient.Message:
		if err.Get("type") != "not found" {
			return false
		}
		msg = err.Get("error")

		// string
	case string:
		msg = err

		// error
	case error:
		msg = err.Error()

	}

	// if we have an error page, use it
	errorPage := wiki.conf.Get("error_page")
	if !useLowLevelError && errorPage != "" {
		useLowLevelError = true
		handlePage(wiki, errorPage, w, r)
		useLowLevelError = false
		return true
	}

	// generic error response
	http.Error(w, msg, http.StatusNotFound)
	return true
}

func renderTemplate(wiki wikiInfo, w http.ResponseWriter, templateName string, dot wikiPage) {
	var buf bytes.Buffer
	err := wiki.template.template.ExecuteTemplate(&buf, templateName+".tpl", dot)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Length", strconv.FormatInt(int64(buf.Len()), 10))
	w.Write(buf.Bytes())
}

func wikiPageFromRes(wiki wikiInfo, res wikiclient.Message) wikiPage {
	return wikiPage{
		Res:        res,
		File:       res.Get("file"),
		Name:       res.Get("name"),
		Title:      res.Get("title"),
		WikiTitle:  wiki.title,
		WikiLogo:   wiki.getLogo(),
		WikiRoot:   wiki.conf.Get("root.wiki"),
		StaticRoot: wiki.template.staticRoot,
		navigation: wiki.conf.GetSlice("navigation"),
	}
}
<commit_msg>do not redirect for main page unless main_page is set<commit_after>// Copyright (c) 2017, Mitchell Cooper
package main

import (
	"bytes"
	wikiclient "github.com/cooper/go-wikiclient"
	"log"
	"net/http"
	"strconv"
	"strings"
)

// master handler
func handleRoot(w http.ResponseWriter, r *http.Request) {
	var delayedWiki wikiInfo

	// try each wiki
	for _, wiki := range wikis {

		// wrong root
		wikiRoot := wiki.conf.Get("root.wiki")
		if r.URL.Path != wikiRoot && r.URL.Path != wikiRoot+"/" {
			continue
		}

		// no main page configured
		if wiki.conf.Get("main_page") == "" {
			continue
		}

		// wrong host
		if wiki.host != r.Host {

			// if the wiki host is empty, it is the fallback wiki.
			// delay it until we've checked all other wikis.
			if wiki.host == "" && delayedWiki.name == "" {
				delayedWiki = wiki
			}

			continue
		}

		// host matches
		delayedWiki = wiki
		break
	}

	// try the delayed wiki
	if delayedWiki.name != "" {

		// redirect is enabled
		if delayedWiki.conf.GetBool("main_redirect") {
			http.Redirect(
				w, r,
				delayedWiki.conf.Get("root.page")+
					"/"+delayedWiki.conf.Get("main_page"),
				http.StatusMovedPermanently,
			)
			return
		}

		// display main page
		handlePage(delayedWiki, delayedWiki.conf.Get("main_page"), w, r)
		return
	}

	// anything else is a 404
	http.NotFound(w, r)
}

// page request
func handlePage(wiki wikiInfo, relPath string, w http.ResponseWriter, r *http.Request) {
	res, err := wiki.client.DisplayPage(relPath)

	// wikiclient error or 'not found' response
	if handleError(wiki, err, w, r) || handleError(wiki, res, w, r) {
		return
	}

	// other response
	switch res.Get("type") {

	// page redirect
	case "redirect":
		http.Redirect(w, r, res.Get("redirect"), http.StatusMovedPermanently)

	// page content
	case "page":
		renderTemplate(wiki, w, "page", wikiPageFromRes(wiki, res))

	// anything else
	default:
		http.NotFound(w, r)
	}
}

// image request
func handleImage(wiki wikiInfo, relPath string, w http.ResponseWriter, r *http.Request) {
	res, err := wiki.client.DisplayImage(relPath, 0, 0)
	if handleError(wiki, err, w, r) || handleError(wiki, res, w, r) {
		return
	}
	http.ServeFile(w, r, res.Get("path"))
}

// topic request
func handleCategoryPosts(wiki wikiInfo, relPath string, w http.ResponseWriter, r *http.Request) {

	// extract page number from relPath
	pageN := 1
	catName := relPath
	split := strings.SplitN(relPath, "/", 2)
	if len(split) == 2 {
		if i, err := strconv.Atoi(split[1]); err == nil {
			pageN = i
		}
		catName = split[0]
	}

	// error
	res, err := wiki.client.DisplayCategoryPosts(catName, pageN)
	if handleError(wiki, err, w, r) || handleError(wiki, res, w, r) {
		return
	}

	// pages is a map of page numbers to arrays of page refs
	pagesMap, ok := res.Args["pages"].(map[string]interface{})
	if !ok {
		handleError(wiki, "invalid response", w, r)
		return
	}

	// get the page with the requested number
	aSlice, ok := pagesMap[strconv.Itoa(pageN)].([]interface{})
	if !ok {
		log.Printf("problem: %+v", pagesMap[strconv.Itoa(pageN)])
		handleError(wiki, "invalid page number", w, r)
		return
	}

	// add each page
	page := wikiPageFromRes(wiki, res)
	for _, argMap := range aSlice {
		msg := wikiclient.Message{Args: argMap.(map[string]interface{})}
		page.Pages = append(page.Pages, wikiPageFromRes(wiki, msg))
	}

	renderTemplate(wiki, w, "posts", page)
}

// this is set true when calling handlePage for the error page. this way, if an
// error occurs when trying to display the error page, we don't infinitely loop
// between handleError and handlePage
var useLowLevelError bool

func handleError(wiki wikiInfo, errMaybe interface{}, w http.ResponseWriter, r *http.Request) bool {
	msg := "An unknown error has occurred"
	switch err := errMaybe.(type) {

	// if there's no error, stop
	case nil:
		return false

	// message of type "not found" is an error; otherwise, stop
	case wikiclient.Message:
		if err.Get("type") != "not found" {
			return false
		}
		msg = err.Get("error")

		// string
	case string:
		msg = err

		// error
	case error:
		msg = err.Error()

	}

	// if we have an error page, use it
	errorPage := wiki.conf.Get("error_page")
	if !useLowLevelError && errorPage != "" {
		useLowLevelError = true
		handlePage(wiki, errorPage, w, r)
		useLowLevelError = false
		return true
	}

	// generic error response
	http.Error(w, msg, http.StatusNotFound)
	return true
}

func renderTemplate(wiki wikiInfo, w http.ResponseWriter, templateName string, dot wikiPage) {
	var buf bytes.Buffer
	err := wiki.template.template.ExecuteTemplate(&buf, templateName+".tpl", dot)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Length", strconv.FormatInt(int64(buf.Len()), 10))
	w.Write(buf.Bytes())
}

func wikiPageFromRes(wiki wikiInfo, res wikiclient.Message) wikiPage {
	return wikiPage{
		Res:        res,
		File:       res.Get("file"),
		Name:       res.Get("name"),
		Title:      res.Get("title"),
		WikiTitle:  wiki.title,
		WikiLogo:   wiki.getLogo(),
		WikiRoot:   wiki.conf.Get("root.wiki"),
		StaticRoot: wiki.template.staticRoot,
		navigation: wiki.conf.GetSlice("navigation"),
	}
}
<|endoftext|>